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 { 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_border_color>>(&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) }; } } }