From 6bb48b4fe9ea76b8f9a5db3acf8d9bb1b98c1481 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 18 Mar 2023 12:03:08 -0400
Subject: [PATCH] wayland: Unref the libdecor window when hiding
Hiding the decorations while not unreferencing the frame was a workaround for an internal libdecor use-after-free bug that was fixed some time ago. Revert to unreferencing the window when hiding to ensure that it is properly destroyed.
Reverts dd2e318
---
src/video/wayland/SDL_waylandwindow.c | 26 ++++++++++----------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index fe9580d4bf83..79a94456d410 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -1227,21 +1227,15 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
/* Create the shell surface and map the toplevel/popup */
#ifdef HAVE_LIBDECOR_H
if (data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
- if (data->shell_surface.libdecor.frame) {
- /* If the frame already exists, just set the visibility. */
- libdecor_frame_set_visibility(data->shell_surface.libdecor.frame, true);
- libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
+ data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor,
+ data->surface,
+ &libdecor_frame_interface,
+ data);
+ if (data->shell_surface.libdecor.frame == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!");
} else {
- data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor,
- data->surface,
- &libdecor_frame_interface,
- data);
- if (data->shell_surface.libdecor.frame == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!");
- } else {
- libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
- libdecor_frame_map(data->shell_surface.libdecor.frame);
- }
+ libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
+ libdecor_frame_map(data->shell_surface.libdecor.frame);
}
} else
#endif
@@ -1473,8 +1467,8 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
#ifdef HAVE_LIBDECOR_H
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
if (wind->shell_surface.libdecor.frame) {
- libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, false);
- libdecor_frame_set_app_id(wind->shell_surface.libdecor.frame, data->classname);
+ libdecor_frame_unref(wind->shell_surface.libdecor.frame);
+ wind->shell_surface.libdecor.frame = NULL;
}
} else
#endif