diff options
author | Matias Linares <matiaslina@openmailbox.org> | 2015-11-08 23:02:00 -0300 |
---|---|---|
committer | Matias Linares <matiaslina@openmailbox.org> | 2015-11-08 23:02:00 -0300 |
commit | acf4a04b7452b6dd2e69064b4f85144b8445bbe9 (patch) | |
tree | aef2d5caab26bab04b300ef232ca75578716fa7f /src/safe_x11/window.rs | |
download | dotwm-acf4a04b7452b6dd2e69064b4f85144b8445bbe9.tar.gz |
Initial commit
This initial commit has the following:
* We can spawn a terminal.
* Given a new window, we can move it around the screen, but only the
window that was created, all the other windows disappear on the void,
so.. :(
and that's it
Diffstat (limited to 'src/safe_x11/window.rs')
-rw-r--r-- | src/safe_x11/window.rs | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/safe_x11/window.rs b/src/safe_x11/window.rs new file mode 100644 index 0000000..624fea4 --- /dev/null +++ b/src/safe_x11/window.rs @@ -0,0 +1,144 @@ +use x11::xlib; +use x11::xlib::{ + Window, + XWindowAttributes, + XGetWindowAttributes, + XDefaultScreenOfDisplay, + XMoveWindow, + + XSetInputFocus, + XSetWindowBorder, + + IsViewable, RevertToParent, CurrentTime, +}; + +use std::ptr; +use std::mem::uninitialized; +use std::cmp::{max}; + +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. + pub inner: Window, +} + +fn fixed_with_ratio(x: i32, ratio: f32) -> i32 { + let fx = x as f32; + let fixed = fx * ratio; + fixed as i32 +} + +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<XWindow> { + if w != 0 { + Some(XWindow { + display: d, + inner: w, + }) + } else { + None + } + } + + /// Set the border width To the window. + pub fn set_border_width(&self, size: u32) { + unsafe { xlib::XSetWindowBorderWidth(self.display, self.inner, size) }; + } + + pub fn set_boder_color<T: Into<Vec<u8>>>(&self, color: T) { + let c = get_color(self.display, color); + unsafe { XSetWindowBorder(self.display, self.inner, c); } + } + + /// Raises a window. + pub fn raise(&self) { + unsafe { xlib::XRaiseWindow(self.display, self.inner); } + } + + /// Register input events on some [`xlib::Window`](../../x11/xlib/type.Window.html) + /// + /// # Example + /// + /// if we want to handle when a pointer enter into a window rectangle, we + /// should do something like: + /// + /// ``` + /// use x11::xlib; + /// + /// let display = open_display("").unwrap(); + /// // Raw window + /// let window = 0xc00022; + /// + /// window.select_input(xlib::EnterWindowMask); + /// ``` + pub fn select_input(&self, mask: i64) { + unsafe { xlib::XSelectInput(self.display, self.inner, mask); } + } + + /// Returns the window attributes from certain window. + pub fn attributes(&self) -> XWindowAttributes { + unsafe { + let attrptr: *mut XWindowAttributes = uninitialized(); + XGetWindowAttributes(self.display, self.inner, attrptr); + ptr::read(attrptr) + } + } + + /// Moves the window given an offset from where it is. + pub fn move_offset(&self, xoffset: i32, yoffset: i32) { + unsafe { + let mut attributes: XWindowAttributes = uninitialized(); + XGetWindowAttributes(self.display, self.inner, &mut attributes); + println!("Moving window({:x}), {} + {} = {}, {} + {} = {}", + self.inner as u64, + attributes.x, xoffset, attributes.x + xoffset, + attributes.y, yoffset, attributes.y + yoffset); + XMoveWindow(self.display, self.inner, + attributes.x + xoffset, + attributes.y + yoffset); + } + } + + /// Moves the window to a particular coord in the screen. + pub fn move_to(&self, x: i32, y: i32) -> Result<(), &str> { + let screen = unsafe { + let s = XDefaultScreenOfDisplay(self.display); + ptr::read(s) + }; + + 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) }; + Ok(()) + } + } + + /// Resizes the window a fixed amount within the height and width. + pub fn resize(&self, w: i32, h: i32) { + let ratio = screen_ratio(self.display); + let attrs = self.attributes(); + unsafe { + 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); + } + } + + /// Raise the focus of the window. + pub fn focus(&self) { + let attrs = self.attributes(); + if attrs.map_state == IsViewable { + unsafe { + XSetInputFocus(self.display, self.inner, + RevertToParent, CurrentTime) + }; + } + } +} |