Browse Source

wayland: Fix the corner case when positioning popups

If the popup is positioned such that it requires correction on both the x and y axes, it will be aligned with parent only at the window corners, which is neither overlapping nor adjacent. In this case, nudge the window plus or minus one screen unit on the x axis so it is properly adjacent to the parent and within spec guidelines.
Frank Praznik 1 year ago
parent
commit
b92eaddbbd
1 changed files with 16 additions and 2 deletions
  1. 16 2
      src/video/wayland/SDL_waylandwindow.c

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

@@ -303,6 +303,8 @@ static void ConfigureWindowGeometry(SDL_Window *window)
 
 static void EnsurePopupPositionIsValid(SDL_Window *window)
 {
+    int adj_count = 0;
+
     /* Per the xdg-positioner spec, child popup windows must intersect or at
      * least be partially adjacent to the parent window.
      *
@@ -312,15 +314,27 @@ static void EnsurePopupPositionIsValid(SDL_Window *window)
      */
     if (window->x + window->w < 0) {
         window->x = -window->w;
+        ++adj_count;
     }
     if (window->y + window->h < 0) {
         window->y = -window->h;
+        ++adj_count;
     }
     if (window->x > window->parent->w) {
-        window->x = window->parent->w - 1;
+        window->x = window->parent->w;
+        ++adj_count;
     }
     if (window->y > window->parent->h) {
-        window->y = window->parent->h - 1;
+        window->y = window->parent->h;
+        ++adj_count;
+    }
+
+    /* If adjustment was required on the x and y axes, the popup is aligned with
+     * the parent corner-to-corner and is neither overlapping nor adjacent, so it
+     * must be nudged by 1 to be considered adjacent.
+     */
+    if (adj_count > 1) {
+        window->x += window->x < 0 ? 1 : -1;
     }
 }