diff options
author | Joe Wilm <joe@jwilm.com> | 2017-04-26 10:26:46 -0700 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-05-01 08:36:09 -0700 |
commit | 574586045f08307b310983ed713972d0b6a45c30 (patch) | |
tree | 0419c4d54ca292c06e6411979a40e8a26e029ca7 | |
parent | 09031decc0510c107804aea490e437176bbb3535 (diff) | |
download | alacritty-574586045f08307b310983ed713972d0b6a45c30.tar.gz alacritty-574586045f08307b310983ed713972d0b6a45c30.zip |
Support setting _NET_WM_PID in X11 environments
Support is added for setting _NET_WM_PID automatically. This is to
support scripting of the window environment. For example, this makes it
possible to script opening a window with same CWD:
1. Retrieve the current window
2. (new) get PID of window
3. Check if it's Alacritty, find first child (presumably a shell), and
get the child's cwd.
4. Spawn new instance of terminal with cwd.
Unaddressed in this commit is how this will coexist on a Wayland system.
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/window.rs | 52 |
4 files changed, 57 insertions, 2 deletions
@@ -24,6 +24,7 @@ dependencies = [ "serde_yaml 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "vte 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -35,6 +35,9 @@ unicode-width = "0.1.4" clippy = { version = "0.0.104", optional = true } +[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))'.dependencies] +x11-dl = "2.12.0" + [features] default = ["err-println"] # Enabling this feature makes shaders automatically reload when changed @@ -27,6 +27,9 @@ #[macro_use] extern crate log; #[macro_use] extern crate serde_derive; +#[cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))] +extern crate x11_dl; + extern crate cgmath; extern crate copypasta; extern crate errno; diff --git a/src/window.rs b/src/window.rs index a69bd0ea..b821c77b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -217,10 +217,14 @@ impl Window { window.make_current()?; } - Ok(Window { + let window = Window { glutin_window: window, cursor_visible: true, - }) + }; + + window.run_os_extensions(); + + Ok(window) } /// Get some properties about the device @@ -301,6 +305,50 @@ impl Window { } } +pub trait OsExtensions { + fn run_os_extensions(&self) {} +} + +#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd")))] +impl OsExtensions for Window { } + +#[cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))] +impl OsExtensions for Window { + fn run_os_extensions(&self) { + use ::glutin::os::unix::WindowExt; + use ::x11_dl::xlib::{self, XA_CARDINAL, PropModeReplace}; + use ::std::ffi::{CStr}; + use ::std::ptr; + use ::libc::getpid; + + let xlib_display = self.glutin_window.get_xlib_display(); + let xlib_window = self.glutin_window.get_xlib_window(); + + if let (Some(xlib_window), Some(xlib_display)) = (xlib_window, xlib_display) { + let xlib = xlib::Xlib::open().expect("get xlib"); + + // Set _NET_WM_PID to process pid + unsafe { + let _net_wm_pid = CStr::from_ptr(b"_NET_WM_PID\0".as_ptr() as *const _); + let atom = (xlib.XInternAtom)(xlib_display as *mut _, _net_wm_pid.as_ptr(), 0); + let pid = getpid(); + + (xlib.XChangeProperty)(xlib_display as _, xlib_window as _, atom, + XA_CARDINAL, 32, PropModeReplace, &pid as *const i32 as *const u8, 1); + + } + // Although this call doesn't actually pass any data, it does cause + // WM_CLIENT_MACHINE to be set. WM_CLIENT_MACHINE MUST be set if _NET_WM_PID is set + // (which we do above). + unsafe { + (xlib.XSetWMProperties)(xlib_display as _, xlib_window as _, ptr::null_mut(), + ptr::null_mut(), ptr::null_mut(), 0, ptr::null_mut(), ptr::null_mut(), + ptr::null_mut()); + } + } + } +} + impl Proxy { /// Wakes up the event loop of the window /// |