From d3952a8a2c8a32d4f6f521402427052a4b756f9f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Jan 2022 15:14:33 -0600 Subject: [PATCH 02/11] wayland: Avoid spurious resize events --- src/video/wayland/SDL_waylandwindow.c | 42 +++++++++++++++++---------- src/video/wayland/SDL_waylandwindow.h | 1 + 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 3eae22bf7..a4b5933eb 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -224,14 +224,16 @@ handle_configure_xdg_toplevel(void *data, * us a completely stateless, sizeless configure, with which we have * to enforce our own state anyway. */ - if (width != 0 && height != 0) { + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { window->w = width; window->h = height; + wind->needs_resize_event = SDL_TRUE; } /* This part is good though. */ - if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) { wind->scale_factor = driverdata->scale_factor; + wind->needs_resize_event = SDL_TRUE; } return; @@ -284,8 +286,11 @@ handle_configure_xdg_toplevel(void *data, } /* Store this now so the xdg_surface configure knows what to resize to */ - window->w = width; - window->h = height; + if (window->w != width || window->h != height) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } } else { /* For fullscreen, foolishly do what the compositor says. If it's wrong, * don't blame us, we were explicitly instructed to do this. @@ -293,14 +298,16 @@ handle_configure_xdg_toplevel(void *data, * UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug: * https://bugs.kde.org/show_bug.cgi?id=444962 */ - if (width != 0 && height != 0) { + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { window->w = width; window->h = height; + wind->needs_resize_event = SDL_TRUE; } /* This part is good though. */ - if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) { wind->scale_factor = driverdata->scale_factor; + wind->needs_resize_event = SDL_TRUE; } } } @@ -330,6 +337,7 @@ decoration_frame_configure(struct libdecor_frame *frame, enum libdecor_window_state window_state; int width, height; + float scale_factor = wind->scale_factor; SDL_bool focused = SDL_FALSE; SDL_bool fullscreen = SDL_FALSE; @@ -399,7 +407,7 @@ decoration_frame_configure(struct libdecor_frame *frame, /* This part is good though. */ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { - wind->scale_factor = driverdata->scale_factor; + scale_factor = driverdata->scale_factor; } } else if (!(window->flags & SDL_WINDOW_RESIZABLE)) { width = window->windowed.w; @@ -427,7 +435,7 @@ decoration_frame_configure(struct libdecor_frame *frame, } /* Do the resize on the SDL side (this will set window->w/h)... */ - Wayland_HandleResize(window, width, height, wind->scale_factor); + Wayland_HandleResize(window, width, height, scale_factor); wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE; /* ... then commit the changes on the libdecor side. */ @@ -1341,14 +1349,18 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; SDL_VideoData *viddata = data->waylandData; - struct wl_region *region; - window->w = 0; - window->h = 0; - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height); - window->w = width; - window->h = height; - data->scale_factor = scale; + + if (data->needs_resize_event || window->w != width || window->h != height || data->scale_factor != scale) { + /* We may have already updated window w/h (or only adjusted scale factor), + * so we must override the deduplication logic in the video core */ + window->w = 0; + window->h = 0; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height); + window->w = width; + window->h = height; + data->needs_resize_event = SDL_FALSE; + } wl_surface_set_buffer_scale(data->surface, data->scale_factor); diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 8ca090f0c..bce1d1855 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -84,6 +84,7 @@ typedef struct { int num_outputs; float scale_factor; + SDL_bool needs_resize_event; } SDL_WindowData; extern void Wayland_ShowWindow(_THIS, SDL_Window *window); -- 2.34.1