constraints: Pass constrained relative coordinates to window impl
A placement rule placed window positions itself relative to its parent, thus converting between relative coordinates to absolute coordinates, then back to relative coordinates implies unwanted restrictions for example when the absolute coordinate should not be calculated againts the current parent window position. Deal with this by keeping track of the relative position all the way from the constraining engine to the move-resize window implementation. https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
This commit is contained in:
parent
05e9d6ab9e
commit
ff381d1d52
6 changed files with 86 additions and 23 deletions
|
@ -123,6 +123,8 @@ typedef struct
|
|||
{
|
||||
MetaRectangle orig;
|
||||
MetaRectangle current;
|
||||
int rel_x;
|
||||
int rel_y;
|
||||
ActionType action_type;
|
||||
gboolean is_user_action;
|
||||
|
||||
|
@ -281,7 +283,9 @@ meta_window_constrain (MetaWindow *window,
|
|||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
MetaRectangle *new)
|
||||
MetaRectangle *new,
|
||||
int *rel_x,
|
||||
int *rel_y)
|
||||
{
|
||||
ConstraintInfo info;
|
||||
ConstraintPriority priority = PRIORITY_MINIMUM;
|
||||
|
@ -318,6 +322,8 @@ meta_window_constrain (MetaWindow *window,
|
|||
|
||||
/* Make sure we use the constrained position */
|
||||
*new = info.current;
|
||||
*rel_x = info.rel_x;
|
||||
*rel_y = info.rel_y;
|
||||
|
||||
/* We may need to update window->require_fully_onscreen,
|
||||
* window->require_on_single_monitor, and perhaps other quantities
|
||||
|
@ -342,6 +348,8 @@ setup_constraint_info (ConstraintInfo *info,
|
|||
|
||||
info->orig = *orig;
|
||||
info->current = *new;
|
||||
info->rel_x = 0;
|
||||
info->rel_y = 0;
|
||||
|
||||
if (info->current.width < 1)
|
||||
info->current.width = 1;
|
||||
|
@ -494,15 +502,14 @@ place_window_if_needed(MetaWindow *window,
|
|||
{
|
||||
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);
|
||||
&info->rel_x, &info->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;
|
||||
placed_rect.x = parent_rect.x + info->rel_x;
|
||||
placed_rect.y = parent_rect.y + info->rel_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -745,6 +752,8 @@ try_flip_window_position (MetaWindow *window,
|
|||
int parent_x,
|
||||
int parent_y,
|
||||
MetaRectangle *rect,
|
||||
int *rel_x,
|
||||
int *rel_y,
|
||||
MetaRectangle *intersection)
|
||||
{
|
||||
MetaPlacementRule flipped_rule = *placement_rule;;
|
||||
|
@ -781,6 +790,8 @@ try_flip_window_position (MetaWindow *window,
|
|||
{
|
||||
*placement_rule = flipped_rule;
|
||||
*rect = flipped_rect;
|
||||
*rel_x = flipped_rel_x;
|
||||
*rel_y = flipped_rel_y;
|
||||
*intersection = flipped_intersection;
|
||||
}
|
||||
}
|
||||
|
@ -815,6 +826,8 @@ constrain_custom_rule (MetaWindow *window,
|
|||
MetaRectangle intersection;
|
||||
gboolean constraint_satisfied;
|
||||
MetaRectangle adjusted_unconstrained;
|
||||
int adjusted_rel_x;
|
||||
int adjusted_rel_y;
|
||||
MetaPlacementRule current_rule;
|
||||
MetaWindow *parent;
|
||||
MetaRectangle parent_rect;
|
||||
|
@ -834,12 +847,16 @@ constrain_custom_rule (MetaWindow *window,
|
|||
switch (window->placement.state)
|
||||
{
|
||||
case META_PLACEMENT_STATE_UNCONSTRAINED:
|
||||
adjusted_rel_x = window->rect.x - parent->rect.x;
|
||||
adjusted_rel_y = window->rect.y - parent->rect.y;
|
||||
break;
|
||||
case META_PLACEMENT_STATE_CONSTRAINED:
|
||||
adjusted_unconstrained.x =
|
||||
parent->rect.x + window->placement.current.rel_x;
|
||||
adjusted_unconstrained.y =
|
||||
parent->rect.y + window->placement.current.rel_y;
|
||||
adjusted_rel_x = window->placement.current.rel_x;
|
||||
adjusted_rel_y = window->placement.current.rel_y;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -861,6 +878,8 @@ constrain_custom_rule (MetaWindow *window,
|
|||
{
|
||||
case META_PLACEMENT_STATE_CONSTRAINED:
|
||||
info->current = adjusted_unconstrained;
|
||||
info->rel_x = adjusted_rel_x;
|
||||
info->rel_y = adjusted_rel_y;
|
||||
goto done;
|
||||
case META_PLACEMENT_STATE_UNCONSTRAINED:
|
||||
break;
|
||||
|
@ -878,6 +897,8 @@ constrain_custom_rule (MetaWindow *window,
|
|||
parent_rect.x,
|
||||
parent_rect.y,
|
||||
&info->current,
|
||||
&info->rel_x,
|
||||
&info->rel_y,
|
||||
&intersection);
|
||||
}
|
||||
if (info->current.height != intersection.height &&
|
||||
|
@ -889,6 +910,8 @@ constrain_custom_rule (MetaWindow *window,
|
|||
parent_rect.x,
|
||||
parent_rect.y,
|
||||
&info->current,
|
||||
&info->rel_x,
|
||||
&info->rel_y,
|
||||
&intersection);
|
||||
}
|
||||
|
||||
|
@ -906,6 +929,7 @@ constrain_custom_rule (MetaWindow *window,
|
|||
{
|
||||
int current_x2;
|
||||
int work_area_monitor_x2;
|
||||
int new_x;
|
||||
|
||||
current_x2 = info->current.x + info->current.width;
|
||||
work_area_monitor_x2 = (info->work_area_monitor.x +
|
||||
|
@ -913,19 +937,27 @@ constrain_custom_rule (MetaWindow *window,
|
|||
|
||||
if (current_x2 > work_area_monitor_x2)
|
||||
{
|
||||
info->current.x = MAX (info->work_area_monitor.x,
|
||||
work_area_monitor_x2 - info->current.width);
|
||||
new_x = MAX (info->work_area_monitor.x,
|
||||
work_area_monitor_x2 - info->current.width);
|
||||
}
|
||||
else if (info->current.x < info->work_area_monitor.x)
|
||||
{
|
||||
info->current.x = info->work_area_monitor.x;
|
||||
new_x = info->work_area_monitor.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_x = info->current.x;
|
||||
}
|
||||
|
||||
info->rel_x += new_x - info->current.x;
|
||||
info->current.x = new_x;
|
||||
}
|
||||
if (current_rule.constraint_adjustment &
|
||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y)
|
||||
{
|
||||
int current_y2;
|
||||
int work_area_monitor_y2;
|
||||
int new_y;
|
||||
|
||||
current_y2 = info->current.y + info->current.height;
|
||||
work_area_monitor_y2 = (info->work_area_monitor.y +
|
||||
|
@ -933,13 +965,20 @@ constrain_custom_rule (MetaWindow *window,
|
|||
|
||||
if (current_y2 > work_area_monitor_y2)
|
||||
{
|
||||
info->current.y = MAX (info->work_area_monitor.y,
|
||||
work_area_monitor_y2 - info->current.height);
|
||||
new_y = MAX (info->work_area_monitor.y,
|
||||
work_area_monitor_y2 - info->current.height);
|
||||
}
|
||||
else if (info->current.y < info->work_area_monitor.y)
|
||||
{
|
||||
info->current.y = info->work_area_monitor.y;
|
||||
new_y = info->work_area_monitor.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_y = info->current.y;
|
||||
}
|
||||
|
||||
info->rel_y += new_y - info->current.y;
|
||||
info->current.y = new_y;
|
||||
}
|
||||
|
||||
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
|
||||
|
@ -954,21 +993,27 @@ constrain_custom_rule (MetaWindow *window,
|
|||
if (current_rule.constraint_adjustment &
|
||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X)
|
||||
{
|
||||
info->current.x = intersection.x;
|
||||
int new_x;
|
||||
new_x = intersection.x;
|
||||
info->current.width = intersection.width;
|
||||
info->rel_x += new_x - info->current.x;
|
||||
info->current.x = new_x;
|
||||
}
|
||||
if (current_rule.constraint_adjustment &
|
||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y)
|
||||
{
|
||||
info->current.y = intersection.y;
|
||||
int new_y;
|
||||
new_y = intersection.y;
|
||||
info->current.height = intersection.height;
|
||||
info->rel_y += new_y - info->current.y;
|
||||
info->current.y = new_y;
|
||||
}
|
||||
|
||||
done:
|
||||
window->placement.state = META_PLACEMENT_STATE_CONSTRAINED;
|
||||
|
||||
window->placement.current.rel_x = info->current.x - parent_rect.x;
|
||||
window->placement.current.rel_y = info->current.y - parent_rect.y;
|
||||
window->placement.current.rel_x = info->rel_x;
|
||||
window->placement.current.rel_y = info->rel_y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ void meta_window_constrain (MetaWindow *window,
|
|||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
MetaRectangle *new);
|
||||
MetaRectangle *new,
|
||||
int *rel_x,
|
||||
int *rel_y);
|
||||
|
||||
#endif /* META_CONSTRAINTS_H */
|
||||
|
|
|
@ -569,6 +569,8 @@ struct _MetaWindowClass
|
|||
int gravity,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
int rel_x,
|
||||
int rel_y,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result);
|
||||
gboolean (*update_struts) (MetaWindow *window);
|
||||
|
|
|
@ -4001,6 +4001,8 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||
gboolean did_placement;
|
||||
MetaRectangle unconstrained_rect;
|
||||
MetaRectangle constrained_rect;
|
||||
int rel_x = 0;
|
||||
int rel_y = 0;
|
||||
MetaMoveResizeResultFlags result = 0;
|
||||
gboolean moved_or_resized = FALSE;
|
||||
MetaWindowUpdateMonitorFlags update_monitor_flags;
|
||||
|
@ -4066,7 +4068,14 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||
flags,
|
||||
gravity,
|
||||
&old_rect,
|
||||
&constrained_rect);
|
||||
&constrained_rect,
|
||||
&rel_x,
|
||||
&rel_y);
|
||||
}
|
||||
else if (window->placement.rule)
|
||||
{
|
||||
rel_x = window->placement.current.rel_x;
|
||||
rel_y = window->placement.current.rel_y;
|
||||
}
|
||||
|
||||
/* If we did placement, then we need to save the position that the window
|
||||
|
@ -4080,7 +4089,13 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||
}
|
||||
|
||||
/* Do the protocol-specific move/resize logic */
|
||||
META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, unconstrained_rect, constrained_rect, flags, &result);
|
||||
META_WINDOW_GET_CLASS (window)->move_resize_internal (window,
|
||||
gravity,
|
||||
unconstrained_rect,
|
||||
constrained_rect,
|
||||
rel_x,
|
||||
rel_y,
|
||||
flags, &result);
|
||||
|
||||
if (result & META_MOVE_RESIZE_RESULT_MOVED)
|
||||
{
|
||||
|
|
|
@ -220,6 +220,8 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
|||
int gravity,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
int rel_x,
|
||||
int rel_y,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result)
|
||||
{
|
||||
|
@ -326,11 +328,6 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
|||
|
||||
if (window->placement.rule)
|
||||
{
|
||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||
int rel_x, rel_y;
|
||||
|
||||
rel_x = configured_x - parent->rect.x;
|
||||
rel_y = configured_y - parent->rect.y;
|
||||
configuration =
|
||||
meta_wayland_window_configuration_new_relative (rel_x,
|
||||
rel_y,
|
||||
|
|
|
@ -1308,6 +1308,8 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
|||
int gravity,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
int rel_x,
|
||||
int rel_y,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue