[mutter] constraints: Try place popup on the same monitor as the anchor rect



commit 0205398d96b4d8b352b774fffeb9a812f5a18681
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Jan 20 11:36:17 2022 +0100

    constraints: Try place popup on the same monitor as the anchor rect
    
    When we'd place a popup, if the initially calculated position would be
    on another monitor than the anchor rect on the parent window, the
    later constrained position would end up on another monitor than the
    parent window. This could for example happen if a popup menu opening
    towards the right was opened very close to the screen edge of a right
    most monitor in a two side by side monitor setup.
    
    Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1783
    Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1768
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2252>

 src/core/constraints.c | 67 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 50 insertions(+), 17 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 4b1d95338a..f5729354f0 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -350,6 +350,7 @@ setup_constraint_info (ConstraintInfo      *info,
     meta_backend_get_monitor_manager (backend);
   MetaLogicalMonitor *logical_monitor;
   MetaWorkspace *cur_workspace;
+  MetaPlacementRule *placement_rule;
 
   info->orig    = *orig;
   info->current = *new;
@@ -405,9 +406,41 @@ setup_constraint_info (ConstraintInfo      *info,
   if (!info->is_user_action)
     info->fixed_directions = FIXED_DIRECTION_NONE;
 
-  logical_monitor =
-    meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
-                                                        &info->current);
+  placement_rule = meta_window_get_placement_rule (window);
+  if (placement_rule)
+    {
+      MetaRectangle rect;
+      MetaRectangle parent_rect;
+
+      rect = placement_rule->anchor_rect;
+
+      parent_rect = placement_rule->parent_rect;
+      rect.x += parent_rect.x;
+      rect.y += parent_rect.y;
+      logical_monitor =
+        meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
+                                                            &rect);
+      if (!logical_monitor)
+        {
+          logical_monitor =
+            meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
+                                                                &parent_rect);
+        }
+    }
+  else
+    {
+      logical_monitor =
+        meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
+                                                            &info->current);
+    }
+
+  if (!logical_monitor)
+    {
+      g_warning ("No sensible logical monitor could be used for constraining");
+      logical_monitor =
+        meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
+    }
+
   meta_window_get_work_area_for_logical_monitor (window,
                                                  logical_monitor,
                                                  &info->work_area_monitor);
@@ -527,23 +560,23 @@ place_window_if_needed(MetaWindow     *window,
         {
           meta_window_place (window, orig_rect.x, orig_rect.y,
                              &placed_rect.x, &placed_rect.y);
+
+          /* placing the window may have changed the monitor.  Find the
+           * new monitor and update the ConstraintInfo
+           */
+          logical_monitor =
+            meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
+                                                                &placed_rect);
+          info->entire_monitor = logical_monitor->rect;
+          meta_window_get_work_area_for_logical_monitor (window,
+                                                         logical_monitor,
+                                                         &info->work_area_monitor);
+          cur_workspace = window->display->workspace_manager->active_workspace;
+          info->usable_monitor_region =
+            meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
         }
       did_placement = TRUE;
 
-      /* placing the window may have changed the monitor.  Find the
-       * new monitor and update the ConstraintInfo
-       */
-      logical_monitor =
-        meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
-                                                            &placed_rect);
-      info->entire_monitor = logical_monitor->rect;
-      meta_window_get_work_area_for_logical_monitor (window,
-                                                     logical_monitor,
-                                                     &info->work_area_monitor);
-      cur_workspace = window->display->workspace_manager->active_workspace;
-      info->usable_monitor_region =
-        meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
-
       info->current.x = placed_rect.x;
       info->current.y = placed_rect.y;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]