From cffe227be93a19f6175ed6647cceac5e7bd71a4a Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sun, 30 Sep 2018 15:43:50 -0500 Subject: [PATCH] open a splash window instead --- Cargo.lock | 1 + Cargo.toml | 3 ++- src/gui.rs | 20 +++++++++++++++++++- src/main.rs | 1 + xlib/src/atom.rs | 38 ++++++++++++++++++++++++++++++++++++++ xlib/src/lib.rs | 4 +++- xlib/src/window.rs | 29 ++++++++++++++++++++++++++++- 7 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 xlib/src/atom.rs diff --git a/Cargo.lock b/Cargo.lock index a0219f8..cbd1c5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,6 +378,7 @@ dependencies = [ "png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7f208b4..b9576a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,9 @@ failure = "0.1" gl = "0.10" glutin = "0.18" imlib2 = { version = "0.1", path = "./imlib2" } +leanshot_xlib = { version = "0.1", path = "./xlib" } nanovg = { version = "1.0.2", features = ["gl3"] } png = "0.12" structopt = "0.2" time = "0.1" -leanshot_xlib = { version = "0.1", path = "./xlib" } +x11 = { version = "2.18", features = ["xlib"] } diff --git a/src/gui.rs b/src/gui.rs index 434fcb4..f8e2332 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,5 +1,5 @@ use imlib2::{self, Image as Image2}; -use xlib::{Display, Visual, Window}; +use xlib::{self, Display, Visual, Window}; use errors::ScreenshotError; use Options; @@ -116,7 +116,25 @@ impl GUI { .with_multisampling(4) .with_srgb(true); let win = GlWindow::new(wb, ctx, &evl).expect("couldn't make window"); + + // crosshair win.set_cursor(MouseCursor::Crosshair); + + // change window type + { + use glutin::os::unix::WindowExt; + use xlib::Atom; + match win.get_xlib_window() { + Some(id) => { + let w = Window::create_from_handle(&self.display, id)?; + let key = Atom::new(&self.display, "_NET_WM_WINDOW_TYPE", false)?; + let val = Atom::new(&self.display, "_NET_WM_WINDOW_TYPE_SPLASH", false)?; + w.change_property(&key, &val); + } + _ => (), + } + } + let f = win.get_hidpi_factor() as f64; unsafe { win.make_current().expect("couldn't make window"); diff --git a/src/main.rs b/src/main.rs index 9ed6dd1..4bcca40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ extern crate png; extern crate structopt; extern crate leanshot_xlib as xlib; extern crate time; +extern crate x11; mod capture; mod errors; diff --git a/xlib/src/atom.rs b/xlib/src/atom.rs new file mode 100644 index 0000000..ab6680b --- /dev/null +++ b/xlib/src/atom.rs @@ -0,0 +1,38 @@ +use std::ffi::CString; +use x11::xlib as x; + +use Display; +use X11Error; + +/// A unique string or intger +pub struct Atom { + inner: x::Atom, +} + +impl Atom { + /// Create a new atom using a string + pub fn new( + display: &Display, + val: impl AsRef, + only_if_exists: bool, + ) -> Result { + let val = { + let v = val.as_ref(); + let s = CString::new(v).unwrap(); + s.as_ptr() + }; + let inner = + unsafe { x::XInternAtom(display.as_raw(), val, if only_if_exists { 1 } else { 0 }) }; + Ok(Atom { inner }) + } + + /// Create a new Atom object from an existing handle + pub fn from(handle: x::Atom) -> Self { + Atom { inner: handle } + } + + /// Get the handle + pub fn as_raw(&self) -> x::Atom { + self.inner + } +} diff --git a/xlib/src/lib.rs b/xlib/src/lib.rs index dd1ad5c..a0d566e 100644 --- a/xlib/src/lib.rs +++ b/xlib/src/lib.rs @@ -5,8 +5,9 @@ #[macro_use] extern crate failure; extern crate libc; -extern crate x11; +pub extern crate x11; +mod atom; mod cursor; mod display; mod drawable; @@ -21,6 +22,7 @@ mod window; #[allow(missing_docs)] mod cursorfont; +pub use atom::Atom; pub use cursor::Cursor; pub use cursorfont::*; pub use display::{Display, GetDisplay}; diff --git a/xlib/src/window.rs b/xlib/src/window.rs index 6da1e4b..77c3176 100644 --- a/xlib/src/window.rs +++ b/xlib/src/window.rs @@ -4,7 +4,7 @@ use std::mem; use libc; use x11::xlib as x; -use {Display, Drawable, GetDisplay, Image, Rectangle, X11Error}; +use {Atom, Display, Drawable, GetDisplay, Image, Rectangle, X11Error}; /// A wrapper around a window handle. #[derive(Copy, Clone, PartialEq, Eq)] @@ -53,6 +53,14 @@ impl Window { }) } + /// Create a new Window instance from an existing ID + pub fn create_from_handle(display: &Display, id: u64) -> Result { + Ok(Window { + display: display.as_raw(), + inner: id, + }) + } + /// Get window attributes. pub fn get_attributes(&self) -> Result { let attr = unsafe { @@ -86,6 +94,25 @@ impl Window { ), ) } + + /// Change window property + // TODO: make it more general + pub fn change_property(&self, key: &Atom, val: &Atom) { + use std::mem::transmute; + let v = val.as_raw(); + unsafe { + x::XChangeProperty( + self.display, + self.inner, + key.as_raw(), + x::XA_ATOM, + 32, + x::PropModeReplace, + transmute(&v), + 1, + ); + } + } } impl GetDisplay for Window {