diff --git a/configure.ac b/configure.ac index 0f64aceba..81f1c3144 100644 --- a/configure.ac +++ b/configure.ac @@ -85,6 +85,7 @@ MUTTER_PC_MODULES=" xrender x11-xcb xcb-randr + xcb-res " GLIB_GSETTINGS diff --git a/src/core/window-private.h b/src/core/window-private.h index 7793dccb9..67abbccd8 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -524,6 +524,7 @@ struct _MetaWindowClass gboolean (*update_icon) (MetaWindow *window, cairo_surface_t **icon, cairo_surface_t **mini_icon); + uint32_t (*get_client_pid) (MetaWindow *window); void (*update_main_monitor) (MetaWindow *window); void (*main_monitor_changed) (MetaWindow *window, const MetaMonitorInfo *old); @@ -705,6 +706,8 @@ void meta_window_handle_leave (MetaWindow *window); void meta_window_handle_ungrabbed_event (MetaWindow *window, const ClutterEvent *event); +uint32_t meta_window_get_client_pid (MetaWindow *window); + void meta_window_get_client_area_rect (const MetaWindow *window, cairo_rectangle_int_t *rect); void meta_window_get_titlebar_rect (MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index 60716fb56..3fea48353 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -253,6 +253,12 @@ meta_window_real_update_icon (MetaWindow *window, return FALSE; } +static uint32_t +meta_window_real_get_client_pid (MetaWindow *window) +{ + return 0; +} + static void meta_window_finalize (GObject *object) { @@ -420,6 +426,7 @@ meta_window_class_init (MetaWindowClass *klass) klass->update_struts = meta_window_real_update_struts; klass->get_default_skip_hints = meta_window_real_get_default_skip_hints; klass->update_icon = meta_window_real_update_icon; + klass->get_client_pid = meta_window_real_get_client_pid; obj_props[PROP_TITLE] = g_param_spec_string ("title", @@ -7055,6 +7062,21 @@ meta_window_get_transient_for (MetaWindow *window) return NULL; } +/** + * meta_window_get_client_pid: + * @window: a #MetaWindow + * + * Returns the pid of the process that created this window, if available + * to the windowing system. + * + * Return value: the pid, or 0 if not known. + */ +uint32_t +meta_window_get_client_pid (MetaWindow *window) +{ + return META_WINDOW_GET_CLASS (window)->get_client_pid (window); +} + /** * meta_window_get_pid: * @window: a #MetaWindow diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index 7dd6f4247..b74a8fac6 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -453,6 +453,17 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window, meta_window_emit_size_changed (window); } +static uint32_t +meta_window_wayland_get_client_pid (MetaWindow *window) +{ + MetaWaylandSurface *surface = window->surface; + struct wl_resource *resource = surface->resource; + pid_t pid; + + wl_client_get_credentials (wl_resource_get_client (resource), &pid, NULL, NULL); + return (uint32_t)pid; +} + static void appears_focused_changed (GObject *object, GParamSpec *pspec, @@ -487,6 +498,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->move_resize_internal = meta_window_wayland_move_resize_internal; window_class->update_main_monitor = meta_window_wayland_update_main_monitor; window_class->main_monitor_changed = meta_window_wayland_main_monitor_changed; + window_class->get_client_pid = meta_window_wayland_get_client_pid; } MetaWindow * diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 3d47f0d4e..c8b9b0426 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -28,6 +28,9 @@ #include #include #include /* For display->resource_mask */ +#include + +#include #include @@ -1481,6 +1484,42 @@ meta_window_x11_main_monitor_changed (MetaWindow *window, { } +static uint32_t +meta_window_x11_get_client_pid (MetaWindow *window) +{ + xcb_connection_t *xcb = XGetXCBConnection (window->display->xdisplay); + xcb_res_client_id_spec_t spec = { 0 }; + xcb_res_query_client_ids_cookie_t cookie; + xcb_res_query_client_ids_reply_t *reply = NULL; + + spec.client = window->xwindow; + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; + + cookie = xcb_res_query_client_ids (xcb, 1, &spec); + reply = xcb_res_query_client_ids_reply (xcb, cookie, NULL); + + if (reply == NULL) + return 0; + + uint32_t pid = 0, *value; + xcb_res_client_id_value_iterator_t it; + for (it = xcb_res_query_client_ids_ids_iterator (reply); + it.rem; + xcb_res_client_id_value_next (&it)) + { + spec = it.data->spec; + if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) + { + value = xcb_res_client_id_value_value (it.data); + pid = *value; + break; + } + } + + free (reply); + return pid; +} + static void meta_window_x11_class_init (MetaWindowX11Class *klass) { @@ -1501,6 +1540,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->update_icon = meta_window_x11_update_icon; window_class->update_main_monitor = meta_window_x11_update_main_monitor; window_class->main_monitor_changed = meta_window_x11_main_monitor_changed; + window_class->get_client_pid = meta_window_x11_get_client_pid; } void