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

1
debian/control vendored
View File

@ -14,6 +14,7 @@ Build-Depends:
libdtkcore-dev (>=5.4.14),
libdtkcore5-bin (>=5.4.14),
libxcb1-dev,
libxres-dev,
libxcb-icccm4-dev,
libxcb-ewmh-dev,
libx11-dev,

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)

View File

@ -11,6 +11,7 @@ find_package(DtkWidget REQUIRED)
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb-icccm xcb-ewmh xcb)
pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11)
pkg_check_modules(XRes REQUIRED IMPORTED_TARGET xres)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0 gio-unix-2.0)
pkg_check_modules(GLib REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(QGSettings REQUIRED IMPORTED_TARGET gsettings-qt)
@ -57,6 +58,7 @@ target_link_libraries(${BIN_NAME}
pthread
PkgConfig::XCB
PkgConfig::X11
PkgConfig::XRes
PkgConfig::GIO
PkgConfig::GLib
PkgConfig::QGSettings
@ -66,6 +68,7 @@ target_link_libraries(${BIN_NAME}
target_include_directories(${BIN_NAME} PUBLIC
PkgConfig::XCB
PkgConfig::X11
PkgConfig::XRes
PkgConfig::GIO
PkgConfig::GLib
PkgConfig::QGSettings