this repo has no description

Deal with configurerequest properly

+76 -12
+57 -6
src/clients/client.rs
··· 1 1 use xcb::{ 2 2 x::{ 3 - self, ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigureNotifyEvent, 4 - ConfigureWindow, Cw, EventMask, MapWindow, PropMode, SendEvent, SendEventDest, StackMode, 5 - Window, 3 + self, ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigWindowMask, 4 + ConfigureNotifyEvent, ConfigureWindow, Cw, EventMask, MapWindow, PropMode, SendEvent, 5 + SendEventDest, StackMode, Window, 6 6 }, 7 7 VoidCookieChecked, Xid, 8 8 }; ··· 113 113 }); 114 114 } 115 115 116 + /// Set the client's geometry as requested by the given event. 117 + /// Properties not specified in `e` are not changed. 118 + pub fn set_geom_from(&mut self, conn: &Connection, e: &x::ConfigureRequestEvent) { 119 + let Self { 120 + mut x, 121 + mut y, 122 + mut width, 123 + mut height, 124 + mut border_width, 125 + .. 126 + } = self; 127 + 128 + if e.value_mask().contains(ConfigWindowMask::X) { 129 + x = e.x(); 130 + } 131 + if e.value_mask().contains(ConfigWindowMask::Y) { 132 + y = e.y(); 133 + } 134 + if e.value_mask().contains(ConfigWindowMask::HEIGHT) { 135 + height = e.height(); 136 + } 137 + if e.value_mask().contains(ConfigWindowMask::WIDTH) { 138 + width = e.width(); 139 + } 140 + if e.value_mask().contains(ConfigWindowMask::BORDER_WIDTH) { 141 + border_width = e.border_width(); 142 + } 143 + 144 + self.set_geom(conn, x, y, height, width, border_width); 145 + } 146 + 116 147 /// Set the border colour of the X11 window to the given value (see `crate::colours::Colours`) 117 148 pub fn set_border(&self, conn: &Connection<'_>, colour: u32) { 118 149 conn.send_request(&ChangeWindowAttributes { ··· 131 162 matches!(self.layout_mode, LayoutMode::Fullscreen) 132 163 } 133 164 165 + /// Whether the client is floating 166 + pub const fn floating(&self) -> bool { 167 + matches!(self.layout_mode, LayoutMode::Floating) 168 + } 169 + 134 170 /// Set the window as tiled 135 171 pub fn set_tiled(&mut self, conn: &Connection<'_>) { 136 172 let dirty = !matches!(self.layout_mode, LayoutMode::Tiled); 137 173 self.layout_mode = LayoutMode::Tiled; 138 174 if dirty { 139 - self.apply_net_wm_state(conn) 175 + self.apply_net_wm_state(conn); 140 176 } 141 177 } 142 178 ··· 184 220 property: conn.atoms.net_wm_state, 185 221 r#type: x::ATOM_ATOM, 186 222 data: &[match self.layout_mode { 187 - LayoutMode::Tiled => 0_u32, 188 - LayoutMode::Floating => 0_u32, 223 + LayoutMode::Tiled | LayoutMode::Floating => 0_u32, 189 224 LayoutMode::Fullscreen => conn.atoms.net_wm_fullscreen.resource_id(), 190 225 }], 191 226 }); ··· 256 291 257 292 pub fn set_urgent(&mut self, urgent: bool) { 258 293 self.urgent = urgent; 294 + } 295 + 296 + pub const fn x(&self) -> i16 { 297 + self.x 298 + } 299 + 300 + pub const fn y(&self) -> i16 { 301 + self.y 302 + } 303 + 304 + pub const fn height(&self) -> u16 { 305 + self.height 306 + } 307 + 308 + pub const fn width(&self) -> u16 { 309 + self.width 259 310 } 260 311 261 312 pub const fn border_width(&self) -> u16 {
+19 -6
src/clients/mod.rs
··· 10 10 }; 11 11 use xcb::{ 12 12 x::{ 13 - self, ChangeProperty, ConfigWindow, ConfigureNotifyEvent, ConfigureRequestEvent, 14 - ConfigureWindow, DeleteProperty, DestroyNotifyEvent, Drawable, EventMask, GetGeometry, 15 - GetWindowAttributes, InputFocus, MapRequestEvent, PropMode, SetInputFocus, 16 - UnmapNotifyEvent, Window, 13 + self, ChangeProperty, ConfigWindow, ConfigWindowMask, ConfigureNotifyEvent, 14 + ConfigureRequestEvent, ConfigureWindow, DeleteProperty, DestroyNotifyEvent, Drawable, 15 + EventMask, GetGeometry, GetWindowAttributes, InputFocus, MapRequestEvent, PropMode, 16 + SetInputFocus, UnmapNotifyEvent, Window, 17 17 }, 18 - xinerama::{self}, 19 - BaseEvent, Extension, 18 + xinerama, BaseEvent, Extension, 20 19 }; 21 20 22 21 pub use client::*; ··· 38 37 /// Perform configure requests if we're happy with them, or they're for an unmanaged window. 39 38 pub(crate) fn handle_configure_request(&mut self, e: &ConfigureRequestEvent) -> Result<()> { 40 39 if let Some(c) = self.clients.find_client_mut(e.window()) { 40 + // Always allow setting border width 41 + if c.floating() { 42 + c.set_geom_from(&self.conn, e); 43 + } else if e.value_mask().contains(ConfigWindowMask::BORDER_WIDTH) { 44 + c.set_geom( 45 + &self.conn, 46 + c.x(), 47 + c.y(), 48 + c.height(), 49 + c.width(), 50 + e.border_width(), 51 + ); 52 + } 53 + 41 54 // TODO: Allow changing some properties: 42 55 // - Border width 43 56 // - Size and position if floating