Forráskód Böngészése

video: Prefer the window manager supplied coordinates for selecting a fullscreen display

Unless there are pending client requested window coordinates, such as in the case where the position is set followed by immediately by entering fullscreen, prefer the true window coordinates as sent by the window manager to select a fullscreen display.

Fixes the case where, if the window manager moves an already maximized window to another display, the window would be made fullscreen on the wrong display since the last floating coordinates would be used.
Frank Praznik 4 hónapja
szülő
commit
5447cb6d38

+ 1 - 0
src/events/SDL_windowevents.c

@@ -69,6 +69,7 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
     case SDL_EVENT_WINDOW_MOVED:
         window->undefined_x = false;
         window->undefined_y = false;
+        window->use_pending_position_for_fullscreen = false;
         if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
             window->windowed.x = data1;
             window->windowed.y = data2;

+ 1 - 1
src/video/SDL_sysvideo.h

@@ -96,9 +96,9 @@ struct SDL_Window
     SDL_Surface *surface;
     bool surface_valid;
 
-    bool is_repositioning; // Set during an SDL_SetWindowPosition() call.
     bool is_hiding;
     bool restore_on_show; // Child was hidden recursively by the parent, restore when shown.
+    bool use_pending_position_for_fullscreen;
     bool is_destroying;
     bool is_dropping; // drag/drop in progress, expecting SDL_SendDropComplete().
 

+ 12 - 12
src/video/SDL_video.c

@@ -1660,20 +1660,21 @@ SDL_VideoDisplay *SDL_GetVideoDisplayForFullscreenWindow(SDL_Window *window)
         displayID = window->current_fullscreen_mode.displayID;
     }
 
-    /* The floating position is used here as a very common pattern is
-     * SDL_SetWindowPosition() followed by SDL_SetWindowFullscreen() to make the
-     * window fullscreen desktop on a specific display. If the backend doesn't
-     * support changing the window position, or the compositor hasn't yet actually
-     * moved the window, the current position won't be updated at the time of the
-     * fullscreen call.
+    /* This is used to handle the very common pattern of SDL_SetWindowPosition()
+     * followed immediately by SDL_SetWindowFullscreen() to make the window fullscreen
+     * desktop on a specific display. If the backend doesn't support changing the
+     * window position, or an async window manager hasn't yet actually moved the window,
+     * the current position won't be updated at the time of the fullscreen call.
      */
     if (!displayID) {
-        if (window->flags & SDL_WINDOW_FULLSCREEN && !window->is_repositioning) {
-            // This was a window manager initiated move, use the current position.
-            displayID = GetDisplayForRect(window->x, window->y, 1, 1);
-        } else {
+        if (window->use_pending_position_for_fullscreen) {
+            // The last coordinates were client requested; use the pending floating coordinates.
             displayID = GetDisplayForRect(window->floating.x, window->floating.y, window->floating.w, window->floating.h);
         }
+        else {
+            // The last coordinates were from the window manager; use the current position.
+            displayID = GetDisplayForRect(window->x, window->y, 1, 1);
+        }
     }
     if (!displayID) {
         // Use the primary display for a window if we can't find it anywhere else
@@ -2806,11 +2807,10 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
     window->floating.y = y;
     window->undefined_x = false;
     window->undefined_y = false;
+    window->use_pending_position_for_fullscreen = true;
 
     if (_this->SetWindowPosition) {
-        window->is_repositioning = true;
         const bool result = _this->SetWindowPosition(_this, window);
-        window->is_repositioning = false;
         if (result) {
             SDL_SyncIfRequired(window);
         }

+ 2 - 0
src/video/wayland/SDL_waylandwindow.c

@@ -2651,6 +2651,7 @@ bool Wayland_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
         RepositionPopup(window, false);
         return true;
     } else if (wind->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR || wind->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_XDG_TOPLEVEL) {
+        const bool use_pending_position_for_fullscreen = window->use_pending_position_for_fullscreen;
         const int x = window->floating.x;
         const int y = window->floating.y;
 
@@ -2671,6 +2672,7 @@ bool Wayland_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
          *
          * for positioning a desktop fullscreen window won't work without this.
          */
+        window->use_pending_position_for_fullscreen = use_pending_position_for_fullscreen;
         window->floating.x = x;
         window->floating.y = y;
 

+ 10 - 0
src/video/x11/SDL_x11window.c

@@ -1060,7 +1060,17 @@ bool X11_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
 {
     // Sync any pending fullscreen or maximize events.
     if (window->internal->pending_operation & (X11_PENDING_OP_FULLSCREEN | X11_PENDING_OP_MAXIMIZE)) {
+        // Save state in case it is overwritten while synchronizing.
+        const bool use_client_fs_coords = window->use_pending_position_for_fullscreen;
+        const int x = window->floating.x;
+        const int y = window->floating.y;
+
         X11_SyncWindow(_this, window);
+
+        // Restore state that may have been overwritten while synchronizing.
+        window->use_pending_position_for_fullscreen = use_client_fs_coords;
+        window->floating.x = x;
+        window->floating.y = y;
     }
 
     // Position will be set when window is de-maximized