From 3d6efc4aaff80301c0b10b7b6ba297eb5e54c1a0 Mon Sep 17 00:00:00 2001 From: mntmn Date: Sat, 22 Feb 2020 17:25:15 +0100 Subject: [PATCH] xwayland: port rooted xwayland from wl_shell to xdg-shell protocol Recently, rooted Xwayland crashes on wlroots-based compositors, because wlroots removed the deprecated wl_shell protocol. This MR fixes this by changing the code in question to the xdg-shell protocol. My motivation do this: on etnaviv-based embedded platforms, rooted Xwayland is much faster and doesn't cause UI rendering bugs compared to rootless Xwayland. Signed-off-by: Lukas F. Hartmann --- hw/xwayland/Makefile.am | 9 ++++++- hw/xwayland/meson.build | 3 +++ hw/xwayland/xwayland-screen.c | 21 +++++++++++++--- hw/xwayland/xwayland-screen.h | 2 +- hw/xwayland/xwayland-window.c | 46 ++++++++++++++--------------------- hw/xwayland/xwayland-window.h | 2 +- 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am index 5bb088f80..309efd4cc 100644 --- a/hw/xwayland/Makefile.am +++ b/hw/xwayland/Makefile.am @@ -100,7 +100,9 @@ Xwayland_built_sources += \ linux-dmabuf-unstable-v1-client-protocol.h \ linux-dmabuf-unstable-v1-protocol.c \ viewporter-client-protocol.h \ - viewporter-protocol.c + viewporter-protocol.c\ + xdg-shell-client-protocol.h\ + xdg-shell-protocol.c if XWAYLAND_EGLSTREAM Xwayland_built_sources += \ @@ -154,6 +156,11 @@ viewporter-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter viewporter-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ +xdg-shell-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@ +xdg-shell-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ + wayland-eglstream-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ wayland-eglstream-controller-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build index b6d060363..2e32a0780 100644 --- a/hw/xwayland/meson.build +++ b/hw/xwayland/meson.build @@ -40,6 +40,7 @@ kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwaylan xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml') dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml') viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml') +xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml') client_header = generator(scanner, output : '@BASENAME@-client-protocol.h', @@ -63,6 +64,7 @@ srcs += client_header.process(kbgrab_xml) srcs += client_header.process(xdg_output_xml) srcs += client_header.process(dmabuf_xml) srcs += client_header.process(viewporter_xml) +srcs += client_header.process(xdg_shell_xml) srcs += code.process(relative_xml) srcs += code.process(pointer_xml) srcs += code.process(tablet_xml) @@ -70,6 +72,7 @@ srcs += code.process(kbgrab_xml) srcs += code.process(xdg_output_xml) srcs += code.process(dmabuf_xml) srcs += code.process(viewporter_xml) +srcs += code.process(xdg_shell_xml) xwayland_glamor = [] eglstream_srcs = [] diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 551efb9f0..9f275b540 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -54,6 +54,7 @@ #include "xdg-output-unstable-v1-client-protocol.h" #include "viewporter-client-protocol.h" +#include "xdg-shell-client-protocol.h" static DevPrivateKeyRec xwl_screen_private_key; static DevPrivateKeyRec xwl_client_private_key; @@ -318,6 +319,17 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) } } +static void +xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, + uint32_t serial) +{ + xdg_wm_base_pong(xdg_wm_base, serial); +} + +static const struct xdg_wm_base_listener xdg_wm_base_listener = { + xdg_wm_base_ping, +}; + static void registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) @@ -336,9 +348,12 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, else if (strcmp(interface, "wl_shm") == 0) { xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); } - else if (strcmp(interface, "wl_shell") == 0) { - xwl_screen->shell = - wl_registry_bind(registry, id, &wl_shell_interface, 1); + else if (strcmp(interface, "xdg_wm_base") == 0) { + xwl_screen->xdg_wm_base = + wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener(xwl_screen->xdg_wm_base, + &xdg_wm_base_listener, + NULL); } else if (strcmp(interface, "wl_output") == 0 && version >= 2) { if (xwl_output_create(xwl_screen, id)) diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index abfbc9f1b..69f42bd76 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -79,7 +79,7 @@ struct xwl_screen { struct wl_compositor *compositor; struct zwp_tablet_manager_v2 *tablet_manager; struct wl_shm *shm; - struct wl_shell *shell; + struct xdg_wm_base *xdg_wm_base; struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; struct zwp_pointer_constraints_v1 *pointer_constraints; struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab; diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index 63024ac70..09c854134 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -44,6 +44,7 @@ #include "xwayland-shm.h" #include "viewporter-client-protocol.h" +#include "xdg-shell-client-protocol.h" static DevPrivateKeyRec xwl_window_private_key; static DevPrivateKeyRec xwl_damage_private_key; @@ -401,28 +402,15 @@ send_surface_id_event(struct xwl_window *xwl_window) } static void -shell_surface_ping(void *data, - struct wl_shell_surface *shell_surface, uint32_t serial) +xdg_surface_handle_configure(void *data, + struct xdg_surface *xdg_surface, + uint32_t serial) { - wl_shell_surface_pong(shell_surface, serial); + xdg_surface_ack_configure(xdg_surface, serial); } -static void -shell_surface_configure(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t edges, int32_t width, int32_t height) -{ -} - -static void -shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface) -{ -} - -static const struct wl_shell_surface_listener shell_surface_listener = { - shell_surface_ping, - shell_surface_configure, - shell_surface_popup_done +static const struct xdg_surface_listener xdg_surface_listener = { + xdg_surface_handle_configure, }; static Bool @@ -461,17 +449,19 @@ ensure_surface_for_window(WindowPtr window) } if (!xwl_screen->rootless) { - xwl_window->shell_surface = - wl_shell_get_shell_surface(xwl_screen->shell, xwl_window->surface); - if (xwl_window->shell_surface == NULL) { - ErrorF("Failed creating shell surface\n"); + xwl_window->xdg_surface = + xdg_wm_base_get_xdg_surface(xwl_screen->xdg_wm_base, xwl_window->surface); + if (xwl_window->xdg_surface == NULL) { + ErrorF("Failed creating xdg_wm_base xdg_surface\n"); goto err_surf; } - wl_shell_surface_add_listener(xwl_window->shell_surface, - &shell_surface_listener, xwl_window); + xdg_surface_add_listener(xwl_window->xdg_surface, + &xdg_surface_listener, xwl_window); - wl_shell_surface_set_toplevel(xwl_window->shell_surface); + xdg_surface_get_toplevel(xwl_window->xdg_surface); + + wl_surface_commit(xwl_window->surface); region = wl_compositor_create_region(xwl_screen->compositor); if (region == NULL) { @@ -520,8 +510,8 @@ ensure_surface_for_window(WindowPtr window) return TRUE; err_surf: - if (xwl_window->shell_surface) - wl_shell_surface_destroy(xwl_window->shell_surface); + if (xwl_window->xdg_surface) + xdg_surface_destroy(xwl_window->xdg_surface); wl_surface_destroy(xwl_window->surface); err: free(xwl_window); diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h index 86292e930..d94f07204 100644 --- a/hw/xwayland/xwayland-window.h +++ b/hw/xwayland/xwayland-window.h @@ -42,7 +42,7 @@ struct xwl_window { struct wl_surface *surface; struct wp_viewport *viewport; float scale_x, scale_y; - struct wl_shell_surface *shell_surface; + struct xdg_surface *xdg_surface; WindowPtr window; struct xorg_list link_damage; struct xorg_list link_window;