summaryrefslogtreecommitdiff
path: root/src/clients/client.rs
diff options
context:
space:
mode:
authortcmal <me@aria.rip>2024-07-15 19:25:03 +0100
committertcmal <me@aria.rip>2024-07-15 20:44:58 +0100
commit7e3d3a9bae541d0a70c375567b9c9b280c60252e (patch)
treee353cecf2229790697fdbdfafd458b47b2e6278e /src/clients/client.rs
parent4f97eac4f9983c8cfa6ee506a3a20b0abb33f2a3 (diff)
Handle fullscreen requests sent by clients
Diffstat (limited to 'src/clients/client.rs')
-rw-r--r--src/clients/client.rs65
1 files changed, 48 insertions, 17 deletions
diff --git a/src/clients/client.rs b/src/clients/client.rs
index c9fa645..43d4c54 100644
--- a/src/clients/client.rs
+++ b/src/clients/client.rs
@@ -1,7 +1,8 @@
use xcb::{
x::{
- ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigureNotifyEvent,
- ConfigureWindow, Cw, EventMask, MapWindow, SendEvent, SendEventDest, StackMode, Window,
+ self, ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigureNotifyEvent,
+ ConfigureWindow, Cw, EventMask, MapWindow, PropMode, SendEvent, SendEventDest, StackMode,
+ Window,
},
VoidCookieChecked, Xid,
};
@@ -125,25 +126,40 @@ impl Client {
matches!(self.layout_mode, LayoutMode::Tiled)
}
+ /// Whether the client is fullscreen
+ pub const fn fullscreen(&self) -> bool {
+ matches!(self.layout_mode, LayoutMode::Fullscreen)
+ }
+
/// Set the window as tiled
- pub fn set_tiled(&mut self) {
+ pub fn set_tiled(&mut self, conn: &Connection<'_>) {
+ let dirty = !matches!(self.layout_mode, LayoutMode::Tiled);
self.layout_mode = LayoutMode::Tiled;
+ if dirty {
+ self.apply_net_wm_state(conn)
+ }
}
/// Set the window as floating
pub fn set_floating(&mut self, conn: &Connection<'_>) {
- if !matches!(self.layout_mode, LayoutMode::Floating) {
+ let dirty = !matches!(self.layout_mode, LayoutMode::Floating);
+ self.layout_mode = LayoutMode::Floating;
+
+ if dirty {
conn.send_request(&ConfigureWindow {
window: self.window,
value_list: &[ConfigWindow::StackMode(StackMode::Above)],
});
+ self.apply_net_wm_state(conn);
}
- self.layout_mode = LayoutMode::Floating;
}
/// Set the window as fullscreen
pub fn set_fullscreen(&mut self, conn: &Connection<'_>, mon_geom: &MonitorGeometry) {
- if !matches!(self.layout_mode, LayoutMode::Fullscreen) {
+ let dirty = !matches!(self.layout_mode, LayoutMode::Fullscreen);
+ self.layout_mode = LayoutMode::Fullscreen;
+
+ if dirty {
conn.send_request(&ConfigureWindow {
window: self.window,
value_list: &[ConfigWindow::StackMode(StackMode::Above)],
@@ -157,8 +173,22 @@ impl Client {
mon_geom.height,
self.border_width,
);
+ self.apply_net_wm_state(conn);
}
- self.layout_mode = LayoutMode::Fullscreen;
+ }
+
+ fn apply_net_wm_state(&self, conn: &Connection<'_>) {
+ conn.send_request(&ChangeProperty {
+ mode: PropMode::Replace,
+ window: self.window,
+ property: conn.atoms.net_wm_state,
+ r#type: x::ATOM_ATOM,
+ data: &[match self.layout_mode {
+ LayoutMode::Tiled => 0_u32,
+ LayoutMode::Floating => 0_u32,
+ LayoutMode::Fullscreen => conn.atoms.net_wm_fullscreen.resource_id(),
+ }],
+ });
}
/// Ensure this client is currently mapped / visible
@@ -188,8 +218,8 @@ impl Client {
})
}
- /// Sync the non-geometry related properties with EWMH hints
- pub fn sync_properties(&mut self, conn: &Connection<'_>, focused: bool) {
+ /// Sync the non-geometry related hints with EWMH hints
+ pub fn sync_hints(&mut self, conn: &Connection<'_>, focused: bool) {
let Some(mut hints) = hints::Ewm::get(conn, self.window) else {
return;
};
@@ -204,6 +234,15 @@ impl Client {
self.never_focus = hints.input().is_some_and(|i| !i);
}
+ /// Apply any geometry-related EWM hints on the window
+ pub fn apply_geometry_hints(&mut self, conn: &Connection<'_>, mon_geom: &MonitorGeometry) {
+ if hints::is_fullscreen(conn, self.window) {
+ self.set_fullscreen(conn, mon_geom);
+ } else if hints::is_dialog(conn, self.window) {
+ self.set_floating(conn);
+ }
+ }
+
/// Set the given window as withdrawn / not withdrawn.
pub fn set_withdrawn(&self, conn: &Connection<'_>, withdrawn: bool) -> VoidCookieChecked {
conn.send_request_checked(&ChangeProperty {
@@ -215,14 +254,6 @@ impl Client {
})
}
- pub fn update_window_type(&mut self, conn: &Connection<'_>, mon_geom: &MonitorGeometry) {
- if hints::is_fullscreen(conn, self.window) {
- self.set_fullscreen(conn, mon_geom);
- } else if hints::is_dialog(conn, self.window) {
- self.set_floating(conn);
- }
- }
-
pub fn set_urgent(&mut self, urgent: bool) {
self.urgent = urgent;
}