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 <lukas@mntre.com>
This commit is contained in:
mntmn 2020-02-22 17:25:15 +01:00 committed by Olivier Fourdan
parent de940e06f8
commit 3d6efc4aaf
6 changed files with 49 additions and 34 deletions

View File

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

View File

@ -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 = []

View File

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

View File

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

View File

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

View File

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