summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clients/client.rs63
-rw-r--r--src/clients/mod.rs25
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