diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 1f0e5019..a91638eb 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -159,6 +159,7 @@ struct wlr_xwayland_surface { char *class; char *instance; char *role; + char *startup_id; pid_t pid; bool has_utf8_title; @@ -205,6 +206,7 @@ struct wlr_xwayland_surface { struct wl_signal set_role; struct wl_signal set_parent; struct wl_signal set_pid; + struct wl_signal set_startup_id; struct wl_signal set_window_type; struct wl_signal set_hints; struct wl_signal set_decorations; diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index d564a0e2..5e6bfee3 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -55,6 +55,7 @@ enum atom_name { TEXT, TIMESTAMP, DELETE, + NET_STARTUP_ID, NET_WM_WINDOW_TYPE_NORMAL, NET_WM_WINDOW_TYPE_UTILITY, NET_WM_WINDOW_TYPE_TOOLTIP, diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 2be41168..49c2f908 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -60,6 +60,7 @@ const char *const atom_map[ATOM_LAST] = { [TEXT] = "TEXT", [TIMESTAMP] = "TIMESTAMP", [DELETE] = "DELETE", + [NET_STARTUP_ID] = "_NET_STARTUP_ID", [NET_WM_WINDOW_TYPE_NORMAL] = "_NET_WM_WINDOW_TYPE_NORMAL", [NET_WM_WINDOW_TYPE_UTILITY] = "_NET_WM_WINDOW_TYPE_UTILITY", [NET_WM_WINDOW_TYPE_TOOLTIP] = "_NET_WM_WINDOW_TYPE_TOOLTIP", @@ -165,6 +166,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create( wl_signal_init(&surface->events.set_title); wl_signal_init(&surface->events.set_parent); wl_signal_init(&surface->events.set_pid); + wl_signal_init(&surface->events.set_startup_id); wl_signal_init(&surface->events.set_window_type); wl_signal_init(&surface->events.set_hints); wl_signal_init(&surface->events.set_decorations); @@ -414,6 +416,7 @@ static void xwayland_surface_destroy( free(xsurface->role); free(xsurface->window_type); free(xsurface->protocols); + free(xsurface->startup_id); free(xsurface->hints); free(xsurface->size_hints); free(xsurface); @@ -448,6 +451,29 @@ static void read_surface_class(struct wlr_xwm *xwm, wlr_signal_emit_safe(&surface->events.set_class, surface); } +static void read_surface_startup_id(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *xsurface, + xcb_get_property_reply_t *reply) { + if (reply->type != XCB_ATOM_STRING && + reply->type != xwm->atoms[UTF8_STRING]) { + return; + } + + size_t len = xcb_get_property_value_length(reply); + char *startup_id = xcb_get_property_value(reply); + + free(xsurface->startup_id); + if (len > 0) { + xsurface->startup_id = strndup(startup_id, len); + } else { + xsurface->startup_id = NULL; + } + + wlr_log(WLR_DEBUG, "XCB_ATOM_NET_STARTUP_ID: %s", + xsurface->startup_id ? xsurface->startup_id: "(null)"); + wlr_signal_emit_safe(&xsurface->events.set_startup_id, xsurface); +} + static void read_surface_role(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { @@ -791,6 +817,8 @@ static void read_surface_property(struct wlr_xwm *xwm, read_surface_motif_hints(xwm, xsurface, reply); } else if (property == xwm->atoms[WM_WINDOW_ROLE]) { read_surface_role(xwm, xsurface, reply); + } else if (property == xwm->atoms[NET_STARTUP_ID]) { + read_surface_startup_id(xwm, xsurface, reply); } else { char *prop_name = xwm_get_atom_name(xwm, property); wlr_log(WLR_DEBUG, "unhandled X11 property %" PRIu32 " (%s) for window %" PRIu32, @@ -864,6 +892,7 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm, xwm->atoms[WM_HINTS], xwm->atoms[WM_NORMAL_HINTS], xwm->atoms[MOTIF_WM_HINTS], + xwm->atoms[NET_STARTUP_ID], xwm->atoms[NET_WM_STATE], xwm->atoms[NET_WM_WINDOW_TYPE], xwm->atoms[NET_WM_NAME],