aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xwayland/xwm.h1
-rw-r--r--xwayland/meson.build1
-rw-r--r--xwayland/xwm.c63
3 files changed, 65 insertions, 0 deletions
diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h
index 587f136b..05d229ae 100644
--- a/include/xwayland/xwm.h
+++ b/include/xwayland/xwm.h
@@ -113,6 +113,7 @@ struct wlr_xwm {
struct wlr_xwayland_surface *drag_focus;
const xcb_query_extension_reply_t *xfixes;
+ const xcb_query_extension_reply_t *xres;
#if HAS_XCB_ERRORS
xcb_errors_context_t *errors_context;
#endif
diff --git a/xwayland/meson.build b/xwayland/meson.build
index bbf96eac..b7bbcaf1 100644
--- a/xwayland/meson.build
+++ b/xwayland/meson.build
@@ -4,6 +4,7 @@ xwayland_required = [
'xcb-composite',
'xcb-icccm',
'xcb-render',
+ 'xcb-res',
'xcb-xfixes',
]
xwayland_optional = {
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index f380f8f1..9ac2773d 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -14,6 +14,7 @@
#include <wlr/xwayland.h>
#include <xcb/composite.h>
#include <xcb/render.h>
+#include <xcb/res.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xfixes.h>
#include "util/signal.h"
@@ -510,6 +511,41 @@ static void read_surface_parent(struct wlr_xwm *xwm,
wlr_signal_emit_safe(&xsurface->events.set_parent, xsurface);
}
+static void read_surface_client_id(struct wlr_xwm *xwm,
+ struct wlr_xwayland_surface *xsurface) {
+ xcb_res_client_id_spec_t spec = {
+ .client = xsurface->window_id,
+ .mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID
+ };
+
+ xcb_res_query_client_ids_cookie_t cookie = xcb_res_query_client_ids(
+ xwm->xcb_conn, 1, &spec);
+ xcb_res_query_client_ids_reply_t *reply = xcb_res_query_client_ids_reply(
+ xwm->xcb_conn, cookie, NULL);
+ if (reply == NULL) {
+ return;
+ }
+
+ uint32_t *pid = NULL;
+ xcb_res_client_id_value_iterator_t iter =
+ xcb_res_query_client_ids_ids_iterator(reply);
+ while (iter.rem > 0) {
+ if (iter.data->spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID &&
+ xcb_res_client_id_value_value_length(iter.data) > 0) {
+ pid = xcb_res_client_id_value_value(iter.data);
+ break;
+ }
+ xcb_res_client_id_value_next(&iter);
+ }
+ if (pid == NULL) {
+ free(reply);
+ return;
+ }
+ xsurface->pid = *pid;
+ wlr_signal_emit_safe(&xsurface->events.set_pid, xsurface);
+ free(reply);
+}
+
static void read_surface_pid(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface,
xcb_get_property_reply_t *reply) {
@@ -818,6 +854,9 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm,
for (size_t i = 0; i < sizeof(props)/sizeof(xcb_atom_t); i++) {
read_surface_property(xwm, xsurface, props[i]);
}
+ if (xwm->xres) {
+ read_surface_client_id(xwm, xsurface);
+ }
xsurface->surface_destroy.notify = handle_surface_destroy;
wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy);
@@ -1621,6 +1660,7 @@ void xwm_destroy(struct wlr_xwm *xwm) {
static void xwm_get_resources(struct wlr_xwm *xwm) {
xcb_prefetch_extension_data(xwm->xcb_conn, &xcb_xfixes_id);
xcb_prefetch_extension_data(xwm->xcb_conn, &xcb_composite_id);
+ xcb_prefetch_extension_data(xwm->xcb_conn, &xcb_res_id);
size_t i;
xcb_intern_atom_cookie_t cookies[ATOM_LAST];
@@ -1664,6 +1704,29 @@ static void xwm_get_resources(struct wlr_xwm *xwm) {
xfixes_reply->major_version, xfixes_reply->minor_version);
free(xfixes_reply);
+
+ const xcb_query_extension_reply_t *xres =
+ xcb_get_extension_data(xwm->xcb_conn, &xcb_res_id);
+ if (!xres || !xres->present) {
+ return;
+ }
+
+ xcb_res_query_version_cookie_t xres_cookie =
+ xcb_res_query_version(xwm->xcb_conn, XCB_RES_MAJOR_VERSION,
+ XCB_RES_MINOR_VERSION);
+ xcb_res_query_version_reply_t *xres_reply =
+ xcb_res_query_version_reply(xwm->xcb_conn, xres_cookie, NULL);
+ if (xres_reply == NULL) {
+ return;
+ }
+
+ wlr_log(WLR_DEBUG, "xres version: %" PRIu32 ".%" PRIu32,
+ xres_reply->server_major, xres_reply->server_minor);
+ if (xres_reply->server_major > 1 ||
+ (xres_reply->server_major == 1 && xres_reply->server_minor >= 2)) {
+ xwm->xres = xres;
+ }
+ free(xres_reply);
}
static void xwm_create_wm_window(struct wlr_xwm *xwm) {