fix: use XResQueryClientIds to get pid of xwindow

Code copy from https://gitlab.gnome.org/GNOME/metacity/-/merge_requests/13/diffs

The xprop `_NET_WM_PID` is set by the client side, even if the process
in running in some container. But when pid_ns is unshared, the processes
in side a container, will not be able to get the "right" pid of itself.

The "new" XResQueryClientIds added to XRes will fix this issue by
produce the pid in server side.

refs:

- https://gitlab.freedesktop.org/xorg/xserver/-/issues/1022#note_497597
- https://www.x.org/releases/X11R7.7/doc/resourceproto/resproto.txt

close linuxdeepin/developer-center#3802
This commit is contained in:
black-desk
2023-04-03 15:51:06 +08:00
committed by deepin-bot[bot]
parent 9b82262a4e
commit 29e7ef2f00
3 changed files with 36 additions and 5 deletions

View File

@ -6,6 +6,10 @@
#include <iostream>
#include <cstring>
#include <memory>
#include <X11/Xlib.h>
#include <X11/extensions/XRes.h>
XCBUtils::XCBUtils()
{
@ -371,13 +375,36 @@ std::string XCBUtils::getWMName(XWindow xid)
uint32_t XCBUtils::getWMPid(XWindow xid)
{
uint32_t ret = 0;
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_pid(&m_ewmh, xid);
if (!xcb_ewmh_get_wm_pid_reply(&m_ewmh, cookie, &ret, nullptr)) {
std::cout << xid << " getWMPid error" << std::endl;
// NOTE(black_desk): code copy from https://gitlab.gnome.org/GNOME/metacity/-/merge_requests/13/diffs
XResClientIdSpec spec = {
.client = xid,
.mask = XRES_CLIENT_ID_PID_MASK,
};
std::shared_ptr<Display> dpy = {
XOpenDisplay(nullptr),
[](Display *p){ XCloseDisplay(p); },
};
long num_ids;
XResClientIdValue *client_ids;
XResQueryClientIds(dpy.get(),
1,
&spec,
&num_ids,
&client_ids);
pid_t pid = -1;
for (long i = 0; i < num_ids; i++) {
if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) {
pid = XResGetClientPid(&client_ids[i]);
break;
}
}
return ret;
XResClientIdsDestroy(num_ids, client_ids);
return pid;
}
std::string XCBUtils::getWMIconName(XWindow xid)