Skip to content

Commit

Permalink
x11: More robust geometry calculations (rust-windowing#438)
Browse files Browse the repository at this point in the history
Tested on the following window managers:
* Xfwm4 4.12.4
* Mutter 3.26.2
* Muffin 3.6.0
* Budgie 10.4
* Marco 1.20.0
* Compiz 0.9.13.1
* KWin 5.12.3
* Enlightenment 0.22.2
* FVWM 2.6.7
* Awesome 4.2
* i3 4.15
* xmonad 0.13
* dwm 6.1
* Openbox 3.6.1
* Fluxbox 1.3.7
* Blackbox 0.70.1
* IceWM 1.3.8
* IceWM 1.4.2
  • Loading branch information
francesca64 authored Apr 7, 2018
1 parent 9d036a6 commit 4005bf1
Show file tree
Hide file tree
Showing 3 changed files with 460 additions and 48 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Overhauled X11 window geometry calculations. `get_position` and `set_position` are more universally accurate across different window managers, and `get_outer_size` actually works now.

# Version 0.12.0 (2018-04-06)

- Added subclass to macos windows so they can be made resizable even with no decorations.
Expand Down
66 changes: 66 additions & 0 deletions src/platform/linux/x11/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ pub enum GetPropertyError {
NothingAllocated,
}

impl GetPropertyError {
pub fn is_actual_property_type(&self, t: ffi::Atom) -> bool {
if let GetPropertyError::TypeMismatch(actual_type) = *self {
actual_type == t
} else {
false
}
}
}

pub unsafe fn get_property<T>(
xconn: &Arc<XConnection>,
window: c_ulong,
Expand Down Expand Up @@ -299,6 +309,62 @@ pub unsafe fn lookup_utf8(
str::from_utf8(&buffer[..count as usize]).unwrap_or("").to_string()
}


#[derive(Debug)]
pub struct FrameExtents {
pub left: c_ulong,
pub right: c_ulong,
pub top: c_ulong,
pub bottom: c_ulong,
}

impl FrameExtents {
pub fn new(left: c_ulong, right: c_ulong, top: c_ulong, bottom: c_ulong) -> Self {
FrameExtents { left, right, top, bottom }
}

pub fn from_border(border: c_ulong) -> Self {
Self::new(border, border, border, border)
}
}

#[derive(Debug)]
pub struct WindowGeometry {
pub x: c_int,
pub y: c_int,
pub width: c_uint,
pub height: c_uint,
pub frame: FrameExtents,
}

impl WindowGeometry {
pub fn get_position(&self) -> (i32, i32) {
(self.x as _, self.y as _)
}

pub fn get_inner_position(&self) -> (i32, i32) {
(
self.x.saturating_add(self.frame.left as c_int) as _,
self.y.saturating_add(self.frame.top as c_int) as _,
)
}

pub fn get_inner_size(&self) -> (u32, u32) {
(self.width as _, self.height as _)
}

pub fn get_outer_size(&self) -> (u32, u32) {
(
self.width.saturating_add(
self.frame.left.saturating_add(self.frame.right) as c_uint
) as _,
self.height.saturating_add(
self.frame.top.saturating_add(self.frame.bottom) as c_uint
) as _,
)
}
}

// Important: all XIM calls need to happen from the same thread!
pub struct Ime {
xconn: Arc<XConnection>,
Expand Down
Loading

0 comments on commit 4005bf1

Please sign in to comment.