From 5d7d8a19f6364dfb6e6583125ced3103d069f2b3 Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Wed, 27 Jan 2016 12:27:34 -0300 Subject: Refactor move sticky. --- src/safe_x11/mod.rs | 7 ++++ src/safe_x11/window.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 94 insertions(+), 10 deletions(-) (limited to 'src/safe_x11') diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs index 9e5859a..03c54d8 100644 --- a/src/safe_x11/mod.rs +++ b/src/safe_x11/mod.rs @@ -16,9 +16,11 @@ use x11::xlib::{ XEvent, XNextEvent, + XDefaultGC, // Windows Window, + GC, Atom, XInternAtom, }; @@ -226,6 +228,11 @@ fn get_color>>(display: *mut Display, color: T) -> u64{ } } +fn default_gc(display: *mut Display) -> GC { + let screen_num = unsafe { xlib::XDefaultScreen(display) }; + unsafe { XDefaultGC(display, screen_num) } +} + /// Get the keysym for the given event. pub fn lookup_keysym(ev: &mut XKeyEvent) -> xlib::KeySym { unsafe { xlib::XLookupKeysym(ev, 0) } diff --git a/src/safe_x11/window.rs b/src/safe_x11/window.rs index 78b73f7..c889dfc 100644 --- a/src/safe_x11/window.rs +++ b/src/safe_x11/window.rs @@ -23,19 +23,22 @@ use x11::xlib::{ XChangeWindowAttributes, XSetWindowAttributes, XMapWindow, XUnmapWindow, + + XBlackPixel,XWhitePixel, XDrawString, }; use std::ptr; use std::mem::uninitialized; use std::mem::transmute; use std::cmp::{max}; +use std::ffi::CString; use safe_x11::{screen_ratio,get_color}; /// Representation of [`xlib::Window`](../../x11/xlib/type.Window.html) pub struct XWindow { display: *mut xlib::Display, - /// xlib::Window that wraps this struct. + // The Application window. pub inner: Window, fullscreen: bool, prev_attribs: XWindowAttributes, @@ -47,12 +50,21 @@ fn fixed_with_ratio(x: i32, ratio: f32) -> i32 { fixed as i32 } +fn window_attribs(display: *mut xlib::Display, w: Window) -> XWindowAttributes { + unsafe { + let mut attrptr: XWindowAttributes = uninitialized(); + XGetWindowAttributes(display, w, &mut attrptr); + attrptr + } +} + impl XWindow { /// Generate a reference to the window in certain display. This will return /// `None` if the window is the root window. pub fn new(d: *mut xlib::Display, w: Window) -> Option { if w != 0 { let attrs: XWindowAttributes = unsafe { uninitialized() }; + println!("Window created!"); Some(XWindow { display: d, inner: w, @@ -73,6 +85,7 @@ impl XWindow { /// the user selected "delete window" from a hypothetical menu and /// also perform any confirmation dialog with the user. pub fn delete(&self) { + // First delete the border window and then the main window. let mut ev: XClientMessageEvent = unsafe { uninitialized() }; ev.type_ = ClientMessage; ev.window = self.inner; @@ -95,7 +108,9 @@ impl XWindow { /// Raises a window. pub fn raise(&self) { - unsafe { xlib::XRaiseWindow(self.display, self.inner); } + unsafe { + xlib::XRaiseWindow(self.display, self.inner); + } } /// Register input events on some [`xlib::Window`](../../x11/xlib/type.Window.html) @@ -120,11 +135,7 @@ impl XWindow { /// Returns the window attributes from certain window. pub fn attributes(&self) -> XWindowAttributes { - unsafe { - let mut attrptr: XWindowAttributes = uninitialized(); - XGetWindowAttributes(self.display, self.inner, &mut attrptr); - attrptr - } + window_attribs(self.display, self.inner) } /// Moves the window given an offset from where it is. @@ -148,15 +159,64 @@ impl XWindow { if 0 > x && x <= screen.width || 0 > y && y <= screen.height { Err("Cannot move the window outside the screen!") } else { - unsafe { XMoveWindow(self.display, self.inner, x, y) }; + unsafe { + XMoveWindow(self.display, self.inner, x, y); + }; Ok(()) } } + // Some functions for moving within some boundaries. + + /// Move sticky to the left. + pub fn move_sticky_left(&self, boundaries: &[i32]) { + let attrs = self.attributes(); + if let Some(v) = boundaries.iter() + .skip_while(|&a| *a >= attrs.x) + .next() { + let _ = self.move_to(*v, attrs.y); + } + } + + /// Move sticky to the right. + pub fn move_sticky_right(&self, boundaries: &[i32]) { + let attrs = self.attributes(); + let win_bound = attrs.x + attrs.width; + + if let Some(v) = boundaries.iter() + .skip_while(|&a| *a <= win_bound) + .next() { + let _ = self.move_to(*v - attrs.width, attrs.y); + } + } + + /// Move up sticky. + pub fn move_sticky_up(&self, boundaries: &[i32]) { + let attrs = self.attributes(); + + if let Some(v) = boundaries.iter() + .skip_while(|&a| *a >= attrs.y) + .next() { + let _ = self.move_to(attrs.x, *v); + } + } + + /// Move down sticky. + pub fn move_sticky_down(&self, boundaries: &[i32]) { + let attrs = self.attributes(); + let win_bound = attrs.y + attrs.height; + + if let Some(v) = boundaries.iter() + .skip_while(|&a| *a <= win_bound) + .next() { + let _ = self.move_to(attrs.x, *v - attrs.height); + } + } + /// 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); + XMoveResizeWindow(self.display, self.inner, x, y, w, h as u32); } } @@ -168,7 +228,7 @@ impl XWindow { let ww: u32 = max(1, (attrs.width + fixed_with_ratio(w, ratio)) as u32); let wh: u32 = max(1, (attrs.height + fixed_with_ratio(h, ratio)) as u32); xlib::XResizeWindow(self.display, self.inner, - ww, wh); + ww, wh as u32); } } @@ -245,6 +305,23 @@ impl XWindow { } } + pub fn draw_string>>(&self, s: T) { + // Title :D + println!("Drawing string for {}", self.inner); + let cstr = CString::new(s).unwrap(); + unsafe { + let gc = xlib::XCreateGC(self.display, self.inner, 0, ptr::null_mut()); + xlib::XSetForeground(self.display, gc, XWhitePixel(self.display, 0)); + xlib::XSetBackground(self.display, gc, XBlackPixel(self.display, 0)); + println!("Loading fixed"); + let font: xlib::XFontStruct = ptr::read(xlib::XLoadQueryFont(self.display, CString::new("fixed").unwrap().as_ptr())); + xlib::XSetFont(self.display, gc, font.fid); + xlib::XClearWindow(self.display, self.inner); + XDrawString(self.display, self.inner, gc, + 3, 10, cstr.as_ptr(), cstr.to_bytes().len() as i32); + } + } + pub fn map(&self) { unsafe { XMapWindow(self.display, self.inner); } } -- cgit v1.2.3-70-g09d2