diff options
author | Matias Linares <matiaslina@openmailbox.org> | 2015-11-29 11:57:19 -0300 |
---|---|---|
committer | Matias Linares <matiaslina@openmailbox.org> | 2015-11-29 11:57:48 -0300 |
commit | d5e55aab6499a89e9dfaf5b976938bfe3e2f6aee (patch) | |
tree | 52efc28076c31fdd2522ed8b7871a7dd99ad0c87 /src/safe_x11 | |
parent | e1ec354306742a5804a20e2651cf49945cd17287 (diff) | |
download | dotwm-d5e55aab6499a89e9dfaf5b976938bfe3e2f6aee.tar.gz |
Begin ef EWMH support and sticky movement
The implementationn of the EWMH and ICCCM support is incomplete. I need to
check how to implement on the right way.
Diffstat (limited to 'src/safe_x11')
-rw-r--r-- | src/safe_x11/mod.rs | 17 | ||||
-rw-r--r-- | src/safe_x11/window.rs | 68 |
2 files changed, 84 insertions, 1 deletions
diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs index 0283966..9cd14fd 100644 --- a/src/safe_x11/mod.rs +++ b/src/safe_x11/mod.rs @@ -6,6 +6,8 @@ use x11::xlib; use x11::xlib::{ Display, + XDisplayWidth, XDisplayHeight, + XDefaultScreen, XConnectionNumber, Screen, Cursor, @@ -17,6 +19,8 @@ use x11::xlib::{ // Windows Window, + + Atom, XInternAtom, }; use x11::xlib::XKeyEvent; @@ -110,6 +114,12 @@ pub fn next_xevent(display: *mut Display) -> XEvent { } } +pub fn screen_size(display: *mut Display) -> (u32, u32) { + let screen = unsafe { XDefaultScreen(display) }; + let dw: u32 = unsafe { XDisplayWidth(display, screen) as u32 }; + let dh: u32 = unsafe { XDisplayHeight(display, screen) as u32 }; + (dw, dh) +} /// Grab pointer buttons. /// @@ -210,3 +220,10 @@ fn get_color<T: Into<Vec<u8>>>(display: *mut Display, color: T) -> u64{ pub fn lookup_keysym(ev: &mut XKeyEvent) -> xlib::KeySym { unsafe { xlib::XLookupKeysym(ev, 0) } } + +pub fn atom<T: Into<Vec<u8>>>(display: *mut Display, name: T) -> Atom { + unsafe { + let cstr = CString::new(name).unwrap(); + XInternAtom(display, cstr.as_ptr(), 0) + } +} diff --git a/src/safe_x11/window.rs b/src/safe_x11/window.rs index 0e8ab10..6c8e48b 100644 --- a/src/safe_x11/window.rs +++ b/src/safe_x11/window.rs @@ -6,16 +6,25 @@ use x11::xlib::{ XWindowAttributes, XGetWindowAttributes, XDefaultScreenOfDisplay, - XMoveWindow, + XMoveWindow, XMoveResizeWindow, + + XDisplayHeight, XDisplayWidth, XDefaultScreen, + XA_ATOM, Atom, PropModeReplace, XSetInputFocus, XSetWindowBorder, IsViewable, RevertToParent, CurrentTime, + + XEvent, XSendEvent, XClientMessageEvent, + ClientMessage,ClientMessageData, NoEventMask, + + XChangeProperty, }; use std::ptr; use std::mem::uninitialized; +use std::mem::transmute; use std::cmp::{max}; use safe_x11::{screen_ratio,get_color}; @@ -25,6 +34,7 @@ pub struct XWindow { display: *mut xlib::Display, /// xlib::Window that wraps this struct. pub inner: Window, + fullscreen: bool, } fn fixed_with_ratio(x: i32, ratio: f32) -> i32 { @@ -41,6 +51,7 @@ impl XWindow { Some(XWindow { display: d, inner: w, + fullscreen: false, }) } else { None @@ -52,6 +63,25 @@ impl XWindow { unsafe { xlib::XSetWindowBorderWidth(self.display, self.inner, size) }; } + /// clients receiving a WM_DELETE_WINDOW message should behave as if + /// the user selected "delete window" from a hypothetical menu and + /// also perform any confirmation dialog with the user. + pub fn delete(&self) { + let mut ev: XClientMessageEvent = unsafe { uninitialized() }; + ev.type_ = ClientMessage; + ev.window = self.inner; + ev.format = 32; + ev.message_type = 0; // WM_PROTOCOLS + ev.data = ClientMessageData::new(); + ev.data.set_long(0, 0); // WM_DELETE_WINDOW + ev.data.set_long(1, CurrentTime as i64); + + let mut event = XEvent::from(ev); + + unsafe { XSendEvent(self.display, self.inner, 0, NoEventMask, &mut event); } + } + + /// Sets the border color to the selected window 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); } @@ -116,6 +146,13 @@ impl XWindow { Ok(()) } } + + /// Move and resize the window in one step + pub fn move_resize(&self, x:i32, y: i32, w: u32, h: u32) { + unsafe { + XMoveResizeWindow(self.display, self.inner, x, y, w, h); + } + } /// Resizes the window a fixed amount within the height and width. pub fn resize(&self, w: i32, h: i32) { @@ -148,4 +185,33 @@ impl XWindow { self.set_border_width(1); self.set_border_color("black"); } + + /// Fullscreen toggle + pub fn toggle_fullscreen(&mut self, wm_state_atom: Atom, + fs_atom: Atom, fullscreen: bool) { + let screen = unsafe { XDefaultScreen(self.display) }; + let dh: u32 = unsafe { XDisplayHeight(self.display, screen) as u32 }; + let dw: u32 = unsafe { XDisplayWidth(self.display, screen) as u32 }; + + if fullscreen != self.fullscreen { + self.fullscreen = fullscreen; + let fs_atom_slice: &[Atom; 1] = &[fs_atom]; + let fs_atom_ptr: *const u8 = unsafe { transmute(fs_atom_slice) }; + + println!("Changing property!"); + unsafe { + XChangeProperty(self.display, self.inner, wm_state_atom, + XA_ATOM, 32, PropModeReplace, fs_atom_ptr, + fullscreen as i32); + } + } + + if fullscreen { + println!("resizing!"); + self.move_resize(0, 0, dw, dh); + self.set_border_width(0); + } else { + self.set_border_width(1); + } + } } |