summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2022-01-20 11:36:17 +0100
committerRobert Mader <robert.mader@collabora.com>2022-02-13 23:13:16 +0100
commit71c8002e1668c69aaf74e41c76607b0d65e56fa4 (patch)
tree553fdafdffc973a71fae062b76d7a9199b42cfa8
parent7ec93deeed025f42f61012db7af06e0cf204a457 (diff)
downloadmutter-71c8002e1668c69aaf74e41c76607b0d65e56fa4.tar.gz
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> (cherry picked from commit 0205398d96b4d8b352b774fffeb9a812f5a18681)
-rw-r--r--src/core/constraints.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 4b1d95338..f5729354f 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;