constraints: Only readjust placement constraint when not checking

When check_only is TRUE, the constraint should not be applied, just
checked. We failed to comply here when a placed transient window was
to be moved together with its parent, updating the window position
directly even if check_only was TRUE.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/496
This commit is contained in:
Jonas Ådahl 2018-10-19 13:57:10 +02:00 committed by Florian Müllner
parent f580b28a27
commit 23f31e518e

View File

@ -779,7 +779,7 @@ try_flip_window_position (MetaWindow *window,
} }
static gboolean static gboolean
is_custom_rule_satisfied (ConstraintInfo *info, is_custom_rule_satisfied (MetaRectangle *rect,
MetaPlacementRule *placement_rule, MetaPlacementRule *placement_rule,
MetaRectangle *intersection) MetaRectangle *intersection)
{ {
@ -790,9 +790,9 @@ is_custom_rule_satisfied (ConstraintInfo *info,
y_constrain_actions = (META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y | y_constrain_actions = (META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y |
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y); META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y);
if ((placement_rule->constraint_adjustment & x_constrain_actions && if ((placement_rule->constraint_adjustment & x_constrain_actions &&
info->current.width != intersection->width) || rect->width != intersection->width) ||
(placement_rule->constraint_adjustment & y_constrain_actions && (placement_rule->constraint_adjustment & y_constrain_actions &&
info->current.height != intersection->height)) rect->height != intersection->height))
return FALSE; return FALSE;
else else
return TRUE; return TRUE;
@ -807,6 +807,7 @@ constrain_custom_rule (MetaWindow *window,
MetaPlacementRule *placement_rule; MetaPlacementRule *placement_rule;
MetaRectangle intersection; MetaRectangle intersection;
gboolean constraint_satisfied; gboolean constraint_satisfied;
MetaRectangle adjusted_unconstrained;
MetaPlacementRule current_rule; MetaPlacementRule current_rule;
MetaWindow *parent; MetaWindow *parent;
MetaRectangle parent_rect; MetaRectangle parent_rect;
@ -818,24 +819,46 @@ constrain_custom_rule (MetaWindow *window,
if (!placement_rule) if (!placement_rule)
return TRUE; return TRUE;
adjusted_unconstrained = info->current;
switch (window->placement_state) switch (window->placement_state)
{ {
case META_PLACEMENT_STATE_UNCONSTRAINED: case META_PLACEMENT_STATE_UNCONSTRAINED:
break; break;
case META_PLACEMENT_STATE_CONSTRAINED:
parent = meta_window_get_transient_for (window);
meta_window_get_frame_rect (parent, &parent_rect);
adjusted_unconstrained.x =
parent_rect.x + window->constrained_placement_rule_offset_x;
adjusted_unconstrained.y =
parent_rect.y + window->constrained_placement_rule_offset_y;
break;
}
meta_rectangle_intersect (&adjusted_unconstrained, &info->work_area_monitor,
&intersection);
constraint_satisfied = (meta_rectangle_equal (&info->current,
&adjusted_unconstrained) &&
is_custom_rule_satisfied (&adjusted_unconstrained,
placement_rule,
&intersection));
if (check_only)
return constraint_satisfied;
current_rule = *placement_rule;
switch (window->placement_state)
{
case META_PLACEMENT_STATE_CONSTRAINED: case META_PLACEMENT_STATE_CONSTRAINED:
{ {
MetaRectangle parent_buffer_rect; MetaRectangle parent_buffer_rect;
parent = meta_window_get_transient_for (window);
meta_window_get_frame_rect (parent, &parent_rect);
info->current.x =
parent_rect.x + window->constrained_placement_rule_offset_x;
info->current.y =
parent_rect.y + window->constrained_placement_rule_offset_y;
meta_window_get_buffer_rect (parent, &parent_buffer_rect); meta_window_get_buffer_rect (parent, &parent_buffer_rect);
if (!meta_rectangle_overlap (&info->current, &parent_buffer_rect) && if (!meta_rectangle_overlap (&adjusted_unconstrained,
!meta_rectangle_is_adjacent_to (&info->current, &parent_buffer_rect) &&
!meta_rectangle_is_adjacent_to (&adjusted_unconstrained,
&parent_buffer_rect)) &parent_buffer_rect))
{ {
g_warning ("Buggy client caused popup to be placed outside of " g_warning ("Buggy client caused popup to be placed outside of "
@ -843,23 +866,17 @@ constrain_custom_rule (MetaWindow *window,
info->should_unmanage = TRUE; info->should_unmanage = TRUE;
return TRUE; return TRUE;
} }
else
return TRUE; {
info->current = adjusted_unconstrained;
goto done;
}
break;
} }
case META_PLACEMENT_STATE_UNCONSTRAINED:
break;
} }
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
&intersection);
constraint_satisfied = is_custom_rule_satisfied (info,
placement_rule,
&intersection);
if (check_only)
return constraint_satisfied;
current_rule = *placement_rule;
if (constraint_satisfied) if (constraint_satisfied)
goto done; goto done;
@ -882,7 +899,7 @@ constrain_custom_rule (MetaWindow *window,
meta_rectangle_intersect (&info->current, &info->work_area_monitor, meta_rectangle_intersect (&info->current, &info->work_area_monitor,
&intersection); &intersection);
constraint_satisfied = is_custom_rule_satisfied (info, constraint_satisfied = is_custom_rule_satisfied (&info->current,
placement_rule, placement_rule,
&intersection); &intersection);
@ -908,7 +925,7 @@ constrain_custom_rule (MetaWindow *window,
meta_rectangle_intersect (&info->current, &info->work_area_monitor, meta_rectangle_intersect (&info->current, &info->work_area_monitor,
&intersection); &intersection);
constraint_satisfied = is_custom_rule_satisfied (info, constraint_satisfied = is_custom_rule_satisfied (&info->current,
placement_rule, placement_rule,
&intersection); &intersection);