-
I wrote this code to try and get GParted's window to be topped, but it doesn't seem to have any effect: use std::process::Command;
use anyhow::{Context, Result};
use sysinfo::System;
use x11rb::{
connection::Connection,
protocol::xproto::{AtomEnum, ClientMessageEvent, ConnectionExt, EventMask},
};
fn main() -> Result<()> {
let mut process = Command::new("gparted").spawn()?;
let mut system = System::new();
'a: loop {
system.refresh_all();
for process in system.processes_by_name("gpartedbin") {
pin_window(process.pid().as_u32())?;
break 'a;
}
}
process.wait()?;
Ok(())
}
pub fn pin_window(pin_pid: u32) -> Result<()> {
let mut fined = false;
while !fined {
let (conn, screen_num) = x11rb::connect(None).unwrap();
let screen = &conn.setup().roots[screen_num];
let root_id = screen.root;
let cookie = conn.intern_atom(true, b"_NET_CLIENT_LIST")?;
let atom = cookie.reply()?.atom;
let reply = conn
.get_property(false, root_id, atom, AtomEnum::ANY, 0, u32::MAX)?
.reply()?;
let windows = reply.value32().context("illage reply")?.collect::<Vec<_>>();
let cookie = conn.intern_atom(true, b"_NET_WM_PID")?;
let atom = cookie.reply()?.atom;
let pin_window_cookie = conn.intern_atom(true, b"_NET_WM_STATE_ABOVE")?;
let pin_window_atom = pin_window_cookie.reply()?.atom;
let sticky_window = conn.intern_atom(true, b"_NET_WM_STATE_STICKY")?;
let sticky_window = sticky_window.reply()?.atom;
let window_state_cookie = conn.intern_atom(true, b"_NET_WM_STATE")?;
let window_state_atom = window_state_cookie.reply()?.atom;
for window in windows {
let pid = conn
.get_property(false, window, atom, AtomEnum::ANY, 0, u32::MAX)?
.reply();
if let Ok(pid) = pid {
let pids = pid.value32().unwrap().collect::<Vec<_>>();
if pids.contains(&pin_pid) {
fined = true;
dbg!(window);
let event = ClientMessageEvent::new(
32,
window,
window_state_atom,
[2, pin_window_atom, sticky_window, 0, 0],
);
conn.send_event(
false,
window,
EventMask::SUBSTRUCTURE_REDIRECT | EventMask::SUBSTRUCTURE_NOTIFY,
event,
)?;
conn.flush()?;
}
}
}
}
Ok(())
} where |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
From a quick look (sorry, not much time right now): https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm46072576082640
You are sending the client message to the target window, but it should be sent to the root window. Also, instead of just doing Edit: Also, you can run |
Beta Was this translation helpful? Give feedback.
From a quick look (sorry, not much time right now):
https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm46072576082640
You are sending the client message to the target window, but it should be sent to the root window.
Also, instead of just doing
flush()
when you are done, I recommendsync()
(which sends a request and waits for the reply). I think there were cases whereflush()
+immediately closing the connection caused requests not to be handled (the X11 server handled the disconnect before it handled the just-written data).Edit: Also, you can run
xprop
…