wayland: Avoid spurious resize events
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
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 3eae22b..a4b5933 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 8ca090f..bce1d18 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);