summaryrefslogtreecommitdiff
path: root/src/dotwm.rs
diff options
context:
space:
mode:
authorMatias Linares <matiaslina@openmailbox.org>2015-12-07 16:19:36 -0300
committerMatias Linares <matiaslina@openmailbox.org>2015-12-07 16:19:36 -0300
commit69f8194da778a692b6b0c14f43d9611c2072e8ba (patch)
tree8d9f252bf7a6db515a05800a73b35b21d1692cfb /src/dotwm.rs
parent12faa87415d91820503b6b1c98ebabbddc50d665 (diff)
downloaddotwm-69f8194da778a692b6b0c14f43d9611c2072e8ba.tar.gz
Implement desktops.
It's somewhat buggy. But works :). There're 2 desktops only for now, maybe later I will implement something more dynamic
Diffstat (limited to 'src/dotwm.rs')
-rw-r--r--src/dotwm.rs174
1 files changed, 72 insertions, 102 deletions
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<XWindow>,
/// 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<NetAtom, Atom>,
/// Number of the active desctop
- current_desktop: usize,
- cw_idx: usize,
+ pub desktop_idx: usize,
+ /// Desktops
+ pub desktops: Vec<Desktop>,
}
/// 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<usize> {
- 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<i32> {
+ 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<i32> {
+ 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<i32> {
- self.geometries().iter().map(|x| x.0).collect()
- }
+ if desktop == self.desktop_idx {
+ return;
+ }
- pub fn y_geometries(&self) -> Vec<i32> {
- 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);
}
}