summaryrefslogtreecommitdiff
path: root/src/safe_x11/window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/safe_x11/window.rs')
-rw-r--r--src/safe_x11/window.rs144
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)
+ };
+ }
+ }
+}