config: split window handling
This commit is contained in:
parent
f4fdf750ec
commit
0016bc8cf0
2 changed files with 201 additions and 198 deletions
|
|
@ -89,6 +89,7 @@ use {
|
|||
|
||||
mod dispatch;
|
||||
mod matchers;
|
||||
mod windows;
|
||||
|
||||
pub(super) struct ConfigProxyHandler {
|
||||
pub client_data: Cell<*const u8>,
|
||||
|
|
@ -2050,28 +2051,6 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn tl_to_window(&self, tl: &dyn ToplevelNode) -> Window {
|
||||
self.tl_id_to_window(tl.tl_data().identifier.get())
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
fn handle_set_pointer_revert_key(&self, seat: Seat, key: KeySym) -> Result<(), CphError> {
|
||||
self.get_seat(seat)?.set_pointer_revert_key(key);
|
||||
Ok(())
|
||||
|
|
@ -2337,182 +2316,6 @@ impl ConfigProxyHandler {
|
|||
self.keymaps.remove(&keymap);
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
|
||||
fn handle_client_exists(&self, client: ConfigClient) {
|
||||
self.respond(Response::ClientExists {
|
||||
exists: self.get_client(client).is_ok(),
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_client_is_xwayland(&self, client: ConfigClient) -> Result<(), CphError> {
|
||||
self.respond(Response::ClientIsXwayland {
|
||||
is_xwayland: self.get_client(client)?.is_xwayland,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_client_kill(&self, client: ConfigClient) {
|
||||
self.state.clients.kill(ClientId::from_raw(client.0));
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
})
|
||||
}
|
||||
|
||||
fn handle_window_exists(&self, window: Window) {
|
||||
self.respond(Response::WindowExists {
|
||||
exists: self.get_window(window).is_ok(),
|
||||
});
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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 fn auto_focus(&self, data: &ToplevelData) -> bool {
|
||||
for matcher in self.window_matcher_no_auto_focus.lock().values() {
|
||||
if matcher.node.pull(data) {
|
||||
|
|
|
|||
200
src/config/handler/windows.rs
Normal file
200
src/config/handler/windows.rs
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
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(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue