wayland: Tag/Check wl_output objects as well, fixes crashes when libdecor is in use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 7510714..0a5cf6e 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 64f4bda..f44706f 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 81d1607..daeb55f 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -42,16 +42,6 @@
#include <libdecor.h>
#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 35774bc..90405fe 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: */