343 lines
11 KiB
Rust
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(())
|
|
})
|
|
}
|
|
}
|