xwm: reading all surface properties at xwayland_surface_create

Signed-off-by: xurui <xurui@kylinos.cn>
This commit is contained in:
xurui 2026-02-26 14:25:35 +08:00
parent 1ce992d7cb
commit c663c5832f

View file

@ -174,6 +174,20 @@ static void read_surface_client_id(struct wlr_xwm *xwm,
free(reply); free(reply);
} }
static void read_surface_property(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface, xcb_atom_t property,
xcb_get_property_reply_t *reply);
static xcb_get_property_cookie_t get_property(struct wlr_xwm *xwm,
xcb_window_t window_id, xcb_atom_t atom) {
uint32_t len = 2048;
if (atom == xwm->atoms[NET_WM_ICON]) {
/* Compositors need to fetch icon data wlr_xwayland_surface_fetch_icon() */
len = 0;
}
return xcb_get_property(xwm->xcb_conn, 0, window_id, atom, XCB_ATOM_ANY, 0, len);
}
static struct wlr_xwayland_surface *xwayland_surface_create( static struct wlr_xwayland_surface *xwayland_surface_create(
struct wlr_xwm *xwm, xcb_window_t window_id, int16_t x, int16_t y, struct wlr_xwm *xwm, xcb_window_t window_id, int16_t x, int16_t y,
uint16_t width, uint16_t height, bool override_redirect) { uint16_t width, uint16_t height, bool override_redirect) {
@ -275,6 +289,39 @@ static struct wlr_xwayland_surface *xwayland_surface_create(
read_surface_client_id(xwm, surface, client_id_cookie); read_surface_client_id(xwm, surface, client_id_cookie);
} }
// read all surface properties
const xcb_atom_t props[] = {
XCB_ATOM_WM_CLASS,
XCB_ATOM_WM_NAME,
XCB_ATOM_WM_TRANSIENT_FOR,
xwm->atoms[WM_PROTOCOLS],
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_STRUT_PARTIAL],
xwm->atoms[NET_WM_WINDOW_TYPE],
xwm->atoms[NET_WM_NAME],
xwm->atoms[NET_WM_ICON],
};
xcb_get_property_cookie_t cookies[sizeof(props) / sizeof(props[0])] = {0};
for (size_t i = 0; i < sizeof(props) / sizeof(props[0]); i++) {
cookies[i] = get_property(xwm, surface->window_id, props[i]);
}
for (size_t i = 0; i < sizeof(props) / sizeof(props[0]); i++) {
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xwm->xcb_conn, cookies[i], NULL);
if (reply == NULL) {
wlr_log(WLR_ERROR, "Failed to get window property");
continue;
}
read_surface_property(xwm, surface, props[i], reply);
free(reply);
}
wl_signal_emit_mutable(&xwm->xwayland->events.new_surface, surface); wl_signal_emit_mutable(&xwm->xwayland->events.new_surface, surface);
return surface; return surface;
@ -1165,16 +1212,6 @@ bool wlr_xwayland_surface_fetch_icon(
return true; return true;
} }
static xcb_get_property_cookie_t get_property(struct wlr_xwm *xwm,
xcb_window_t window_id, xcb_atom_t atom) {
uint32_t len = 2048;
if (atom == xwm->atoms[NET_WM_ICON]) {
/* Compositors need to fetch icon data wlr_xwayland_surface_fetch_icon() */
len = 0;
}
return xcb_get_property(xwm->xcb_conn, 0, window_id, atom, XCB_ATOM_ANY, 0, len);
}
static void xwayland_surface_associate(struct wlr_xwm *xwm, static void xwayland_surface_associate(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface, struct wlr_surface *surface) { struct wlr_xwayland_surface *xsurface, struct wlr_surface *surface) {
assert(xsurface->surface == NULL); assert(xsurface->surface == NULL);
@ -1195,39 +1232,6 @@ static void xwayland_surface_associate(struct wlr_xwm *xwm,
xsurface->surface_unmap.notify = xwayland_surface_handle_unmap; xsurface->surface_unmap.notify = xwayland_surface_handle_unmap;
wl_signal_add(&surface->events.unmap, &xsurface->surface_unmap); wl_signal_add(&surface->events.unmap, &xsurface->surface_unmap);
// read all surface properties
const xcb_atom_t props[] = {
XCB_ATOM_WM_CLASS,
XCB_ATOM_WM_NAME,
XCB_ATOM_WM_TRANSIENT_FOR,
xwm->atoms[WM_PROTOCOLS],
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_STRUT_PARTIAL],
xwm->atoms[NET_WM_WINDOW_TYPE],
xwm->atoms[NET_WM_NAME],
xwm->atoms[NET_WM_ICON],
};
xcb_get_property_cookie_t cookies[sizeof(props) / sizeof(props[0])] = {0};
for (size_t i = 0; i < sizeof(props) / sizeof(props[0]); i++) {
cookies[i] = get_property(xwm, xsurface->window_id, props[i]);
}
for (size_t i = 0; i < sizeof(props) / sizeof(props[0]); i++) {
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xwm->xcb_conn, cookies[i], NULL);
if (reply == NULL) {
wlr_log(WLR_ERROR, "Failed to get window property");
continue;
}
read_surface_property(xwm, xsurface, props[i], reply);
free(reply);
}
wl_signal_emit_mutable(&xsurface->events.associate, NULL); wl_signal_emit_mutable(&xsurface->events.associate, NULL);
} }