From 69f8194da778a692b6b0c14f43d9611c2072e8ba Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Mon, 7 Dec 2015 16:19:36 -0300 Subject: Implement desktops. It's somewhat buggy. But works :). There're 2 desktops only for now, maybe later I will implement something more dynamic --- src/dotwm.rs | 174 +++++++++++++++++++++++++---------------------------------- 1 file changed, 72 insertions(+), 102 deletions(-) (limited to 'src/dotwm.rs') diff --git a/src/dotwm.rs b/src/dotwm.rs index b3ed782..2781ae8 100644 --- a/src/dotwm.rs +++ b/src/dotwm.rs @@ -12,26 +12,36 @@ use safe_x11::{ open_display, close_display, atom, - screen_size, }; -use safe_x11::window::XWindow; +use safe_x11::window::{ + XWindow, +}; +use desktop::Desktop; use std::ptr; use std::process::exit; use std::mem::uninitialized; use std::collections::HashMap; use libc::c_int; +use libc::c_char; #[allow(unused_variables)] unsafe extern "C" fn error_handler(d: *mut Display, evptr: *mut XErrorEvent) -> c_int { - println!("ERRORR"); + println!("ERROR"); let ev = ptr::read(evptr); if ev.error_code == xlib::BadAccess { println!("Another widnow manager is running :C"); exit(1); } + println!("Error code {:?}", ev.error_code); + let mut buf: [i8; 1000] = [0i8; 1000]; + let bufptr = buf.as_mut_ptr(); + xlib::XGetErrorText(d, ev.error_code as c_int, bufptr as *mut c_char, 1000); + let string = String::from_raw_parts(bufptr as *mut u8, 1000, 1000); + println!("Error: {}", string); + 0 } @@ -53,8 +63,6 @@ pub enum NetAtom { pub struct DotWM { /// Reference to the X display. pub display: *mut Display, - /// References to all the windows. - pub window_list: Vec, /// Check if the window manager needs to end. pub finish: bool, /// Vec holding atoms for ICCCM support @@ -62,8 +70,9 @@ pub struct DotWM { /// Vec holding atoms for EWHM support pub netatoms: HashMap, /// Number of the active desctop - current_desktop: usize, - cw_idx: usize, + pub desktop_idx: usize, + /// Desktops + pub desktops: Vec, } /// DotWM state. @@ -106,68 +115,64 @@ impl DotWM { DotWM { display: d, - cw_idx: 0, finish: false, wmatoms: wmatoms, netatoms: netatoms, - current_desktop: 0, - window_list: vec![], + desktop_idx: 0, + desktops: vec![ + Desktop::new(d, "main"), + Desktop::new(d, "other") + ], } } + /// this should always return a desktop. + pub fn current_desktop_mut(&mut self) -> &mut Desktop { + self.desktops.get_mut(self.desktop_idx).unwrap() + } + + pub fn current_desktop(&self) -> &Desktop { + self.desktops.get(self.desktop_idx).unwrap() + } + + /// Add a window to the current desktop 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(); - } + self.current_desktop_mut().add_window(w); } pub fn current_window(&self) -> Option<&XWindow> { - if self.cw_idx < self.window_list.len() { - self.window_list.get(self.cw_idx) + let d = self.desktops.get(self.desktop_idx); + if let Some(desktop) = d { + desktop.current_window() } else { None } } pub fn current_window_mut(&mut self) -> Option<&mut XWindow> { - if self.cw_idx < self.window_list.len() { - self.window_list.get_mut(self.cw_idx) + let d = self.desktops.get_mut(self.desktop_idx); + if let Some(desktop) = d { + desktop.current_window_mut() } else { None } } pub fn remove_window(&mut self, w: xlib::Window) { - let pos = self.window_list.iter().position(|xw| xw.inner == w); - - match pos { - Some(idx) => { - let new_idx = if idx == 0 { usize::max_value() } else { idx - 1 }; - self.window_list.remove(idx); - self.cw_idx = new_idx; - self.focus_current_window(); - }, - None => (), - } + //let iter = self.desktops.iter_mut(); + //for desktop in iter { + // desktop.remove_window(w); + //} + self.current_desktop_mut().remove_window(w); } 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(); + self.current_desktop_mut().change_focus_of(idx); } /// Find a given window and returns it's position on the window_list. pub fn find_window(&self, w: xlib::Window) -> Option { - self.window_list.iter().position(|xw| xw.inner == w) + self.current_desktop().find_window(w) } /// Focus the next window. @@ -175,82 +180,47 @@ impl DotWM { /// There're 3 posibilities. There's no window, there's one window or there /// are more windows. pub fn focus_next(&mut self) { - if self.window_list.len() > 0 { - // Unfocus the current window. - let prev_win = &self.window_list[self.cw_idx]; - prev_win.unfocus(); - - // And give focus to the next one. - let next_win_idx = if self.cw_idx < self.window_list.len() - 1 { - self.cw_idx + 1 - } else { - 0 - }; - - let curr_win = &self.window_list[next_win_idx]; - curr_win.focus(); - self.cw_idx = next_win_idx; - } + self.current_desktop_mut().focus_next(); } - fn focus_current_window(&self) { - self.current_window().map(|x| x.focus()); + pub fn x_geometries(&self) -> Vec { + self.current_desktop().geometries().iter().map(|x| x.0).collect() } - fn unfocus_current_window(&self) { - self.current_window().map(|x| x.unfocus()); + pub fn y_geometries(&self) -> Vec { + self.current_desktop().geometries().iter().map(|x| x.1).collect() } - /// Get a list of the geometries for every window in the screen (including - /// the screen borders. The form is (x, y). - /// - /// # Example - /// - /// Having a screen of 800x600, and a window on 10(x), 10(y) with dimensions - /// 400(width) and 300(height): - /// - /// ``` - /// for (x, y) in dotwm.geometries() { - /// println!("x: {} - y: {}", x, y); - /// } - /// ``` - /// - /// The output will be: - /// - /// ``` - /// (0,0) - /// (800, 600) - /// (10, 10) - /// (410, 310) - /// ``` - pub fn geometries(&self) -> Vec<(i32,i32)> { - let (screen_width, screen_height) = screen_size(self.display); - let mut result: Vec<(i32,i32)> = vec![ - (0, 0), - (screen_width as i32, screen_height as i32), - ]; - - for w in self.window_list.iter() { - let attrs = w.attributes(); - result.push((attrs.x, attrs.y)); - result.push((attrs.x + attrs.width, attrs.y + attrs.height)); + pub fn change_desktop(&mut self,desktop: usize) { + if desktop > self.desktops.len() { + return; } - result - } - - pub fn x_geometries(&self) -> Vec { - self.geometries().iter().map(|x| x.0).collect() - } + if desktop == self.desktop_idx { + return; + } - pub fn y_geometries(&self) -> Vec { - self.geometries().iter().map(|x| x.1).collect() + let new_desktop = &self.desktops[desktop]; + let old_desktop = &self.desktops[self.desktop_idx]; + + new_desktop.show_windows(); + // let mut do_not_propagate: xlib::XSetWindowAttributes = unsafe { uninitialized() }; + // let root = root_window(self.display); + // do_not_propagate.do_not_propagate_mask = xlib::SubstructureNotifyMask; + // change_window_attributes(self.display, root, xlib::CWEventMask, + // &mut do_not_propagate); + + old_desktop.hide_windows(); + // let mut root_mask: xlib::XSetWindowAttributes = unsafe { uninitialized() }; + // root_mask.event_mask = xlib::SubstructureRedirectMask|xlib::ButtonPressMask|xlib::SubstructureNotifyMask|xlib::PropertyChangeMask; + // change_window_attributes(self.display, root, xlib::CWEventMask, + // &mut root_mask); + self.desktop_idx = desktop; } } impl Drop for DotWM { fn drop(&mut self) { - println!("Closing display"); close_display(self.display); } } -- cgit v1.2.3-54-g00ecf