linux: Fix process PID to window mapping for X11 (#22348)

Closes #22326

This PR adds process PID information to window created by X11, so that
window manager can identify which process this window belongs to.
Without this property, the window manager would have no reliable way to
know which process created this window.

In original issue, `robotgo` throws error on `x, y, w, h :=
robotgo.GetBounds(pid)` this method. If we go deeper into the source
code of `robotgo`, it calls `GetXidFromPid` which goes through all
windows, and tries to check for provided pid. Hence, when it tries to do
that for Zed, it fails and returns `0, err` to caller.

```go
// Robotgo source code trying to look through all windows and query pid

// GetXidFromPid get the xid from pid
func GetXidFromPid(xu *xgbutil.XUtil, pid int) (xproto.Window, error) {
	windows, err := ewmh.ClientListGet(xu)
	if err != nil {
		return 0, err
	}

	for _, window := range windows {
		wmPid, err := ewmh.WmPidGet(xu, window)
		if err != nil {
			return 0, err
		}

		if uint(pid) == wmPid {
			return window, nil
		}
	}

	return 0, errors.New("failed to find a window with a matching pid.")
}
```

Querying for pid for active Zed window:

Before:
```sh
tims@lemon ~/w/go-repro [127]> xprop -root _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x4e00002
tims@lemon ~/w/go-repro> xprop -id 0x4e00002 _NET_WM_PID
_NET_WM_PID:  not found.
```

After:
```sh
tims@lemon ~/w/go-repro> xprop -root _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x4e00002
tims@lemon ~/w/go-repro> xprop -id 0x4e00002 _NET_WM_PID
_NET_WM_PID(CARDINAL) = 103548
tims@lemon ~/w/go-repro>
```

Correct zed process PID (below) assosiated with zed window (shown
above):

![image](https://github.com/user-attachments/assets/8b40128b-addb-4c88-944e-b1d26b908bf5)

Release Notes:

- Fix `robotgo` failing when Zed window is open on Linux
This commit is contained in:
tims 2025-01-04 05:40:36 +05:30 committed by GitHub
parent 71a0eb3b13
commit b46b261f11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -55,6 +55,7 @@ x11rb::atom_manager! {
WM_PROTOCOLS,
WM_DELETE_WINDOW,
WM_CHANGE_STATE,
_NET_WM_PID,
_NET_WM_NAME,
_NET_WM_STATE,
_NET_WM_STATE_MAXIMIZED_VERT,
@ -436,6 +437,18 @@ impl X11WindowState {
// Collect errors during setup, so that window can be destroyed on failure.
let setup_result = maybe!({
let pid = std::process::id();
check_reply(
|| "X11 ChangeProperty for _NET_WM_PID failed.",
xcb.change_property32(
xproto::PropMode::REPLACE,
x_window,
atoms._NET_WM_PID,
xproto::AtomEnum::CARDINAL,
&[pid],
),
)?;
if let Some(size) = params.window_min_size {
let mut size_hints = WmSizeHints::new();
let min_size = (size.width.0 as i32, size.height.0 as i32);