diff options
Diffstat (limited to 'src/command.rs')
-rw-r--r-- | src/command.rs | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/src/command.rs b/src/command.rs index b728776..3bebc52 100644 --- a/src/command.rs +++ b/src/command.rs @@ -2,13 +2,22 @@ //! Command execution module. //! +use std::collections::HashMap; use std::ffi::OsStr; -use std::process::{Command,Child}; use std::io::Result; +use std::ops::Deref; +use std::process::{Command,Child}; +use std::process; +use std::ptr; use libc::c_int; use libc::pid_t; -use std::ptr; + +use x11::xlib; +use x11::xlib::{XEvent, GrabModeAsync}; + +use dotwm::DotWM; +use safe_x11::grab_key; const WNOHANG: c_int = 0x00000001; @@ -31,3 +40,80 @@ pub fn collect_zombies() { while waitpid(-1, ptr::null_mut(), WNOHANG) > 0 {} }; } + +/// Defines a callback to call no certains events. +pub type ExecFn = fn(&mut DotWM, XEvent, &[String]) -> bool; + +/// Map for keys => functions +pub type BindingHash = HashMap<(u32, u32), (ExecFn, Vec<String>)>; + +pub 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); + } +} + +pub 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() { + prog_args.push(arg); + } + exec_cmd(program, prog_args.deref()).unwrap(); + } + true +} + +pub fn move_win(wm: &mut DotWM, _: xlib::XEvent, args: &[String]) -> bool { + let x = args[0].parse::<i32>().unwrap(); + let y = args[1].parse::<i32>().unwrap(); + if let Some(ref win) = wm.current_window() { + win.move_offset(x, y); + }; + true +} + +pub 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 +} + +pub fn focus_next(wm: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { + wm.focus_next(); + true +} + +pub fn quit_dotwm(_: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { + process::exit(0); +} + +/// Add a binding to the WM. +/// +/// # Example +/// +/// ``` +/// fn quit_dotwm(_: &mut DotWM, _: xlib::XEvent, _: &[String]) -> bool { +/// process::exit(0); +/// } +/// +/// // ... +/// +/// add_binding(keysym::XK_Return, xlib::Mod4Mask, exec, +/// &["xterm"]); +/// ``` +pub 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)); +} |