Skip to content

Commit

Permalink
Support setting _NET_WM_PID in X11 environments
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jwilm committed May 1, 2017
1 parent 09031de commit 5745860
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
52 changes: 50 additions & 2 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
///
Expand Down

0 comments on commit 5745860

Please sign in to comment.