window: Keep windows with placement rule attached to parent
A window placed using a placement rule should keep that relative position even if the parent window moves, as the position tied to the parent window, not to the stage. Thus, if the parent window moves, the child window should move with it. In the implementation in this commit, the constraints engine is not used when repositioning the children; the window is simply positioned according to the effective placement rule that was derived from the initial constraining, as the a xdg_popup at the moment cannot move (relative its parent) after being mapped. Closes: https://gitlab.gnome.org/GNOME/mutter/issues/274
This commit is contained in:
parent
ca5b27baf5
commit
5376c31a33
@ -787,7 +787,7 @@ constrain_custom_rule (MetaWindow *window,
|
|||||||
MetaPlacementRule *placement_rule;
|
MetaPlacementRule *placement_rule;
|
||||||
MetaRectangle intersection;
|
MetaRectangle intersection;
|
||||||
gboolean constraint_satisfied;
|
gboolean constraint_satisfied;
|
||||||
MetaPlacementRule current_rule;
|
MetaPlacementRule *current_rule;
|
||||||
|
|
||||||
if (priority > PRIORITY_CUSTOM_RULE)
|
if (priority > PRIORITY_CUSTOM_RULE)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -796,6 +796,14 @@ constrain_custom_rule (MetaWindow *window,
|
|||||||
if (!placement_rule)
|
if (!placement_rule)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
if (window->constrained_placement_rule)
|
||||||
|
{
|
||||||
|
meta_window_process_placement (window,
|
||||||
|
window->constrained_placement_rule,
|
||||||
|
&info->current.x, &info->current.y);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
|
meta_rectangle_intersect (&info->current, &info->work_area_monitor,
|
||||||
&intersection);
|
&intersection);
|
||||||
|
|
||||||
@ -803,24 +811,28 @@ constrain_custom_rule (MetaWindow *window,
|
|||||||
placement_rule,
|
placement_rule,
|
||||||
&intersection);
|
&intersection);
|
||||||
|
|
||||||
if (constraint_satisfied || check_only)
|
if (check_only)
|
||||||
return constraint_satisfied;
|
return constraint_satisfied;
|
||||||
|
|
||||||
current_rule = *placement_rule;
|
current_rule = g_new0 (MetaPlacementRule, 1);
|
||||||
|
*current_rule = *placement_rule;
|
||||||
|
|
||||||
|
if (constraint_satisfied)
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (info->current.width != intersection.width &&
|
if (info->current.width != intersection.width &&
|
||||||
(current_rule.constraint_adjustment &
|
(current_rule->constraint_adjustment &
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X))
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X))
|
||||||
{
|
{
|
||||||
try_flip_window_position (window, info, ¤t_rule,
|
try_flip_window_position (window, info, current_rule,
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X,
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X,
|
||||||
&info->current, &intersection);
|
&info->current, &intersection);
|
||||||
}
|
}
|
||||||
if (info->current.height != intersection.height &&
|
if (info->current.height != intersection.height &&
|
||||||
(current_rule.constraint_adjustment &
|
(current_rule->constraint_adjustment &
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y))
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y))
|
||||||
{
|
{
|
||||||
try_flip_window_position (window, info, ¤t_rule,
|
try_flip_window_position (window, info, current_rule,
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y,
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y,
|
||||||
&info->current, &intersection);
|
&info->current, &intersection);
|
||||||
}
|
}
|
||||||
@ -832,9 +844,9 @@ constrain_custom_rule (MetaWindow *window,
|
|||||||
&intersection);
|
&intersection);
|
||||||
|
|
||||||
if (constraint_satisfied)
|
if (constraint_satisfied)
|
||||||
return TRUE;
|
goto done;
|
||||||
|
|
||||||
if (current_rule.constraint_adjustment &
|
if (current_rule->constraint_adjustment &
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X)
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X)
|
||||||
{
|
{
|
||||||
if (info->current.x != intersection.x)
|
if (info->current.x != intersection.x)
|
||||||
@ -842,7 +854,7 @@ constrain_custom_rule (MetaWindow *window,
|
|||||||
else if (info->current.width != intersection.width)
|
else if (info->current.width != intersection.width)
|
||||||
info->current.x -= info->current.width - intersection.width;
|
info->current.x -= info->current.width - intersection.width;
|
||||||
}
|
}
|
||||||
if (current_rule.constraint_adjustment &
|
if (current_rule->constraint_adjustment &
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y)
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y)
|
||||||
{
|
{
|
||||||
if (info->current.y != intersection.y)
|
if (info->current.y != intersection.y)
|
||||||
@ -858,21 +870,25 @@ constrain_custom_rule (MetaWindow *window,
|
|||||||
&intersection);
|
&intersection);
|
||||||
|
|
||||||
if (constraint_satisfied)
|
if (constraint_satisfied)
|
||||||
return TRUE;
|
goto done;
|
||||||
|
|
||||||
if (current_rule.constraint_adjustment &
|
if (current_rule->constraint_adjustment &
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X)
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X)
|
||||||
{
|
{
|
||||||
info->current.x = intersection.x;
|
info->current.x = intersection.x;
|
||||||
info->current.width = intersection.width;
|
info->current.width = intersection.width;
|
||||||
}
|
}
|
||||||
if (current_rule.constraint_adjustment &
|
if (current_rule->constraint_adjustment &
|
||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y)
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y)
|
||||||
{
|
{
|
||||||
info->current.y = intersection.y;
|
info->current.y = intersection.y;
|
||||||
info->current.height = intersection.height;
|
info->current.height = intersection.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
g_clear_pointer (&window->constrained_placement_rule, g_free);
|
||||||
|
window->constrained_placement_rule = current_rule;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +521,7 @@ struct _MetaWindow
|
|||||||
guint bypass_compositor;
|
guint bypass_compositor;
|
||||||
|
|
||||||
MetaPlacementRule *placement_rule;
|
MetaPlacementRule *placement_rule;
|
||||||
|
MetaPlacementRule *constrained_placement_rule;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaWindowClass
|
struct _MetaWindowClass
|
||||||
|
@ -313,6 +313,7 @@ meta_window_finalize (GObject *object)
|
|||||||
g_free (window->gtk_app_menu_object_path);
|
g_free (window->gtk_app_menu_object_path);
|
||||||
g_free (window->gtk_menubar_object_path);
|
g_free (window->gtk_menubar_object_path);
|
||||||
g_free (window->placement_rule);
|
g_free (window->placement_rule);
|
||||||
|
g_free (window->constrained_placement_rule);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -3752,13 +3753,23 @@ meta_window_updates_are_frozen (MetaWindow *window)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_window_reposition (MetaWindow *window)
|
||||||
|
{
|
||||||
|
meta_window_move_resize_internal (window,
|
||||||
|
(META_MOVE_RESIZE_MOVE_ACTION |
|
||||||
|
META_MOVE_RESIZE_RESIZE_ACTION),
|
||||||
|
NorthWestGravity,
|
||||||
|
window->rect);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
maybe_move_attached_dialog (MetaWindow *window,
|
maybe_move_attached_window (MetaWindow *window,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
if (meta_window_is_attached_dialog (window))
|
if (meta_window_is_attached_dialog (window) ||
|
||||||
/* It ignores x,y for such a dialog */
|
meta_window_get_placement_rule (window))
|
||||||
meta_window_move_frame (window, FALSE, 0, 0);
|
meta_window_reposition (window);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -4061,7 +4072,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
window->frame_bounds = NULL;
|
window->frame_bounds = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_foreach_transient (window, maybe_move_attached_dialog, NULL);
|
meta_window_foreach_transient (window, maybe_move_attached_window, NULL);
|
||||||
|
|
||||||
meta_stack_update_window_tile_matches (window->display->stack,
|
meta_stack_update_window_tile_matches (window->display->stack,
|
||||||
workspace_manager->active_workspace);
|
workspace_manager->active_workspace);
|
||||||
|
Loading…
Reference in New Issue
Block a user