From 9b97e5ed583566d6e0a2a14acb18d2eb5c8d3ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 13 Feb 2020 19:41:42 +0100 Subject: [PATCH] place: Make placement rule processing provide relative coordinates A placement rule is always about placing a window relative to its parent. In order to eventually place it against predicted future parent positions, make the placement rule processing output relative coordinates, having the caller deal with turning them into absolute. https://gitlab.gnome.org/GNOME/mutter/merge_requests/705 --- src/core/constraints.c | 39 +++++++++++++++++++++++++++----- src/core/place.c | 51 +++++++++++++++++------------------------- src/core/place.h | 4 ++-- 3 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index 89e70f3a8..a66fe6e20 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -490,8 +490,25 @@ place_window_if_needed(MetaWindow *window, orig_rect = info->orig; - meta_window_place (window, orig_rect.x, orig_rect.y, - &placed_rect.x, &placed_rect.y); + if (window->placement_rule) + { + MetaWindow *parent = meta_window_get_transient_for (window); + MetaRectangle parent_rect; + int rel_x, rel_y; + + meta_window_process_placement (window, + window->placement_rule, + &rel_x, &rel_y); + meta_window_get_frame_rect (parent, &parent_rect); + + placed_rect.x = parent_rect.x + rel_x; + placed_rect.y = parent_rect.y + rel_y; + } + else + { + meta_window_place (window, orig_rect.x, orig_rect.y, + &placed_rect.x, &placed_rect.y); + } did_placement = TRUE; /* placing the window may have changed the monitor. Find the @@ -725,12 +742,16 @@ try_flip_window_position (MetaWindow *window, ConstraintInfo *info, MetaPlacementRule *placement_rule, MetaPlacementConstraintAdjustment constraint_adjustment, + int parent_x, + int parent_y, MetaRectangle *rect, MetaRectangle *intersection) { MetaPlacementRule flipped_rule = *placement_rule;; MetaRectangle flipped_rect; MetaRectangle flipped_intersection; + int flipped_rel_x; + int flipped_rel_y; switch (constraint_adjustment) { @@ -747,7 +768,9 @@ try_flip_window_position (MetaWindow *window, flipped_rect = info->current; meta_window_process_placement (window, &flipped_rule, - &flipped_rect.x, &flipped_rect.y); + &flipped_rel_x, &flipped_rel_y); + flipped_rect.x = parent_x + flipped_rel_x; + flipped_rect.y = parent_y + flipped_rel_y; meta_rectangle_intersect (&flipped_rect, &info->work_area_monitor, &flipped_intersection); @@ -852,7 +875,10 @@ constrain_custom_rule (MetaWindow *window, { try_flip_window_position (window, info, ¤t_rule, META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X, - &info->current, &intersection); + parent_rect.x, + parent_rect.y, + &info->current, + &intersection); } if (info->current.height != intersection.height && (current_rule.constraint_adjustment & @@ -860,7 +886,10 @@ constrain_custom_rule (MetaWindow *window, { try_flip_window_position (window, info, ¤t_rule, META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y, - &info->current, &intersection); + parent_rect.x, + parent_rect.y, + &info->current, + &intersection); } meta_rectangle_intersect (&info->current, &info->work_area_monitor, diff --git a/src/core/place.c b/src/core/place.c index 7b4a6a7b3..6d0a159a3 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -610,53 +610,52 @@ find_first_fit (MetaWindow *window, void meta_window_process_placement (MetaWindow *window, MetaPlacementRule *placement_rule, - int *x, - int *y) + int *rel_x, + int *rel_y) { - MetaWindow *parent = meta_window_get_transient_for (window); - MetaRectangle parent_rect; MetaRectangle anchor_rect; int window_width, window_height; + int x, y; window_width = placement_rule->width; window_height = placement_rule->height; - meta_window_get_frame_rect (parent, &parent_rect); anchor_rect = placement_rule->anchor_rect; - anchor_rect.x += parent_rect.x; - anchor_rect.y += parent_rect.y; /* Place at anchor point. */ if (placement_rule->anchor & META_PLACEMENT_ANCHOR_LEFT) - *x = anchor_rect.x; + x = anchor_rect.x; else if (placement_rule->anchor & META_PLACEMENT_ANCHOR_RIGHT) - *x = anchor_rect.x + anchor_rect.width; + x = anchor_rect.x + anchor_rect.width; else - *x = anchor_rect.x + (anchor_rect.width / 2); + x = anchor_rect.x + (anchor_rect.width / 2); if (placement_rule->anchor & META_PLACEMENT_ANCHOR_TOP) - *y = anchor_rect.y; + y = anchor_rect.y; else if (placement_rule->anchor & META_PLACEMENT_ANCHOR_BOTTOM) - *y = anchor_rect.y + anchor_rect.height; + y = anchor_rect.y + anchor_rect.height; else - *y = anchor_rect.y + (anchor_rect.height / 2); + y = anchor_rect.y + (anchor_rect.height / 2); /* Shift according to gravity. */ if (placement_rule->gravity & META_PLACEMENT_GRAVITY_LEFT) - *x -= window_width; + x -= window_width; else if (placement_rule->gravity & META_PLACEMENT_GRAVITY_RIGHT) - *x = *x; + x = x; else - *x -= window_width / 2; + x -= window_width / 2; if (placement_rule->gravity & META_PLACEMENT_GRAVITY_TOP) - *y -= window_height; + y -= window_height; else if (placement_rule->gravity & META_PLACEMENT_GRAVITY_BOTTOM) - *y = *y; + y = y; else - *y -= window_height / 2; + y -= window_height / 2; /* Offset according to offset. */ - *x += placement_rule->offset_x; - *y += placement_rule->offset_y; + x += placement_rule->offset_x; + y += placement_rule->offset_y; + + *rel_x = x; + *rel_y = y; } void @@ -672,15 +671,7 @@ meta_window_place (MetaWindow *window, meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); - /* If the window has a custom placement rule, always run only that. */ - if (window->placement_rule) - { - meta_window_process_placement (window, - window->placement_rule, - &x, &y); - - goto done; - } + g_return_if_fail (!window->placement_rule); switch (window->type) { diff --git a/src/core/place.h b/src/core/place.h index 2c0fe8298..2e2c81141 100644 --- a/src/core/place.h +++ b/src/core/place.h @@ -27,8 +27,8 @@ void meta_window_process_placement (MetaWindow *window, MetaPlacementRule *placement_rule, - int *x, - int *y); + int *rel_x, + int *rel_y); void meta_window_place (MetaWindow *window, int x,