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);