diff options
author | Aleksei Bavshin <alebastr89@gmail.com> | 2021-04-16 19:27:12 -0700 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2021-04-23 09:55:01 +0200 |
commit | e0f239fa2828318e9eff6b68f7faafecd338914c (patch) | |
tree | b871ac9fffed0a3aebe3a2c73a9aa389675db1d4 /xwayland/xwm.c | |
parent | c314920a3d2bcb347d9ae491a678d8349f32ae8d (diff) |
xwayland: query window PIDs via XResQueryClientIds
`_NET_WM_PID` is unreliable: it is optional and even if set it may
contain PIDs from sandbox namespaces or remote systems.
Prefer XRes v1.2 QueryClientIds method which returns PIDs as seen by the
Xwayland server.
Diffstat (limited to 'xwayland/xwm.c')
-rw-r--r-- | xwayland/xwm.c | 63 |
1 files changed, 63 insertions, 0 deletions
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) { |