This commit is contained in:
Hiroaki Yamamoto 2025-10-21 09:42:52 +01:00 committed by GitHub
commit 5cccad9606
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 17 additions and 120 deletions

View file

@ -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;

View file

@ -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'

View file

@ -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;

View file

@ -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");

View file

@ -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