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.rs68
1 files changed, 67 insertions, 1 deletions
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);
+ }
+ }
}