aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatias Linares <matiaslina@openmailbox.org>2015-11-30 22:50:01 -0300
committerMatias Linares <matiaslina@openmailbox.org>2015-11-30 22:50:01 -0300
commit12faa87415d91820503b6b1c98ebabbddc50d665 (patch)
tree1f44c59543467629b0e6560dae05594d82142070
parent17e7402348195d24b7745d4dbea9f922b71f675c (diff)
downloaddotwm-12faa87415d91820503b6b1c98ebabbddc50d665.tar.gz
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 :).
-rw-r--r--src/command.rs66
-rw-r--r--src/main.rs2
-rw-r--r--src/safe_x11/mod.rs11
-rw-r--r--src/safe_x11/window.rs20
-rw-r--r--src/socket/mod.rs2
-rw-r--r--src/socket/parser.rs8
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<u32, &'static str> {
+ 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<ExecFn, &'static str> {
"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),