1
0
Fork 0
forked from wry/wry
wry/src/config/handler/windows.rs

343 lines
11 KiB
Rust

use super::*;
impl ConfigProxyHandler {
pub(super) fn tl_to_window(&self, tl: &dyn ToplevelNode) -> Window {
self.tl_id_to_window(tl.tl_data().identifier.get())
}
pub(super) fn tl_id_to_window(&self, tl: ToplevelIdentifier) -> Window {
if let Some(win) = self.windows_from_tl_id.get(&tl) {
return win;
}
let id = Window(self.window_ids.fetch_add(1));
self.windows_from_tl_id.set(tl, id);
self.windows_to_tl_id.set(id, tl);
id
}
pub(super) fn get_window(&self, window: Window) -> Result<Rc<dyn ToplevelNode>, CphError> {
self.windows_to_tl_id
.get(&window)
.and_then(|id| self.state.toplevels.get(&id))
.and_then(|tl| tl.upgrade())
.ok_or(CphError::WindowDoesNotExist(window))
}
pub(super) fn get_client(&self, client: ConfigClient) -> Result<Rc<Client>, CphError> {
self.state
.clients
.get(ClientId::from_raw(client.0))
.ok()
.ok_or(CphError::ClientDoesNotExist(client))
}
pub(super) fn handle_get_clients(&self) {
let mut clients = vec![];
for client in self.state.clients.clients.borrow().values() {
clients.push(ConfigClient(client.data.id.raw()));
}
self.respond(Response::GetClients { clients });
}
pub(super) fn handle_client_exists(&self, client: ConfigClient) {
self.respond(Response::ClientExists {
exists: self.get_client(client).is_ok(),
});
}
pub(super) fn handle_client_is_xwayland(&self, client: ConfigClient) -> Result<(), CphError> {
self.respond(Response::ClientIsXwayland {
is_xwayland: self.get_client(client)?.is_xwayland,
});
Ok(())
}
pub(super) fn handle_client_kill(&self, client: ConfigClient) {
self.state.clients.kill(ClientId::from_raw(client.0));
}
pub(super) fn handle_get_workspace_window(&self, ws: Workspace) -> Result<(), CphError> {
let window = self
.get_existing_workspace(ws)?
.and_then(|ws| ws.container.get())
.map(|c| self.tl_to_window(&*c))
.unwrap_or(Window(0));
self.respond(Response::GetWorkspaceWindow { window });
Ok(())
}
pub(super) fn handle_get_seat_keyboard_window(&self, seat: Seat) -> Result<(), CphError> {
let window = self
.get_seat(seat)?
.get_keyboard_node()
.node_toplevel()
.map(|tl| self.tl_to_window(&*tl))
.unwrap_or(Window(0));
self.respond(Response::GetSeatKeyboardWindow { window });
Ok(())
}
pub(super) fn handle_seat_focus_window(&self, seat: Seat, window_id: Window) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let window = self.get_window(window_id)?;
if !window.node_visible() {
return Err(CphError::WindowNotVisible(window_id));
}
seat.focus_toplevel(window);
seat.maybe_schedule_warp_mouse_to_focus();
Ok(())
}
pub(super) fn handle_get_window_title(&self, window: Window) -> Result<(), CphError> {
let title = self.get_window(window)?.tl_data().title.borrow().clone();
self.respond(Response::GetWindowTitle { title });
Ok(())
}
pub(super) fn handle_get_window_type(&self, window: Window) -> Result<(), CphError> {
let kind = self.get_window(window)?.tl_data().kind.to_window_type();
self.respond(Response::GetWindowType { kind });
Ok(())
}
pub(super) fn handle_get_content_type(&self, window: Window) -> Result<(), CphError> {
let kind = self
.get_window(window)?
.tl_data()
.content_type
.get()
.to_config();
self.respond(Response::GetContentType { kind });
Ok(())
}
pub(super) fn handle_window_resize(
&self,
window: Window,
dx1: i32,
dy1: i32,
dx2: i32,
dy2: i32,
) -> Result<(), CphError> {
self.state.with_layout_animations(|| {
self.get_window(window)?.tl_resize(dx1, dy1, dx2, dy2);
Ok(())
})
}
pub(super) fn handle_window_exists(&self, window: Window) {
self.respond(Response::WindowExists {
exists: self.get_window(window).is_ok(),
});
}
pub(super) fn handle_get_window_id(&self, window: Window) -> Result<(), CphError> {
let id = self
.get_window(window)?
.tl_data()
.identifier
.get()
.to_string();
self.respond(Response::GetWindowId { id: id.to_string() });
Ok(())
}
pub(super) fn handle_get_window_is_visible(&self, window: Window) -> Result<(), CphError> {
let window = self.get_window(window)?;
self.respond(Response::GetWindowIsVisible {
visible: window.node_visible(),
});
Ok(())
}
pub(super) fn handle_get_window_client(&self, window: Window) -> Result<(), CphError> {
let window = self.get_window(window)?;
self.respond(Response::GetWindowClient {
client: window
.tl_data()
.client
.as_ref()
.map(|c| ConfigClient(c.id.raw()))
.unwrap_or(ConfigClient(0)),
});
Ok(())
}
pub(super) fn handle_get_window_parent(&self, window: Window) -> Result<(), CphError> {
let window = self
.get_window(window)?
.tl_data()
.parent
.get()
.and_then(|tl| tl.node_into_toplevel())
.map(|tl| self.tl_to_window(&*tl))
.unwrap_or(Window(0));
self.respond(Response::GetWindowParent { window });
Ok(())
}
pub(super) fn handle_get_window_workspace(&self, window: Window) -> Result<(), CphError> {
let workspace = self
.get_window(window)?
.tl_data()
.workspace
.get()
.map(|ws| self.get_workspace_by_name(&ws.name))
.unwrap_or(Workspace(0));
self.respond(Response::GetWindowWorkspace { workspace });
Ok(())
}
pub(super) fn handle_get_window_children(&self, window: Window) -> Result<(), CphError> {
let mut windows = vec![];
if let Some(c) = self.get_window(window)?.node_into_container() {
for c in c.children.iter() {
windows.push(self.tl_to_window(&*c.node));
}
}
self.respond(Response::GetWindowChildren { windows });
Ok(())
}
pub(super) fn handle_window_close(&self, window: Window) -> Result<(), CphError> {
let window = self.get_window(window)?;
window.tl_close();
Ok(())
}
pub(super) fn handle_window_move(
&self,
window: Window,
direction: Direction,
) -> Result<(), CphError> {
self.state.with_layout_animations(|| {
let window = self.get_window(window)?;
if let Some(float) = window.tl_data().float.get() {
float.move_by_direction(direction.into());
} else if let Some(c) = toplevel_parent_container(&*window) {
c.move_child(window, direction.into());
}
Ok(())
})
}
pub(super) fn handle_get_window_fullscreen(
&self,
window: Window,
) -> Result<(), CphError> {
let tl = self.get_window(window)?;
self.respond(Response::GetWindowFullscreen {
fullscreen: tl.tl_data().is_fullscreen.get(),
});
Ok(())
}
pub(super) fn handle_set_window_fullscreen(
&self,
window: Window,
fullscreen: bool,
) -> Result<(), CphError> {
let tl = self.get_window(window)?;
tl.tl_set_fullscreen(fullscreen, None);
Ok(())
}
pub(super) fn handle_get_window_float_pinned(
&self,
window: Window,
) -> Result<(), CphError> {
let window = self.get_window(window)?;
self.respond(Response::GetWindowFloatPinned {
pinned: window.tl_pinned(),
});
Ok(())
}
pub(super) fn handle_set_window_float_pinned(
&self,
window: Window,
pinned: bool,
) -> Result<(), CphError> {
let window = self.get_window(window)?;
window.tl_set_pinned(true, pinned);
Ok(())
}
pub(super) fn handle_get_window_mono(&self, window: Window) -> Result<(), CphError> {
let window = self.get_window(window)?;
self.respond(Response::GetWindowMono {
mono: toplevel_parent_container(&*window)
.map(|c| c.mono_child.is_some())
.unwrap_or(false),
});
Ok(())
}
pub(super) fn handle_set_window_mono(
&self,
window: Window,
mono: bool,
) -> Result<(), CphError> {
self.state.with_layout_animations(|| {
let window = self.get_window(window)?;
if let Some(c) = toplevel_parent_container(&*window) {
c.set_mono(mono.then_some(window.as_ref()));
}
Ok(())
})
}
pub(super) fn handle_get_window_split(&self, window: Window) -> Result<(), CphError> {
let window = self.get_window(window)?;
self.respond(Response::GetWindowSplit {
axis: toplevel_parent_container(&*window)
.map(|c| c.split.get())
.unwrap_or(ContainerSplit::Horizontal)
.into(),
});
Ok(())
}
pub(super) fn handle_set_window_split(
&self,
window: Window,
axis: Axis,
) -> Result<(), CphError> {
self.state.with_layout_animations(|| {
let window = self.get_window(window)?;
if let Some(c) = toplevel_parent_container(&*window) {
c.set_split(axis.into());
}
Ok(())
})
}
pub(super) fn handle_create_window_split(
&self,
window: Window,
axis: Axis,
) -> Result<(), CphError> {
let window = self.get_window(window)?;
toplevel_create_split(&self.state, window, axis.into());
Ok(())
}
pub(super) fn handle_get_window_floating(&self, window: Window) -> Result<(), CphError> {
let window = self.get_window(window)?;
self.respond(Response::GetWindowFloating {
floating: window.tl_data().parent_is_float.get(),
});
Ok(())
}
pub(super) fn handle_set_window_floating(
&self,
window: Window,
floating: bool,
) -> Result<(), CphError> {
self.state.with_linear_layout_animations(|| {
let window = self.get_window(window)?;
toplevel_set_floating(&self.state, window, floating);
Ok(())
})
}
}