diff --git a/include/xwayland.h b/include/xwayland.h index 5fa20e11..9307e466 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -51,6 +51,7 @@ struct xwayland_view { struct wl_listener set_override_redirect; struct wl_listener set_strut_partial; struct wl_listener set_window_type; + struct wl_listener set_icon; struct wl_listener focus_in; struct wl_listener map_request; diff --git a/meson.build b/meson.build index 335bf629..ba3a2148 100644 --- a/meson.build +++ b/meson.build @@ -51,9 +51,9 @@ endif add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c') wlroots = dependency( - 'wlroots-0.19', + 'wlroots-0.20', default_options: ['default_library=static', 'examples=false'], - version: ['>=0.19.0', '<0.20.0'], + version: ['>=0.20.0', '<0.21.0'], ) wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' diff --git a/src/input/ime.c b/src/input/ime.c index 92d88ffe..ab24f927 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -583,7 +583,7 @@ input_method_relay_create(struct seat *seat) relay->popup_tree = wlr_scene_tree_create(&seat->server->scene->tree); relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&seat->server->text_input_manager->events.text_input, + wl_signal_add(&seat->server->text_input_manager->events.new_text_input, &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; diff --git a/src/xwayland.c b/src/xwayland.c index 6b408a78..96c4863e 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -24,20 +24,6 @@ #include "window-rules.h" #include "workspaces.h" -enum atoms { - ATOM_NET_WM_ICON = 0, - - ATOM_COUNT, -}; - -static const char * const atom_names[] = { - [ATOM_NET_WM_ICON] = "_NET_WM_ICON", -}; - -static_assert(ARRAY_SIZE(atom_names) == ATOM_COUNT, "atom names out of sync"); - -static xcb_atom_t atoms[ATOM_COUNT] = {0}; - static void xwayland_view_unmap(struct view *view, bool client_request); static struct xwayland_view * @@ -372,6 +358,7 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&xwayland_view->set_override_redirect.link); wl_list_remove(&xwayland_view->set_strut_partial.link); wl_list_remove(&xwayland_view->set_window_type.link); + wl_list_remove(&xwayland_view->set_icon.link); wl_list_remove(&xwayland_view->focus_in.link); wl_list_remove(&xwayland_view->map_request.link); @@ -578,30 +565,19 @@ handle_set_strut_partial(struct wl_listener *listener, void *data) } static void -update_icon(struct xwayland_view *xwayland_view) +handle_set_icon(struct wl_listener *listener, void *data) { - if (!xwayland_view->xwayland_surface) { - return; - } + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, set_icon); - xcb_window_t window_id = xwayland_view->xwayland_surface->window_id; - - xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection( - xwayland_view->base.server->xwayland); - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_conn, 0, - window_id, atoms[ATOM_NET_WM_ICON], XCB_ATOM_CARDINAL, 0, 0x10000); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_conn, cookie, NULL); - if (!reply) { - return; - } - xcb_ewmh_get_wm_icon_reply_t icon; - if (!xcb_ewmh_get_wm_icon_from_reply(&icon, reply)) { - wlr_log(WLR_INFO, "Invalid x11 icon"); + xcb_ewmh_get_wm_icon_reply_t icon_reply = {0}; + if (!wlr_xwayland_surface_fetch_icon(xwayland_view->xwayland_surface, + &icon_reply)) { view_set_icon(&xwayland_view->base, NULL, NULL); goto out; } - xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&icon); + xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&icon_reply); struct wl_array buffers; wl_array_init(&buffers); for (; iter.rem; xcb_ewmh_get_wm_icon_next(&iter)) { @@ -631,7 +607,7 @@ update_icon(struct xwayland_view *xwayland_view) wl_array_release(&buffers); out: - free(reply); + xcb_ewmh_get_wm_icon_reply_wipe(&icon_reply); } static void @@ -1088,6 +1064,7 @@ xwayland_view_create(struct server *server, CONNECT_SIGNAL(xsurface, xwayland_view, set_override_redirect); CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial); CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type); + CONNECT_SIGNAL(xsurface, xwayland_view, set_icon); CONNECT_SIGNAL(xsurface, xwayland_view, focus_in); CONNECT_SIGNAL(xsurface, xwayland_view, map_request); @@ -1120,85 +1097,6 @@ handle_new_surface(struct wl_listener *listener, void *data) } } -static struct xwayland_view * -xwayland_view_from_window_id(struct server *server, xcb_window_t id) -{ - struct view *view; - wl_list_for_each(view, &server->views, link) { - if (view->type != LAB_XWAYLAND_VIEW) { - continue; - } - struct xwayland_view *xwayland_view = xwayland_view_from_view(view); - if (xwayland_view->xwayland_surface - && xwayland_view->xwayland_surface->window_id == id) { - return xwayland_view; - } - } - return NULL; -} - -#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f -static bool -handle_x11_event(struct wlr_xwayland *wlr_xwayland, xcb_generic_event_t *event) -{ - switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { - case XCB_PROPERTY_NOTIFY: { - xcb_property_notify_event_t *ev = (void *)event; - if (ev->atom == atoms[ATOM_NET_WM_ICON]) { - struct server *server = wlr_xwayland->data; - struct xwayland_view *xwayland_view = - xwayland_view_from_window_id(server, ev->window); - if (xwayland_view) { - update_icon(xwayland_view); - } else { - wlr_log(WLR_DEBUG, "icon property changed for unknown window"); - } - return true; - } - break; - } - default: - break; - } - - return false; -} - -static void -sync_atoms(struct server *server) -{ - xcb_connection_t *xcb_conn = - wlr_xwayland_get_xwm_connection(server->xwayland); - assert(xcb_conn); - - wlr_log(WLR_DEBUG, "Syncing X11 atoms"); - xcb_intern_atom_cookie_t cookies[ATOM_COUNT]; - - /* First request everything and then loop over the results to reduce latency */ - for (size_t i = 0; i < ATOM_COUNT; i++) { - cookies[i] = xcb_intern_atom(xcb_conn, 0, - strlen(atom_names[i]), atom_names[i]); - } - - for (size_t i = 0; i < ATOM_COUNT; i++) { - xcb_generic_error_t *err = NULL; - xcb_intern_atom_reply_t *reply = - xcb_intern_atom_reply(xcb_conn, cookies[i], &err); - if (reply) { - atoms[i] = reply->atom; - wlr_log(WLR_DEBUG, "Got X11 atom for %s: %u", - atom_names[i], reply->atom); - } - if (err) { - atoms[i] = XCB_ATOM_NONE; - wlr_log(WLR_INFO, "Failed to get X11 atom for %s", - atom_names[i]); - } - free(reply); - free(err); - } -} - static void handle_server_ready(struct wl_listener *listener, void *data) { @@ -1207,7 +1105,6 @@ handle_server_ready(struct wl_listener *listener, void *data) struct server *server = wl_container_of(listener, server, xwayland_server_ready); - sync_atoms(server); } static void @@ -1242,7 +1139,6 @@ xwayland_server_init(struct server *server, struct wlr_compositor *compositor) &server->xwayland_xwm_ready); server->xwayland->data = server; - server->xwayland->user_event_handler = handle_x11_event; if (setenv("DISPLAY", server->xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland"); diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 25a947ed..6e4c298f 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,7 +1,7 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 0.19 +revision = 6d8bb66f98700472d05e57b8199d621e1cefe338 [provide] -dependency_names = wlroots-0.19 -wlroots-0.19=wlroots +dependency_names = wlroots-0.20 +wlroots-0.20=wlroots