From 03185e748b1db8e9586eaafa42bd92bb1938dcfe Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Tue, 27 Jul 2021 18:35:00 -0400 Subject: [PATCH] wayland: Tag/Check wl_output objects as well, fixes crashes when libdecor is in use --- src/video/wayland/SDL_waylandvideo.c | 34 +++++++++++++++++++++++++++ src/video/wayland/SDL_waylandvideo.h | 5 ++++ src/video/wayland/SDL_waylandwindow.c | 18 +++----------- src/video/wayland/SDL_waylandwindow.h | 2 -- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 7510714ee..0a5cf6e08 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -127,6 +127,39 @@ get_classname() return SDL_strdup("SDL_App"); } +static const char *SDL_WAYLAND_surface_tag = "sdl-window"; +static const char *SDL_WAYLAND_output_tag = "sdl-output"; + +void SDL_WAYLAND_register_surface(struct wl_surface *surface) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag); + } +} + +void SDL_WAYLAND_register_output(struct wl_output *output) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag); + } +} + +SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag; + } + return SDL_TRUE; /* For older clients we have to assume this is us... */ +} + +SDL_bool SDL_WAYLAND_own_output(struct wl_output *output) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + return wl_proxy_get_tag((struct wl_proxy *) output) == &SDL_WAYLAND_output_tag; + } + return SDL_TRUE; /* For older clients we have to assume this is us... */ +} + static void Wayland_DeleteDevice(SDL_VideoDevice *device) { @@ -392,6 +425,7 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id) data->scale_factor = 1.0; wl_output_add_listener(output, &output_listener, data); + SDL_WAYLAND_register_output(output); } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index 64f4bdac4..f44706f1c 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -91,6 +91,11 @@ typedef struct { SDL_bool done; } SDL_WaylandOutputData; +extern void SDL_WAYLAND_register_surface(struct wl_surface *surface); +extern void SDL_WAYLAND_register_output(struct wl_output *output); +extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface); +extern SDL_bool SDL_WAYLAND_own_output(struct wl_output *output); + #endif /* SDL_waylandvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 81d16076b..daeb55f13 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -42,16 +42,6 @@ #include #endif -static const char *SDL_WAYLAND_surface_tag = "sdl-window"; - -SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface) -{ - if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { - return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag; - } - return SDL_TRUE; /* For older clients we have to assume this is us... */ -} - static void CommitMinMaxDimensions(SDL_Window *window) { @@ -488,7 +478,7 @@ handle_surface_enter(void *data, struct wl_surface *surface, SDL_WindowData *window = data; SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); - if (!SDL_WAYLAND_own_surface(surface)) { + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { return; } @@ -508,7 +498,7 @@ handle_surface_leave(void *data, struct wl_surface *surface, int i, send_move_event = 0; SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); - if (!SDL_WAYLAND_own_surface(surface)) { + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { return; } @@ -1138,9 +1128,7 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) wl_compositor_create_surface(c->compositor); wl_surface_add_listener(data->surface, &surface_listener, data); - if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { - wl_proxy_set_tag((struct wl_proxy *)data->surface, &SDL_WAYLAND_surface_tag); - } + SDL_WAYLAND_register_surface(data->surface); /* Fire a callback when the compositor wants a new frame rendered. * Right now this only matters for OpenGL; we use this callback to add a diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 35774bc73..90405fe20 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -114,8 +114,6 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); extern int Wayland_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation); -extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface); - #endif /* SDL_waylandwindow_h_ */ /* vi: set ts=4 sw=4 expandtab: */