[mutter] window: Keep windows with placement rule attached to parent
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] window: Keep windows with placement rule attached to parent
- Date: Mon, 27 Aug 2018 12:31:31 +0000 (UTC)
commit 5376c31a33020d7dc5a69b129f2dd4f42d0890a1
Author: Jonas Ådahl <jadahl gmail com>
Date: Wed Aug 22 21:54:16 2018 +0200
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
src/core/constraints.c | 42 +++++++++++++++++++++++++++++-------------
src/core/window-private.h | 1 +
src/core/window.c | 21 ++++++++++++++++-----
3 files changed, 46 insertions(+), 18 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 73b4b96ea..82e19ee29 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -787,7 +787,7 @@ constrain_custom_rule (MetaWindow *window,
MetaPlacementRule *placement_rule;
MetaRectangle intersection;
gboolean constraint_satisfied;
- MetaPlacementRule current_rule;
+ MetaPlacementRule *current_rule;
if (priority > PRIORITY_CUSTOM_RULE)
return TRUE;
@@ -796,6 +796,14 @@ constrain_custom_rule (MetaWindow *window,
if (!placement_rule)
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,
&intersection);
@@ -803,24 +811,28 @@ constrain_custom_rule (MetaWindow *window,
placement_rule,
&intersection);
- if (constraint_satisfied || check_only)
+ if (check_only)
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 &&
- (current_rule.constraint_adjustment &
+ (current_rule->constraint_adjustment &
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,
&info->current, &intersection);
}
if (info->current.height != intersection.height &&
- (current_rule.constraint_adjustment &
+ (current_rule->constraint_adjustment &
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,
&info->current, &intersection);
}
@@ -832,9 +844,9 @@ constrain_custom_rule (MetaWindow *window,
&intersection);
if (constraint_satisfied)
- return TRUE;
+ goto done;
- if (current_rule.constraint_adjustment &
+ if (current_rule->constraint_adjustment &
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X)
{
if (info->current.x != intersection.x)
@@ -842,7 +854,7 @@ constrain_custom_rule (MetaWindow *window,
else if (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)
{
if (info->current.y != intersection.y)
@@ -858,21 +870,25 @@ constrain_custom_rule (MetaWindow *window,
&intersection);
if (constraint_satisfied)
- return TRUE;
+ goto done;
- if (current_rule.constraint_adjustment &
+ if (current_rule->constraint_adjustment &
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X)
{
info->current.x = intersection.x;
info->current.width = intersection.width;
}
- if (current_rule.constraint_adjustment &
+ if (current_rule->constraint_adjustment &
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y)
{
info->current.y = intersection.y;
info->current.height = intersection.height;
}
+done:
+ g_clear_pointer (&window->constrained_placement_rule, g_free);
+ window->constrained_placement_rule = current_rule;
+
return TRUE;
}
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 76c454417..c47de087a 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -521,6 +521,7 @@ struct _MetaWindow
guint bypass_compositor;
MetaPlacementRule *placement_rule;
+ MetaPlacementRule *constrained_placement_rule;
};
struct _MetaWindowClass
diff --git a/src/core/window.c b/src/core/window.c
index f8b0e0128..c06f52c86 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -313,6 +313,7 @@ meta_window_finalize (GObject *object)
g_free (window->gtk_app_menu_object_path);
g_free (window->gtk_menubar_object_path);
g_free (window->placement_rule);
+ g_free (window->constrained_placement_rule);
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
}
@@ -3752,13 +3753,23 @@ meta_window_updates_are_frozen (MetaWindow *window)
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
-maybe_move_attached_dialog (MetaWindow *window,
+maybe_move_attached_window (MetaWindow *window,
void *data)
{
- if (meta_window_is_attached_dialog (window))
- /* It ignores x,y for such a dialog */
- meta_window_move_frame (window, FALSE, 0, 0);
+ if (meta_window_is_attached_dialog (window) ||
+ meta_window_get_placement_rule (window))
+ meta_window_reposition (window);
return FALSE;
}
@@ -4061,7 +4072,7 @@ meta_window_move_resize_internal (MetaWindow *window,
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,
workspace_manager->active_workspace);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]