mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
window: Replace the user_rect with the unconstrained_rect
Realistically, the user rect contains the unconstrained window rectangle coordinates that we want to be displaying, in case something in the constraints change. Rename it to the "unconstrained_rect", and change the code to always save it, regardless of current state. When metacity was originally being built, the purpose of the user rect was a lot less clear. The code only saved it on user actions, with various other calls to save_user_window_placement() and a force mechanism sprinkled in to avoid windows being snapped back to odd places when constraints changed. This could lead to odd bugs. For instance, if the user uses some extension which automatically tiles windows and didn't pass user_action=TRUE, and then the struts changed, the window would be placed back at the last place a user moved it to, rather than where the window was tiled to. The META_IS_USER_ACTION flag is still used in the constraints code to determine whether we should allow shoving windows offscreen, so we can't remove it completely, but we should think about splitting out the constrainment policies it commands for a bit more fine-grained control. https://bugzilla.gnome.org/show_bug.cgi?id=726714
This commit is contained in:
parent
4a7939268c
commit
2c0ad5bef7
@ -539,10 +539,10 @@ place_window_if_needed(MetaWindow *window,
|
|||||||
.083 * info->work_area_monitor.height;
|
.083 * info->work_area_monitor.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* idle_move_resize() uses the user_rect, so make sure it uses the
|
/* idle_move_resize() uses the unconstrained_rect, so make sure it
|
||||||
* placed coordinates (bug #556696).
|
* uses the placed coordinates (bug #556696).
|
||||||
*/
|
*/
|
||||||
window->user_rect = info->current;
|
window->unconstrained_rect = info->current;
|
||||||
|
|
||||||
if (window->maximize_horizontally_after_placement ||
|
if (window->maximize_horizontally_after_placement ||
|
||||||
window->maximize_vertically_after_placement)
|
window->maximize_vertically_after_placement)
|
||||||
|
@ -302,9 +302,6 @@ struct _MetaWindow
|
|||||||
/* Have we placed this window? */
|
/* Have we placed this window? */
|
||||||
guint placed : 1;
|
guint placed : 1;
|
||||||
|
|
||||||
/* Must we force_save_user_window_placement? */
|
|
||||||
guint force_save_user_rect : 1;
|
|
||||||
|
|
||||||
/* Is this not a transient of the focus window which is being denied focus? */
|
/* Is this not a transient of the focus window which is being denied focus? */
|
||||||
guint denied_focus_and_not_transient : 1;
|
guint denied_focus_and_not_transient : 1;
|
||||||
|
|
||||||
@ -422,16 +419,15 @@ struct _MetaWindow
|
|||||||
*/
|
*/
|
||||||
MetaRectangle saved_rect;
|
MetaRectangle saved_rect;
|
||||||
|
|
||||||
/* This is the geometry the window had after the last user-initiated
|
/* This is the geometry the window will have if no constraints have
|
||||||
* move/resize operations. We use this whenever we are moving the
|
* applied. We use this whenever we are moving implicitly (for example,
|
||||||
* implicitly (for example, if we move to avoid a panel, we can snap
|
* if we move to avoid a panel, we can snap back to this position if
|
||||||
* back to this position if the panel moves again). Note that this
|
* the panel moves again). Note that this gives the position and size
|
||||||
* gives the position and size of the client window (i.e. ignoring
|
* of the client window (i.e. ignoring the frame).
|
||||||
* the frame).
|
|
||||||
*
|
*
|
||||||
* Position always in root coords, unlike window->rect.
|
* Position always in root coords, unlike window->rect.
|
||||||
*/
|
*/
|
||||||
MetaRectangle user_rect;
|
MetaRectangle unconstrained_rect;
|
||||||
|
|
||||||
/* Cached net_wm_icon_geometry */
|
/* Cached net_wm_icon_geometry */
|
||||||
MetaRectangle icon_geometry;
|
MetaRectangle icon_geometry;
|
||||||
@ -742,7 +738,6 @@ void meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
int gravity,
|
int gravity,
|
||||||
MetaRectangle client_rect);
|
MetaRectangle client_rect);
|
||||||
void meta_window_save_user_window_placement (MetaWindow *window);
|
|
||||||
|
|
||||||
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
|
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
|
||||||
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
|
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
|
||||||
|
@ -79,7 +79,6 @@ static void meta_window_show (MetaWindow *window);
|
|||||||
static void meta_window_hide (MetaWindow *window);
|
static void meta_window_hide (MetaWindow *window);
|
||||||
|
|
||||||
static void meta_window_save_rect (MetaWindow *window);
|
static void meta_window_save_rect (MetaWindow *window);
|
||||||
static void force_save_user_window_placement (MetaWindow *window);
|
|
||||||
|
|
||||||
static void ensure_mru_position_after (MetaWindow *window,
|
static void ensure_mru_position_after (MetaWindow *window,
|
||||||
MetaWindow *after_this_one);
|
MetaWindow *after_this_one);
|
||||||
@ -831,7 +830,7 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
|
|
||||||
/* And this is our unmaximized size */
|
/* And this is our unmaximized size */
|
||||||
window->saved_rect = window->rect;
|
window->saved_rect = window->rect;
|
||||||
window->user_rect = window->rect;
|
window->unconstrained_rect = window->rect;
|
||||||
|
|
||||||
window->depth = attrs->depth;
|
window->depth = attrs->depth;
|
||||||
window->xvisual = attrs->visual;
|
window->xvisual = attrs->visual;
|
||||||
@ -877,7 +876,6 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
/* if already mapped we don't want to do the placement thing;
|
/* if already mapped we don't want to do the placement thing;
|
||||||
* override-redirect windows are placed by the app */
|
* override-redirect windows are placed by the app */
|
||||||
window->placed = ((window->mapped && !window->hidden) || window->override_redirect);
|
window->placed = ((window->mapped && !window->hidden) || window->override_redirect);
|
||||||
window->force_save_user_rect = TRUE;
|
|
||||||
window->denied_focus_and_not_transient = FALSE;
|
window->denied_focus_and_not_transient = FALSE;
|
||||||
window->unmanaging = FALSE;
|
window->unmanaging = FALSE;
|
||||||
window->is_in_queues = 0;
|
window->is_in_queues = 0;
|
||||||
@ -2715,49 +2713,6 @@ meta_window_save_rect (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* force_save_user_window_placement:
|
|
||||||
* @window: Store current position of this window for future reference
|
|
||||||
*
|
|
||||||
* Save the user_rect regardless of whether the window is maximized or
|
|
||||||
* fullscreen. See save_user_window_placement() for most uses.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
force_save_user_window_placement (MetaWindow *window)
|
|
||||||
{
|
|
||||||
meta_window_get_client_root_coords (window, &window->user_rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* save_user_window_placement:
|
|
||||||
* @window: Store current position of this window for future reference
|
|
||||||
*
|
|
||||||
* Save the user_rect, but only if the window is neither maximized nor
|
|
||||||
* fullscreen, otherwise the window may snap back to those dimensions
|
|
||||||
* (bug #461927).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_window_save_user_window_placement (MetaWindow *window)
|
|
||||||
{
|
|
||||||
if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED_SIDE_BY_SIDE (window) || window->fullscreen))
|
|
||||||
{
|
|
||||||
MetaRectangle user_rect;
|
|
||||||
|
|
||||||
meta_window_get_client_root_coords (window, &user_rect);
|
|
||||||
|
|
||||||
if (!window->maximized_horizontally)
|
|
||||||
{
|
|
||||||
window->user_rect.x = user_rect.x;
|
|
||||||
window->user_rect.width = user_rect.width;
|
|
||||||
}
|
|
||||||
if (!window->maximized_vertically)
|
|
||||||
{
|
|
||||||
window->user_rect.y = user_rect.y;
|
|
||||||
window->user_rect.height = user_rect.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_maximize_internal (MetaWindow *window,
|
meta_window_maximize_internal (MetaWindow *window,
|
||||||
MetaMaximizeFlags directions,
|
MetaMaximizeFlags directions,
|
||||||
@ -2788,8 +2743,6 @@ meta_window_maximize_internal (MetaWindow *window,
|
|||||||
window->maximized_horizontally || maximize_horizontally;
|
window->maximized_horizontally || maximize_horizontally;
|
||||||
window->maximized_vertically =
|
window->maximized_vertically =
|
||||||
window->maximized_vertically || maximize_vertically;
|
window->maximized_vertically || maximize_vertically;
|
||||||
if (maximize_horizontally || maximize_vertically)
|
|
||||||
window->force_save_user_rect = FALSE;
|
|
||||||
|
|
||||||
meta_window_recalc_features (window);
|
meta_window_recalc_features (window);
|
||||||
set_net_wm_state (window);
|
set_net_wm_state (window);
|
||||||
@ -3221,10 +3174,6 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
|||||||
&old_rect,
|
&old_rect,
|
||||||
&new_rect);
|
&new_rect);
|
||||||
|
|
||||||
/* Make sure user_rect is current.
|
|
||||||
*/
|
|
||||||
force_save_user_window_placement (window);
|
|
||||||
|
|
||||||
/* When we unmaximize, if we're doing a mouse move also we could
|
/* When we unmaximize, if we're doing a mouse move also we could
|
||||||
* get the window suddenly jumping to the upper left corner of
|
* get the window suddenly jumping to the upper left corner of
|
||||||
* the workspace, since that's where it was when the grab op
|
* the workspace, since that's where it was when the grab op
|
||||||
@ -3235,7 +3184,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
|||||||
if (meta_grab_op_is_moving (window->display->grab_op) &&
|
if (meta_grab_op_is_moving (window->display->grab_op) &&
|
||||||
window->display->grab_window == window)
|
window->display->grab_window == window)
|
||||||
{
|
{
|
||||||
window->display->grab_anchor_window_pos = window->user_rect;
|
window->display->grab_anchor_window_pos = window->unconstrained_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_recalc_features (window);
|
meta_window_recalc_features (window);
|
||||||
@ -3334,7 +3283,6 @@ meta_window_make_fullscreen_internal (MetaWindow *window)
|
|||||||
meta_window_save_rect (window);
|
meta_window_save_rect (window);
|
||||||
|
|
||||||
window->fullscreen = TRUE;
|
window->fullscreen = TRUE;
|
||||||
window->force_save_user_rect = FALSE;
|
|
||||||
|
|
||||||
meta_stack_freeze (window->screen->stack);
|
meta_stack_freeze (window->screen->stack);
|
||||||
meta_window_update_layer (window);
|
meta_window_update_layer (window);
|
||||||
@ -3398,10 +3346,6 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
|||||||
target_rect.width,
|
target_rect.width,
|
||||||
target_rect.height);
|
target_rect.height);
|
||||||
|
|
||||||
/* Make sure user_rect is current.
|
|
||||||
*/
|
|
||||||
force_save_user_window_placement (window);
|
|
||||||
|
|
||||||
meta_window_update_layer (window);
|
meta_window_update_layer (window);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (window), "fullscreen");
|
g_object_notify (G_OBJECT (window), "fullscreen");
|
||||||
@ -3754,7 +3698,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
* this is the root position of the X11 window. For server-decorated
|
* this is the root position of the X11 window. For server-decorated
|
||||||
* windows, this is the root position of the client area of the window.
|
* windows, this is the root position of the client area of the window.
|
||||||
*/
|
*/
|
||||||
gboolean is_user_action;
|
|
||||||
gboolean did_placement;
|
gboolean did_placement;
|
||||||
/* used for the configure request, but may not be final
|
/* used for the configure request, but may not be final
|
||||||
* destination due to StaticGravity etc.
|
* destination due to StaticGravity etc.
|
||||||
@ -3770,7 +3713,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_WAYLAND_RESIZE));
|
g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_WAYLAND_RESIZE));
|
||||||
|
|
||||||
is_user_action = (flags & META_IS_USER_ACTION) != 0;
|
|
||||||
did_placement = !window->placed && window->calc_placement;
|
did_placement = !window->placed && window->calc_placement;
|
||||||
|
|
||||||
/* We don't need it in the idle queue anymore. */
|
/* We don't need it in the idle queue anymore. */
|
||||||
@ -3797,6 +3739,10 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
|
|
||||||
new_rect = requested_rect;
|
new_rect = requested_rect;
|
||||||
|
|
||||||
|
/* Save the unconstrained rectangle to the position we should be at
|
||||||
|
* before constraints kick in. */
|
||||||
|
window->unconstrained_rect = new_rect;
|
||||||
|
|
||||||
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
||||||
{
|
{
|
||||||
MetaRectangle old_rect;
|
MetaRectangle old_rect;
|
||||||
@ -3816,11 +3762,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
/* Do the protocol-specific move/resize logic */
|
/* Do the protocol-specific move/resize logic */
|
||||||
META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, requested_rect, new_rect, flags, &result);
|
META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, requested_rect, new_rect, flags, &result);
|
||||||
|
|
||||||
if (!window->placed && window->force_save_user_rect && !window->fullscreen)
|
|
||||||
force_save_user_window_placement (window);
|
|
||||||
else if (is_user_action)
|
|
||||||
meta_window_save_user_window_placement (window);
|
|
||||||
|
|
||||||
if (result & META_MOVE_RESIZE_RESULT_MOVED)
|
if (result & META_MOVE_RESIZE_RESULT_MOVED)
|
||||||
g_signal_emit (window, window_signals[POSITION_CHANGED], 0);
|
g_signal_emit (window, window_signals[POSITION_CHANGED], 0);
|
||||||
|
|
||||||
@ -3948,21 +3889,17 @@ meta_window_move_between_rects (MetaWindow *window,
|
|||||||
int rel_x, rel_y;
|
int rel_x, rel_y;
|
||||||
double scale_x, scale_y;
|
double scale_x, scale_y;
|
||||||
|
|
||||||
rel_x = window->user_rect.x - old_area->x;
|
rel_x = window->unconstrained_rect.x - old_area->x;
|
||||||
rel_y = window->user_rect.y - old_area->y;
|
rel_y = window->unconstrained_rect.y - old_area->y;
|
||||||
scale_x = (double)new_area->width / old_area->width;
|
scale_x = (double)new_area->width / old_area->width;
|
||||||
scale_y = (double)new_area->height / old_area->height;
|
scale_y = (double)new_area->height / old_area->height;
|
||||||
|
|
||||||
window->user_rect.x = new_area->x + rel_x * scale_x;
|
window->unconstrained_rect.x = new_area->x + rel_x * scale_x;
|
||||||
window->user_rect.y = new_area->y + rel_y * scale_y;
|
window->unconstrained_rect.y = new_area->y + rel_y * scale_y;
|
||||||
window->saved_rect.x = window->user_rect.x;
|
window->saved_rect.x = window->unconstrained_rect.x;
|
||||||
window->saved_rect.y = window->user_rect.y;
|
window->saved_rect.y = window->unconstrained_rect.y;
|
||||||
|
|
||||||
meta_window_move_resize (window, FALSE,
|
meta_window_move_resize_now (window);
|
||||||
window->user_rect.x,
|
|
||||||
window->user_rect.y,
|
|
||||||
window->user_rect.width,
|
|
||||||
window->user_rect.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4068,15 +4005,11 @@ meta_window_resize_with_gravity (MetaWindow *window,
|
|||||||
static void
|
static void
|
||||||
meta_window_move_resize_now (MetaWindow *window)
|
meta_window_move_resize_now (MetaWindow *window)
|
||||||
{
|
{
|
||||||
/* If constraints have changed then we want to snap back to wherever
|
|
||||||
* the user had the window. We use user_rect for this reason. See
|
|
||||||
* also bug 426519 comment 3.
|
|
||||||
*/
|
|
||||||
meta_window_move_resize (window, FALSE,
|
meta_window_move_resize (window, FALSE,
|
||||||
window->user_rect.x,
|
window->unconstrained_rect.x,
|
||||||
window->user_rect.y,
|
window->unconstrained_rect.y,
|
||||||
window->user_rect.width,
|
window->unconstrained_rect.width,
|
||||||
window->user_rect.height);
|
window->unconstrained_rect.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -5827,8 +5760,8 @@ update_move (MetaWindow *window,
|
|||||||
window->saved_rect.y += window->frame->child_y;
|
window->saved_rect.y += window->frame->child_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
window->user_rect.x = window->saved_rect.x;
|
window->unconstrained_rect.x = window->saved_rect.x;
|
||||||
window->user_rect.y = window->saved_rect.y;
|
window->unconstrained_rect.y = window->saved_rect.y;
|
||||||
|
|
||||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||||
}
|
}
|
||||||
|
@ -289,5 +289,4 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
|||||||
|
|
||||||
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
|
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
|
||||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||||
meta_window_save_user_window_placement (window);
|
|
||||||
}
|
}
|
||||||
|
@ -2079,18 +2079,6 @@ meta_window_move_resize_request (MetaWindow *window,
|
|||||||
adjust_for_gravity (window, TRUE, gravity, &rect);
|
adjust_for_gravity (window, TRUE, gravity, &rect);
|
||||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* window->user_rect exists to allow "snapping-back" the window if a
|
|
||||||
* new strut is set (causing the window to move) and then the strut
|
|
||||||
* is later removed without the user moving the window in the
|
|
||||||
* interim. We'd like to "snap-back" to the position specified by
|
|
||||||
* ConfigureRequest events (at least the constrained version of the
|
|
||||||
* ConfigureRequest, since that is guaranteed to be onscreen) so we
|
|
||||||
* set user_rect here.
|
|
||||||
*
|
|
||||||
* See also bug 426519.
|
|
||||||
*/
|
|
||||||
meta_window_save_user_window_placement (window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
Loading…
Reference in New Issue
Block a user