From 975aabe3362baf56e47d0ba022f7ea35f7bc5c7f Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Mon, 9 Nov 2015 05:53:12 -0300 Subject: ExecFn Rewrite. This now allows to call a ExecFn with a &mut DotWM by parameter. This help to do some things like do the window swapping. through mod4 + tab. Also the bindings are not longer on the wm, because this generates some problems with the ExecFn. Also, now it's posible to resize the windows :) --- src/main.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 20 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index feda9e0..1374446 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,13 +9,30 @@ pub mod event; use dotwm::DotWM; use command::exec_cmd; use event::{Event,next_event}; + +use safe_x11::grab_key; + use std::ops::Deref; use std::process; +use std::collections::HashMap; use x11::xlib; +use x11::xlib::GrabModeAsync; +use x11::xlib::XEvent; use x11::keysym; -fn exec(_: &DotWM, _: xlib::XEvent, args: &[String]) -> bool { +/// Defines a callback to call no certains events. +pub type ExecFn = fn(&mut DotWM, XEvent, &[String]) -> bool; +type BindingHash = HashMap<(u32, u32), (ExecFn, Vec)>; + +fn exec_func(wm: &mut DotWM, bindings: &mut BindingHash, key: u32, modifiers: u32, ev: xlib::XEvent) { + if let Some(&(func, ref args)) = bindings.get(&(key, modifiers)) { + let v = args.clone(); + func(wm, ev, &v); + } +} + +fn exec(_: &mut DotWM, _: xlib::XEvent, args: &[String]) -> bool { if let Some(program) = args.first() { let mut prog_args = vec![]; for arg in args[1..].iter() { @@ -26,10 +43,8 @@ fn exec(_: &DotWM, _: xlib::XEvent, args: &[String]) -> bool { true } -fn move_win(wm: &DotWM, _: xlib::XEvent, args: &[String]) -> bool { - println!("Parsing x"); +fn move_win(wm: &mut DotWM, _: xlib::XEvent, args: &[String]) -> bool { let x = args[0].parse::().unwrap(); - println!("Parsing y"); let y = args[1].parse::().unwrap(); if let Some(ref win) = wm.current_window() { win.move_offset(x, y); @@ -37,24 +52,62 @@ fn move_win(wm: &DotWM, _: xlib::XEvent, args: &[String]) -> bool { true } -fn quit_dotwm(_: &DotWM, _: xlib::XEvent, _: &[String]) -> bool { +fn resize_win(wm: &mut DotWM, _: xlib::XEvent, args: &[String]) -> bool { + let w = args[0].parse::().unwrap(); + let h = args[1].parse::().unwrap(); + + if let Some(ref win) = wm.current_window() { + win.resize(w, h); + }; + + true +} + +fn focus_next(wm: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { + wm.focus_next(); + true +} + +fn quit_dotwm(_: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { process::exit(0); } +fn add_binding(wm: &mut DotWM, bindings: &mut BindingHash, + key: u32, modifiers: u32, func: ExecFn, args: &[&str]) { + grab_key(wm.display, key, modifiers, true, GrabModeAsync, GrabModeAsync); + let mut v = vec![]; + for arg in args { + v.push(arg.to_string()); + } + bindings.insert((key, modifiers), (func, v)); +} + fn main() { println!("Creating dotwm"); let mut dotwm = DotWM::new(); + let mut bindings: BindingHash = HashMap::new(); - dotwm.add_binding(keysym::XK_Return, xlib::Mod4Mask, exec, - &["xterm"]); - dotwm.add_binding(keysym::XK_p, xlib::Mod4Mask, exec, - &["dmenu_run"]); - dotwm.add_binding(keysym::XK_h, xlib::Mod4Mask, move_win, &["-10", "0"]); - dotwm.add_binding(keysym::XK_j, xlib::Mod4Mask, move_win, &["0", "10"]); - dotwm.add_binding(keysym::XK_k, xlib::Mod4Mask, move_win, &["0", "-10"]); - dotwm.add_binding(keysym::XK_l, xlib::Mod4Mask, move_win, &["10", "0"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_Return, xlib::Mod4Mask, exec, + &["xterm"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_p, xlib::Mod4Mask, exec, + &["dmenu_run"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_Tab, xlib::Mod4Mask, focus_next, &[]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_h, xlib::Mod4Mask, move_win, &["-10", "0"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_j, xlib::Mod4Mask, move_win, &["0", "10"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_k, xlib::Mod4Mask, move_win, &["0", "-10"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_l, xlib::Mod4Mask, move_win, &["10", "0"]); - dotwm.add_binding(keysym::XK_q, xlib::Mod4Mask | xlib::ShiftMask, quit_dotwm, &[]); + // Resize + add_binding(&mut dotwm,&mut bindings, keysym::XK_h, xlib::Mod4Mask | xlib::ControlMask, + resize_win, &["-10", "0"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_j, xlib::Mod4Mask | xlib::ControlMask, + resize_win, &["0", "10"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_k, xlib::Mod4Mask | xlib::ControlMask, + resize_win, &["0", "-10"]); + add_binding(&mut dotwm,&mut bindings, keysym::XK_l, xlib::Mod4Mask | xlib::ControlMask, + resize_win, &["10", "0"]); + + add_binding(&mut dotwm, &mut bindings, keysym::XK_q, xlib::Mod4Mask | xlib::ShiftMask, quit_dotwm, &[]); // Main loop loop { @@ -65,14 +118,20 @@ fn main() { let keysym = unsafe { xlib::XLookupKeysym(&mut e, 0) as u32 }; let mask = e.state; - dotwm.exec_func(keysym, mask, xlib::XEvent::from(e)); + exec_func(&mut dotwm, &mut bindings, keysym, mask, xlib::XEvent::from(e)); }, - Event::Create(e) => { - // XCreateWindowEvent - let create_event = xlib::XCreateWindowEvent::from(e); - dotwm.add_window(create_event.window); + Event::Map(e) => { + // If the window has override_redirect setted to true, this should not + // be handled by the wm. + let map_event = xlib::XMapEvent::from(e); + if map_event.override_redirect == 0 { + println!("Adding window"); + dotwm.add_window(map_event.window); + } else { + println!("Map event 0 :("); + } } - Event::Destroy(e) => { + Event::Unmap(e) => { dotwm.remove_window(e.window); }, Event::Enter(e) => { -- cgit v1.2.3-54-g00ecf