aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatias Linares <matiaslina@openmailbox.org>2015-11-09 01:33:33 -0300
committerMatias Linares <matiaslina@openmailbox.org>2015-11-09 01:33:33 -0300
commit05bfd598a060beafe1a20ff759e499987f1ce87b (patch)
treedba0e6ddc3c8d110ece5bbdd4b3f7f12063eb0a5
parenta92f31598c7f5c5be971d643435193c52080b4dc (diff)
downloaddotwm-05bfd598a060beafe1a20ff759e499987f1ce87b.tar.gz
Focus handling.
For now this have some bugs. Some complex programs (i.e. thunar, firefox) will spawn a lot of XCreateEvents and the last window it's not focused correctly. Also the enter notify should work on an input instead hovering the window
-rw-r--r--src/dotwm.rs37
-rw-r--r--src/event.rs8
-rw-r--r--src/main.rs13
-rw-r--r--src/safe_x11/mod.rs1
-rw-r--r--src/safe_x11/window.rs2
5 files changed, 57 insertions, 4 deletions
diff --git a/src/dotwm.rs b/src/dotwm.rs
index 2d64584..77f09b3 100644
--- a/src/dotwm.rs
+++ b/src/dotwm.rs
@@ -104,14 +104,18 @@ impl DotWM {
}
pub fn add_window(&mut self, w: xlib::Window) {
+ self.unfocus_current_window();
if let Some(w) = XWindow::new(self.display, w) {
+ w.select_input(xlib::EnterWindowMask);
self.window_list.push(w);
// Last windows get focus.
self.cw_idx = self.window_list.len() - 1;
+ self.focus_current_window();
}
}
pub fn current_window(&self) -> Option<&XWindow> {
+ println!("trying to get {} from list of len {}", self.cw_idx, self.window_list.len());
if self.cw_idx < self.window_list.len() {
self.window_list.get(self.cw_idx)
} else {
@@ -121,15 +125,46 @@ impl DotWM {
pub fn remove_window(&mut self, w: xlib::Window) {
let pos = self.window_list.iter().position(|xw| xw.inner == w);
+ println!("Removing widnow {}: pos: {:?}", w, pos);
match pos {
Some(idx) => {
+ let new_idx = if idx == 0 { usize::max_value() } else { idx - 1 };
self.window_list.remove(idx);
- self.cw_idx = usize::max_value();
+ self.cw_idx = new_idx;
+ self.focus_current_window();
},
None => (),
}
}
+
+ pub fn change_focus_of(&mut self, idx: usize) {
+ let w = &self.window_list[idx];
+ self.unfocus_current_window();
+ self.cw_idx = idx;
+ w.set_border_width(1);
+ w.set_border_color("red");
+ w.raise();
+ }
+
+ pub fn find_window(&self, w: xlib::Window) -> Option<usize> {
+ self.window_list.iter().position(|xw| xw.inner == w)
+ }
+
+
+ fn focus_current_window(&self) {
+ if let Some(win) = self.current_window() {
+ win.set_border_width(1);
+ win.set_border_color("red");
+ }
+ }
+
+ fn unfocus_current_window(&self) {
+ if let Some(win) = self.current_window() {
+ win.set_border_width(1);
+ win.set_border_color("black");
+ }
+ }
}
impl Drop for DotWM {
diff --git a/src/event.rs b/src/event.rs
index e15ee18..366ca28 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -6,6 +6,8 @@ use x11::xlib::{
XCrossingEvent,
XCreateWindowEvent,
XDestroyWindowEvent,
+ XUnmapEvent,
+ XMapEvent,
XConfigureEvent,
};
@@ -24,6 +26,8 @@ pub enum Event {
Generic(XEvent),
Create(XCreateWindowEvent),
Destroy(XDestroyWindowEvent),
+ Unmap(XUnmapEvent),
+ Map(XMapEvent),
Configure(XConfigureEvent),
NoEvent
}
@@ -39,6 +43,8 @@ impl fmt::Debug for Event {
&Event::Leave(ev) => format!("Enter({})", XEvent::from(ev).get_type()),
&Event::Create(ev) => format!("Create({})", XEvent::from(ev).get_type()),
&Event::Destroy(ev) => format!("Destroy({})", XEvent::from(ev).get_type()),
+ &Event::Unmap(ev) => format!("Unmap({})", XEvent::from(ev).get_type()),
+ &Event::Map(ev) => format!("Map({})", XEvent::from(ev).get_type()),
&Event::Configure(ev) => format!("Configure({})", XEvent::from(ev).get_type()),
&Event::NoEvent => format!("NoEvent"),
};
@@ -60,6 +66,8 @@ pub fn next_event(display: *mut Display) -> Event {
8 => Event::Leave(XCrossingEvent::from(ev)),
16 => Event::Create(XCreateWindowEvent::from(ev)),
17 => Event::Destroy(XDestroyWindowEvent::from(ev)),
+ 18 => Event::Unmap(XUnmapEvent::from(ev)),
+ 19 => Event::Map(XMapEvent::from(ev)),
22 => Event::Configure(XConfigureEvent::from(ev)),
e => {
println!("Unknown event {}", e);
diff --git a/src/main.rs b/src/main.rs
index c89544d..feda9e0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -47,6 +47,8 @@ fn main() {
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"]);
@@ -57,6 +59,7 @@ fn main() {
// Main loop
loop {
let event = next_event(dotwm.display);
+ println!("Event {:?}", event);
match event {
Event::Key(mut e, true) => {
let keysym = unsafe { xlib::XLookupKeysym(&mut e, 0) as u32 };
@@ -69,7 +72,15 @@ fn main() {
let create_event = xlib::XCreateWindowEvent::from(e);
dotwm.add_window(create_event.window);
}
- _ => println!("Catched event! {:?}", event),
+ Event::Destroy(e) => {
+ dotwm.remove_window(e.window);
+ },
+ Event::Enter(e) => {
+ if let Some(idx) = dotwm.find_window(e.window) {
+ dotwm.change_focus_of(idx);
+ }
+ },
+ _ => (),
}
}
}
diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs
index 199c402..bdfd7cf 100644
--- a/src/safe_x11/mod.rs
+++ b/src/safe_x11/mod.rs
@@ -140,7 +140,6 @@ pub fn grab_key(display: *mut Display, key: u32, modifiers: u32, owner_events: b
pub fn next_xevent(display: *mut Display) -> XEvent {
unsafe {
let mut last_event: XEvent = uninitialized();
- println!("xevent: getting next event!");
xlib::XNextEvent(display, &mut last_event);
last_event
}
diff --git a/src/safe_x11/window.rs b/src/safe_x11/window.rs
index 624fea4..d2fc9ea 100644
--- a/src/safe_x11/window.rs
+++ b/src/safe_x11/window.rs
@@ -50,7 +50,7 @@ impl XWindow {
unsafe { xlib::XSetWindowBorderWidth(self.display, self.inner, size) };
}
- pub fn set_boder_color<T: Into<Vec<u8>>>(&self, color: T) {
+ pub fn set_border_color<T: Into<Vec<u8>>>(&self, color: T) {
let c = get_color(self.display, color);
unsafe { XSetWindowBorder(self.display, self.inner, c); }
}