From 12faa87415d91820503b6b1c98ebabbddc50d665 Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Mon, 30 Nov 2015 22:50:01 -0300 Subject: Add resize-win-sticky. The move window sticky is working weirdly. The movement should be using the attrs.x and attrs.y instead the attrs.x/y + attrs.width/height. But it's working :). --- src/command.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 2 +- src/safe_x11/mod.rs | 11 ++++++++- src/safe_x11/window.rs | 20 +++++++++++++++ src/socket/mod.rs | 2 +- src/socket/parser.rs | 8 +++--- 6 files changed, 102 insertions(+), 7 deletions(-) diff --git a/src/command.rs b/src/command.rs index 78b9e5a..f351e14 100644 --- a/src/command.rs +++ b/src/command.rs @@ -17,7 +17,7 @@ use x11::xlib::{XEvent, GrabModeAsync}; use dotwm::DotWM; use dotwm::NetAtom; -use safe_x11::grab_key; +use safe_x11::{grab_key,ungrab_key}; const WNOHANG: c_int = 0x00000001; @@ -166,6 +166,69 @@ pub fn resize_win(wm: &mut DotWM, _: xlib::XEvent, args: &[String]) -> bool { true } +/// Resizes the window sticking with other windows. +/// +/// The movement of the `right` command is the same logic as the `down`, idem to the +/// movement between `left` and `up` +pub fn resize_win_sticky(wm: &mut DotWM, _: xlib::XEvent, args: &[String]) -> bool { + if let Some(ref win) = wm.current_window() { + let attrs = win.attributes(); + + match &*args[0] { + "left" => { + let mut xgeo = wm.x_geometries(); + xgeo.sort_by(|a,b| b.cmp(a)); + + let val = xgeo.iter().skip_while(|&a| *a >= attrs.x + attrs.width).next(); + if let Some(v) = val { + let diff = attrs.width - (*v - attrs.x); + if *v - attrs.x > 0 { + let _ = win.resize_to(attrs.width - diff, attrs.height); + } + } + }, + "right" => { + let mut xgeo = wm.x_geometries(); + let win_right = attrs.x + attrs.width; + xgeo.sort_by(|a,b| a.cmp(b)); + + let val = xgeo.iter().skip_while(|&a| *a <= win_right).next(); + if let Some(xpoint) = val { + let new_width = (*xpoint - attrs.x); + let _ = win.resize_to(new_width, attrs.height); + } + }, + "up" => { + let mut ygeo = wm.y_geometries(); + ygeo.sort_by(|a,b| b.cmp(a)); + + let val = ygeo.iter().skip_while(|&a| *a >= attrs.y + attrs.height).next(); + if let Some(v) = val { + let diff = attrs.height - (*v - attrs.y); + println!("Resizing to {}x{}", attrs.width, diff); + if *v - attrs.y > 0 { + let _ = win.resize_to(attrs.width, attrs.height - diff); + } + } + }, + "down" => { + let mut ygeo = wm.y_geometries(); + let win_bot = attrs.y + attrs.height; + ygeo.sort_by(|a,b| a.cmp(b)); + + let val = ygeo.iter().skip_while(|&a| *a <= win_bot).next(); + if let Some(v) = val { + let new_height = *v - attrs.y; + println!("Resizing to {}x{}", attrs.width, new_height); + let _ = win.resize_to(attrs.width, new_height); + } + }, + _ => (), + } + } + true +} + /// Close the current window pub fn close_win(wm: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { if let Some(ref win) = wm.current_window() { @@ -203,6 +266,7 @@ pub fn quit_dotwm(wm: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { /// ``` pub fn add_binding(wm: &mut DotWM, bindings: &mut BindingHash, key: u32, modifiers: u32, func: ExecFn, args: &[&str]) { + ungrab_key(wm.display, key, modifiers); grab_key(wm.display, key, modifiers, true, GrabModeAsync, GrabModeAsync); let mut v = vec![]; for arg in args { diff --git a/src/main.rs b/src/main.rs index c9cc11e..21425c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,7 +87,7 @@ fn main() { } } }, - _ => println!("Unknown event"), + _ => (), } collect_zombies(); } diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs index 9cd14fd..2e368aa 100644 --- a/src/safe_x11/mod.rs +++ b/src/safe_x11/mod.rs @@ -149,7 +149,7 @@ pub fn grab_button(display: *mut Display, button: u32, modifiers: u32, cursor: Cursor) { unsafe { let default_win = xlib::XDefaultRootWindow(display); - xlib::XGrabButton(display, button, modifiers , default_win, + xlib::XGrabButton(display, button, modifiers, default_win, owner_events as i32, event_mask as u32, pointer_mode, keyboard_mode, confine_to, cursor); } @@ -159,6 +159,7 @@ pub fn grab_button(display: *mut Display, button: u32, modifiers: u32, /// pub fn grab_key(display: *mut Display, key: u32, modifiers: u32, owner_events: bool, pointer_mode: i32, keyboard_mode: i32) { + println!("Modifiers {:x}", modifiers); unsafe { let default_win = xlib::XDefaultRootWindow(display); let keycode: i32 = xlib::XKeysymToKeycode(display, key as u64) as i32; @@ -166,6 +167,14 @@ pub fn grab_key(display: *mut Display, key: u32, modifiers: u32, owner_events: b owner_events as i32, pointer_mode, keyboard_mode); } } +/// Unregister a combination of keys that will send a `XEvent` +pub fn ungrab_key(display: *mut Display, key: u32, modifiers: u32) { + unsafe { + let default_win = xlib::XDefaultRootWindow(display); + let keycode: i32 = xlib::XKeysymToKeycode(display, key as u64) as i32; + xlib::XUngrabKey(display, keycode, modifiers, default_win); + } +} // Window code. diff --git a/src/safe_x11/window.rs b/src/safe_x11/window.rs index 6c8e48b..34cce64 100644 --- a/src/safe_x11/window.rs +++ b/src/safe_x11/window.rs @@ -166,6 +166,26 @@ impl XWindow { } } + /// Resizes the window an absolute amount within the height and width. + pub fn resize_abs(&self, w: i32, h: i32) { + let attrs = self.attributes(); + unsafe { + let ww: u32 = max(1, (attrs.width + w) as u32); + let wh: u32 = max(1, (attrs.height + h) as u32); + xlib::XResizeWindow(self.display, self.inner, + ww, wh); + } + } + + pub fn resize_to(&self, w: i32, h: i32) { + unsafe { + let ww: u32 = max(1, w as u32); + let wh: u32 = max(1, h as u32); + xlib::XResizeWindow(self.display, self.inner, + ww, wh); + } + } + /// Raise the focus of the window and set a border. pub fn focus(&self) { let attrs = self.attributes(); diff --git a/src/socket/mod.rs b/src/socket/mod.rs index 667969b..66dae16 100644 --- a/src/socket/mod.rs +++ b/src/socket/mod.rs @@ -27,7 +27,7 @@ impl<'a> ParsedCmd<'a> { pub fn handle(self, wm: &mut DotWM, bindings: &mut BindingHash) { match self.f { FnType::Bind => { - let modifier = self.modifiers.iter() + let modifier: u32 = self.modifiers.iter() .fold(0, |acc, x| acc | x ); add_binding(wm, bindings, self.key, modifier, self.func, &self.args); diff --git a/src/socket/parser.rs b/src/socket/parser.rs index 491c315..bd73ff6 100644 --- a/src/socket/parser.rs +++ b/src/socket/parser.rs @@ -22,10 +22,11 @@ macro_rules! simple_try { } fn modifier_from<'a>(s: &'a str) -> Result { + println!("Getted modifier {}", s); match s { - "Mod1" => Ok(xlib::Mod4Mask), - "Mod2" => Ok(xlib::Mod4Mask), - "Mod3" => Ok(xlib::Mod4Mask), + "Mod1" => Ok(xlib::Mod1Mask), + "Mod2" => Ok(xlib::Mod2Mask), + "Mod3" => Ok(xlib::Mod3Mask), "Mod4" => Ok(xlib::Mod4Mask), "Control" => Ok(xlib::ControlMask), "Shift" => Ok(xlib::ShiftMask), @@ -111,6 +112,7 @@ fn func<'a>(s: &'a str) -> Result { "move-win-to" => Ok(move_win_to), "move-win-sticky" => Ok(move_win_sticky), "resize-win" => Ok(resize_win), + "resize-win-sticky" => Ok(resize_win_sticky), "focus-next" => Ok(focus_next), "close-win" => Ok(close_win), "fullscreen" => Ok(fullscreen), -- cgit v1.2.3-70-g09d2