summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs99
1 files changed, 79 insertions, 20 deletions
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<String>)>;
+
+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::<i32>().unwrap();
- println!("Parsing y");
let y = args[1].parse::<i32>().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::<i32>().unwrap();
+ let h = args[1].parse::<i32>().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) => {