summaryrefslogtreecommitdiff
path: root/src/command.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.rs')
-rw-r--r--src/command.rs90
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));
+}