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
This commit is contained in:
Jonas Ådahl 2020-02-13 19:41:42 +01:00 committed by Carlos Garnacho
parent 7f9fac2ba2
commit 9b97e5ed58
3 changed files with 57 additions and 37 deletions

View File

@ -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, &current_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, &current_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,

View File

@ -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)
{

View File

@ -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,