diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clients/client.rs | 63 | ||||
-rw-r--r-- | src/clients/mod.rs | 25 |
2 files changed, 76 insertions, 12 deletions
diff --git a/src/clients/client.rs b/src/clients/client.rs index 43d4c54..6ab664b 100644 --- a/src/clients/client.rs +++ b/src/clients/client.rs @@ -1,8 +1,8 @@ use xcb::{ x::{ - self, ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigureNotifyEvent, - ConfigureWindow, Cw, EventMask, MapWindow, PropMode, SendEvent, SendEventDest, StackMode, - Window, + self, ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigWindowMask, + ConfigureNotifyEvent, ConfigureWindow, Cw, EventMask, MapWindow, PropMode, SendEvent, + SendEventDest, StackMode, Window, }, VoidCookieChecked, Xid, }; @@ -113,6 +113,37 @@ impl Client { }); } + /// Set the client's geometry as requested by the given event. + /// Properties not specified in `e` are not changed. + pub fn set_geom_from(&mut self, conn: &Connection, e: &x::ConfigureRequestEvent) { + let Self { + mut x, + mut y, + mut width, + mut height, + mut border_width, + .. + } = self; + + if e.value_mask().contains(ConfigWindowMask::X) { + x = e.x(); + } + if e.value_mask().contains(ConfigWindowMask::Y) { + y = e.y(); + } + if e.value_mask().contains(ConfigWindowMask::HEIGHT) { + height = e.height(); + } + if e.value_mask().contains(ConfigWindowMask::WIDTH) { + width = e.width(); + } + if e.value_mask().contains(ConfigWindowMask::BORDER_WIDTH) { + border_width = e.border_width(); + } + + self.set_geom(conn, x, y, height, width, border_width); + } + /// Set the border colour of the X11 window to the given value (see `crate::colours::Colours`) pub fn set_border(&self, conn: &Connection<'_>, colour: u32) { conn.send_request(&ChangeWindowAttributes { @@ -131,12 +162,17 @@ impl Client { matches!(self.layout_mode, LayoutMode::Fullscreen) } + /// Whether the client is floating + pub const fn floating(&self) -> bool { + matches!(self.layout_mode, LayoutMode::Floating) + } + /// Set the window as tiled 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) + self.apply_net_wm_state(conn); } } @@ -184,8 +220,7 @@ impl Client { 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::Tiled | LayoutMode::Floating => 0_u32, LayoutMode::Fullscreen => conn.atoms.net_wm_fullscreen.resource_id(), }], }); @@ -258,6 +293,22 @@ impl Client { self.urgent = urgent; } + pub const fn x(&self) -> i16 { + self.x + } + + pub const fn y(&self) -> i16 { + self.y + } + + pub const fn height(&self) -> u16 { + self.height + } + + pub const fn width(&self) -> u16 { + self.width + } + pub const fn border_width(&self) -> u16 { self.border_width } diff --git a/src/clients/mod.rs b/src/clients/mod.rs index 04355fd..7fdb739 100644 --- a/src/clients/mod.rs +++ b/src/clients/mod.rs @@ -10,13 +10,12 @@ use crate::{ }; use xcb::{ x::{ - self, ChangeProperty, ConfigWindow, ConfigureNotifyEvent, ConfigureRequestEvent, - ConfigureWindow, DeleteProperty, DestroyNotifyEvent, Drawable, EventMask, GetGeometry, - GetWindowAttributes, InputFocus, MapRequestEvent, PropMode, SetInputFocus, - UnmapNotifyEvent, Window, + self, ChangeProperty, ConfigWindow, ConfigWindowMask, ConfigureNotifyEvent, + ConfigureRequestEvent, ConfigureWindow, DeleteProperty, DestroyNotifyEvent, Drawable, + EventMask, GetGeometry, GetWindowAttributes, InputFocus, MapRequestEvent, PropMode, + SetInputFocus, UnmapNotifyEvent, Window, }, - xinerama::{self}, - BaseEvent, Extension, + xinerama, BaseEvent, Extension, }; pub use client::*; @@ -38,6 +37,20 @@ impl WM<'_> { /// Perform configure requests if we're happy with them, or they're for an unmanaged window. pub(crate) fn handle_configure_request(&mut self, e: &ConfigureRequestEvent) -> Result<()> { if let Some(c) = self.clients.find_client_mut(e.window()) { + // Always allow setting border width + if c.floating() { + c.set_geom_from(&self.conn, e); + } else if e.value_mask().contains(ConfigWindowMask::BORDER_WIDTH) { + c.set_geom( + &self.conn, + c.x(), + c.y(), + c.height(), + c.width(), + e.border_width(), + ); + } + // TODO: Allow changing some properties: // - Border width // - Size and position if floating |