mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
window: Implement asynchronous popup moving
This commits adds support on the MetaWindow and constraints engine side for asynchronously repositioning a window with a placement rule, either due to environmental changes (e.g. parent moved) or explicitly done so via `meta_window_update_placement_rule()`. This is so far unused, as placement rules where this functionality is triggered are not yet constructed by the xdg-shell implementation, and no users of `meta_window_update_placement_rule()` exists yet. To summarize, it works by making it possible to produce placement rules with the parent rectangle a window should be placed against, while creating a pending configuration that is not applied until acknowledged by the client using the xdg-shell configure/ack_configure mechanisms. An "temporary" constrain result is added to deal with situations where the client window *must* move immediately even though it has not yet acknowledged a new configuration that was sent. This happens for example when the parent window is moved, causing the popup window to change its relative position e.g. because it ended up partially off-screen. In this situation, the temporary position corresponds to the result of the movement of the parent, while the pending (asynchronously configured) position is the relative one given the new constraining result. https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
This commit is contained in:
parent
6c82feb1b8
commit
d08a8de265
@ -123,6 +123,7 @@ typedef struct
|
||||
{
|
||||
MetaRectangle orig;
|
||||
MetaRectangle current;
|
||||
MetaRectangle temporary;
|
||||
int rel_x;
|
||||
int rel_y;
|
||||
ActionType action_type;
|
||||
@ -147,6 +148,8 @@ typedef struct
|
||||
*/
|
||||
GList *usable_screen_region;
|
||||
GList *usable_monitor_region;
|
||||
|
||||
MetaMoveResizeFlags flags;
|
||||
} ConstraintInfo;
|
||||
|
||||
static gboolean do_screen_and_monitor_relative_constraints (MetaWindow *window,
|
||||
@ -284,6 +287,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
MetaGravity resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
MetaRectangle *new,
|
||||
MetaRectangle *temporary,
|
||||
int *rel_x,
|
||||
int *rel_y)
|
||||
{
|
||||
@ -322,6 +326,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
|
||||
/* Make sure we use the constrained position */
|
||||
*new = info.current;
|
||||
*temporary = info.temporary;
|
||||
*rel_x = info.rel_x;
|
||||
*rel_y = info.rel_y;
|
||||
|
||||
@ -348,8 +353,10 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
|
||||
info->orig = *orig;
|
||||
info->current = *new;
|
||||
info->temporary = *orig;
|
||||
info->rel_x = 0;
|
||||
info->rel_y = 0;
|
||||
info->flags = flags;
|
||||
|
||||
if (info->current.width < 1)
|
||||
info->current.width = 1;
|
||||
@ -500,16 +507,11 @@ place_window_if_needed(MetaWindow *window,
|
||||
|
||||
if (window->placement.rule)
|
||||
{
|
||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||
MetaRectangle parent_rect;
|
||||
|
||||
meta_window_process_placement (window,
|
||||
window->placement.rule,
|
||||
&info->rel_x, &info->rel_y);
|
||||
meta_window_get_frame_rect (parent, &parent_rect);
|
||||
|
||||
placed_rect.x = parent_rect.x + info->rel_x;
|
||||
placed_rect.y = parent_rect.y + info->rel_y;
|
||||
placed_rect.x = window->placement.rule->parent_rect.x + info->rel_x;
|
||||
placed_rect.y = window->placement.rule->parent_rect.y + info->rel_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -825,12 +827,13 @@ constrain_custom_rule (MetaWindow *window,
|
||||
MetaPlacementRule *placement_rule;
|
||||
MetaRectangle intersection;
|
||||
gboolean constraint_satisfied;
|
||||
MetaRectangle temporary_rect;
|
||||
MetaRectangle adjusted_unconstrained;
|
||||
int adjusted_rel_x;
|
||||
int adjusted_rel_y;
|
||||
MetaPlacementRule current_rule;
|
||||
MetaWindow *parent;
|
||||
MetaRectangle parent_rect;
|
||||
int parent_x, parent_y;
|
||||
|
||||
if (priority > PRIORITY_CUSTOM_RULE)
|
||||
return TRUE;
|
||||
@ -839,25 +842,72 @@ constrain_custom_rule (MetaWindow *window,
|
||||
if (!placement_rule)
|
||||
return TRUE;
|
||||
|
||||
adjusted_unconstrained = info->current;
|
||||
|
||||
parent = meta_window_get_transient_for (window);
|
||||
meta_window_get_frame_rect (parent, &parent_rect);
|
||||
if (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_FINISHED)
|
||||
{
|
||||
placement_rule->parent_rect.x = parent->rect.x;
|
||||
placement_rule->parent_rect.y = parent->rect.y;
|
||||
}
|
||||
parent_x = placement_rule->parent_rect.x;
|
||||
parent_y = placement_rule->parent_rect.y;
|
||||
|
||||
/*
|
||||
* Calculate the temporary position, meaning a position that will be
|
||||
* applied if the new constrained position requires asynchronous
|
||||
* configuration of the window. This happens for example when the parent
|
||||
* moves, causing this window to change relative position, meaning it can
|
||||
* only have its newly constrained position applied when the configuration is
|
||||
* acknowledged.
|
||||
*/
|
||||
|
||||
switch (window->placement.state)
|
||||
{
|
||||
case META_PLACEMENT_STATE_UNCONSTRAINED:
|
||||
adjusted_rel_x = window->rect.x - parent->rect.x;
|
||||
adjusted_rel_y = window->rect.y - parent->rect.y;
|
||||
temporary_rect = info->current;
|
||||
break;
|
||||
case META_PLACEMENT_STATE_CONSTRAINED:
|
||||
adjusted_unconstrained.x =
|
||||
parent->rect.x + window->placement.current.rel_x;
|
||||
adjusted_unconstrained.y =
|
||||
parent->rect.y + window->placement.current.rel_y;
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED:
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_PENDING:
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_FINISHED:
|
||||
case META_PLACEMENT_STATE_INVALIDATED:
|
||||
temporary_rect = (MetaRectangle) {
|
||||
.x = parent->rect.x + window->placement.current.rel_x,
|
||||
.y = parent->rect.y + window->placement.current.rel_y,
|
||||
.width = info->current.width,
|
||||
.height = info->current.height,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate an adjusted current position. Depending on the rule
|
||||
* configuration and placement state, this may result in window being
|
||||
* reconstrained.
|
||||
*/
|
||||
|
||||
adjusted_unconstrained = temporary_rect;
|
||||
|
||||
if (window->placement.state == META_PLACEMENT_STATE_INVALIDATED ||
|
||||
window->placement.state == META_PLACEMENT_STATE_UNCONSTRAINED ||
|
||||
(window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_FINISHED &&
|
||||
placement_rule->is_reactive))
|
||||
{
|
||||
meta_window_process_placement (window, placement_rule,
|
||||
&adjusted_rel_x,
|
||||
&adjusted_rel_y);
|
||||
adjusted_unconstrained.x = parent_x + adjusted_rel_x;
|
||||
adjusted_unconstrained.y = parent_y + adjusted_rel_y;
|
||||
}
|
||||
else if (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_PENDING)
|
||||
{
|
||||
adjusted_rel_x = window->placement.pending.rel_x;
|
||||
adjusted_rel_y = window->placement.pending.rel_y;
|
||||
adjusted_unconstrained.x = window->placement.pending.x;
|
||||
adjusted_unconstrained.y = window->placement.pending.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
adjusted_rel_x = window->placement.current.rel_x;
|
||||
adjusted_rel_y = window->placement.current.rel_y;
|
||||
break;
|
||||
}
|
||||
|
||||
meta_rectangle_intersect (&adjusted_unconstrained, &info->work_area_monitor,
|
||||
@ -872,30 +922,43 @@ constrain_custom_rule (MetaWindow *window,
|
||||
if (check_only)
|
||||
return constraint_satisfied;
|
||||
|
||||
current_rule = *placement_rule;
|
||||
info->current = adjusted_unconstrained;
|
||||
info->rel_x = adjusted_rel_x;
|
||||
info->rel_y = adjusted_rel_y;
|
||||
info->temporary = temporary_rect;
|
||||
|
||||
switch (window->placement.state)
|
||||
{
|
||||
case META_PLACEMENT_STATE_CONSTRAINED:
|
||||
info->current = adjusted_unconstrained;
|
||||
info->rel_x = adjusted_rel_x;
|
||||
info->rel_y = adjusted_rel_y;
|
||||
goto done;
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_FINISHED:
|
||||
if (!placement_rule->is_reactive)
|
||||
return TRUE;
|
||||
break;
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_PENDING:
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED:
|
||||
return TRUE;
|
||||
case META_PLACEMENT_STATE_UNCONSTRAINED:
|
||||
case META_PLACEMENT_STATE_INVALIDATED:
|
||||
break;
|
||||
}
|
||||
|
||||
if (constraint_satisfied)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Process the placement rule in order either until constraints are
|
||||
* satisfied, or there are no more rules to process.
|
||||
*/
|
||||
|
||||
current_rule = *placement_rule;
|
||||
|
||||
if (info->current.width != intersection.width &&
|
||||
(current_rule.constraint_adjustment &
|
||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X))
|
||||
{
|
||||
try_flip_window_position (window, info, ¤t_rule,
|
||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X,
|
||||
parent_rect.x,
|
||||
parent_rect.y,
|
||||
parent_x,
|
||||
parent_y,
|
||||
&info->current,
|
||||
&info->rel_x,
|
||||
&info->rel_y,
|
||||
@ -907,8 +970,8 @@ constrain_custom_rule (MetaWindow *window,
|
||||
{
|
||||
try_flip_window_position (window, info, ¤t_rule,
|
||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y,
|
||||
parent_rect.x,
|
||||
parent_rect.y,
|
||||
parent_x,
|
||||
parent_y,
|
||||
&info->current,
|
||||
&info->rel_x,
|
||||
&info->rel_y,
|
||||
@ -1010,10 +1073,12 @@ constrain_custom_rule (MetaWindow *window,
|
||||
}
|
||||
|
||||
done:
|
||||
window->placement.state = META_PLACEMENT_STATE_CONSTRAINED;
|
||||
window->placement.state = META_PLACEMENT_STATE_CONSTRAINED_PENDING;
|
||||
|
||||
window->placement.current.rel_x = info->rel_x;
|
||||
window->placement.current.rel_y = info->rel_y;
|
||||
window->placement.pending.rel_x = info->rel_x;
|
||||
window->placement.pending.rel_y = info->rel_y;
|
||||
window->placement.pending.x = info->current.x;
|
||||
window->placement.pending.y = info->current.y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ void meta_window_constrain (MetaWindow *window,
|
||||
MetaGravity resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
MetaRectangle *new,
|
||||
MetaRectangle *intermediate,
|
||||
int *rel_x,
|
||||
int *rel_y);
|
||||
|
||||
|
@ -85,6 +85,7 @@ typedef enum
|
||||
META_MOVE_RESIZE_FORCE_MOVE = 1 << 8,
|
||||
META_MOVE_RESIZE_WAYLAND_STATE_CHANGED = 1 << 9,
|
||||
META_MOVE_RESIZE_FORCE_UPDATE_MONITOR = 1 << 10,
|
||||
META_MOVE_RESIZE_PLACEMENT_CHANGED = 1 << 11,
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
typedef enum
|
||||
@ -141,12 +142,19 @@ typedef struct _MetaPlacementRule
|
||||
int offset_y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
gboolean is_reactive;
|
||||
|
||||
MetaRectangle parent_rect;
|
||||
} MetaPlacementRule;
|
||||
|
||||
typedef enum _MetaPlacementState
|
||||
{
|
||||
META_PLACEMENT_STATE_UNCONSTRAINED,
|
||||
META_PLACEMENT_STATE_CONSTRAINED,
|
||||
META_PLACEMENT_STATE_CONSTRAINED_PENDING,
|
||||
META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED,
|
||||
META_PLACEMENT_STATE_CONSTRAINED_FINISHED,
|
||||
META_PLACEMENT_STATE_INVALIDATED,
|
||||
} MetaPlacementState;
|
||||
|
||||
typedef enum
|
||||
@ -538,6 +546,13 @@ struct _MetaWindow
|
||||
MetaPlacementRule *rule;
|
||||
MetaPlacementState state;
|
||||
|
||||
struct {
|
||||
int x;
|
||||
int y;
|
||||
int rel_x;
|
||||
int rel_y;
|
||||
} pending;
|
||||
|
||||
struct {
|
||||
int rel_x;
|
||||
int rel_y;
|
||||
@ -569,6 +584,7 @@ struct _MetaWindowClass
|
||||
MetaGravity gravity,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
MetaRectangle temporary_rect,
|
||||
int rel_x,
|
||||
int rel_y,
|
||||
MetaMoveResizeFlags flags,
|
||||
|
@ -4001,6 +4001,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
gboolean did_placement;
|
||||
MetaRectangle unconstrained_rect;
|
||||
MetaRectangle constrained_rect;
|
||||
MetaRectangle temporary_rect;
|
||||
int rel_x = 0;
|
||||
int rel_y = 0;
|
||||
MetaMoveResizeResultFlags result = 0;
|
||||
@ -4057,6 +4058,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
g_assert_not_reached ();
|
||||
|
||||
constrained_rect = unconstrained_rect;
|
||||
temporary_rect = window->rect;
|
||||
if (flags & (META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION) &&
|
||||
!(flags & META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE) &&
|
||||
window->monitor)
|
||||
@ -4069,13 +4071,14 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
gravity,
|
||||
&old_rect,
|
||||
&constrained_rect,
|
||||
&temporary_rect,
|
||||
&rel_x,
|
||||
&rel_y);
|
||||
}
|
||||
else if (window->placement.rule)
|
||||
{
|
||||
rel_x = window->placement.current.rel_x;
|
||||
rel_y = window->placement.current.rel_y;
|
||||
rel_x = window->placement.pending.rel_x;
|
||||
rel_y = window->placement.pending.rel_y;
|
||||
}
|
||||
|
||||
/* If we did placement, then we need to save the position that the window
|
||||
@ -4093,6 +4096,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
gravity,
|
||||
unconstrained_rect,
|
||||
constrained_rect,
|
||||
temporary_rect,
|
||||
rel_x,
|
||||
rel_y,
|
||||
flags, &result);
|
||||
|
@ -138,7 +138,8 @@ G_DEFINE_TYPE_WITH_CODE (MetaWaylandXdgPopup,
|
||||
popup_surface_iface_init));
|
||||
|
||||
static MetaPlacementRule
|
||||
meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_positioner);
|
||||
meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_positioner,
|
||||
MetaWindow *parent_window);
|
||||
|
||||
static struct wl_resource *
|
||||
meta_wayland_xdg_surface_get_wm_base_resource (MetaWaylandXdgSurface *xdg_surface);
|
||||
@ -1745,6 +1746,7 @@ xdg_surface_constructor_get_popup (struct wl_client *client,
|
||||
struct wl_resource *xdg_surface_resource = constructor->resource;
|
||||
MetaWaylandSurface *parent_surface =
|
||||
surface_from_xdg_surface_resource (parent_resource);
|
||||
MetaWindow *parent_window;
|
||||
MetaWaylandXdgPositioner *xdg_positioner;
|
||||
MetaWaylandXdgPopup *xdg_popup;
|
||||
MetaWaylandXdgSurface *xdg_surface;
|
||||
@ -1783,9 +1785,11 @@ xdg_surface_constructor_get_popup (struct wl_client *client,
|
||||
xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup);
|
||||
meta_wayland_xdg_surface_constructor_finalize (constructor, xdg_surface);
|
||||
|
||||
parent_window = meta_wayland_surface_get_window (parent_surface);
|
||||
|
||||
xdg_positioner = wl_resource_get_user_data (positioner_resource);
|
||||
xdg_popup->setup.placement_rule =
|
||||
meta_wayland_xdg_positioner_to_placement (xdg_positioner);
|
||||
meta_wayland_xdg_positioner_to_placement (xdg_positioner, parent_window);
|
||||
xdg_popup->setup.parent_surface = parent_surface;
|
||||
}
|
||||
|
||||
@ -1892,8 +1896,13 @@ positioner_gravity_to_placement_gravity (uint32_t gravity)
|
||||
}
|
||||
|
||||
static MetaPlacementRule
|
||||
meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_positioner)
|
||||
meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_positioner,
|
||||
MetaWindow *parent_window)
|
||||
{
|
||||
MetaRectangle parent_rect;
|
||||
|
||||
meta_window_get_frame_rect (parent_window, &parent_rect);
|
||||
|
||||
return (MetaPlacementRule) {
|
||||
.anchor_rect = xdg_positioner->anchor_rect,
|
||||
.gravity = positioner_gravity_to_placement_gravity (xdg_positioner->gravity),
|
||||
@ -1903,6 +1912,8 @@ meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_position
|
||||
.offset_y = xdg_positioner->offset_y,
|
||||
.width = xdg_positioner->width,
|
||||
.height = xdg_positioner->height,
|
||||
|
||||
.parent_rect = parent_rect,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -222,18 +222,23 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
MetaGravity gravity,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
MetaRectangle temporary_rect,
|
||||
int rel_x,
|
||||
int rel_y,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
gboolean can_move_now;
|
||||
gboolean can_move_now = FALSE;
|
||||
int configured_x;
|
||||
int configured_y;
|
||||
int configured_width;
|
||||
int configured_height;
|
||||
int geometry_scale;
|
||||
int new_x;
|
||||
int new_y;
|
||||
int new_buffer_x;
|
||||
int new_buffer_y;
|
||||
|
||||
g_assert (window->frame == NULL);
|
||||
|
||||
@ -300,14 +305,61 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
/* This is a commit of an attach. We should move the window to match the
|
||||
* new position the client wants. */
|
||||
can_move_now = TRUE;
|
||||
if (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED)
|
||||
window->placement.state = META_PLACEMENT_STATE_CONSTRAINED_FINISHED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the size changed, or the state changed, then we have to wait until
|
||||
* the client acks our configure before moving the window. */
|
||||
if (constrained_rect.width != window->rect.width ||
|
||||
constrained_rect.height != window->rect.height ||
|
||||
(flags & META_MOVE_RESIZE_STATE_CHANGED))
|
||||
if (window->placement.rule)
|
||||
{
|
||||
switch (window->placement.state)
|
||||
{
|
||||
case META_PLACEMENT_STATE_UNCONSTRAINED:
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED:
|
||||
case META_PLACEMENT_STATE_INVALIDATED:
|
||||
can_move_now = FALSE;
|
||||
break;
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_PENDING:
|
||||
{
|
||||
if (flags & META_MOVE_RESIZE_PLACEMENT_CHANGED ||
|
||||
rel_x != wl_window->last_sent_rel_x ||
|
||||
rel_y != wl_window->last_sent_rel_y ||
|
||||
constrained_rect.width != window->rect.width ||
|
||||
constrained_rect.height != window->rect.height)
|
||||
{
|
||||
MetaWaylandWindowConfiguration *configuration;
|
||||
|
||||
configuration =
|
||||
meta_wayland_window_configuration_new_relative (rel_x,
|
||||
rel_y,
|
||||
configured_width,
|
||||
configured_height);
|
||||
meta_window_wayland_configure (wl_window, configuration);
|
||||
|
||||
wl_window->last_sent_rel_x = rel_x;
|
||||
wl_window->last_sent_rel_y = rel_y;
|
||||
|
||||
window->placement.state = META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED;
|
||||
|
||||
can_move_now = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
window->placement.state =
|
||||
META_PLACEMENT_STATE_CONSTRAINED_FINISHED;
|
||||
|
||||
can_move_now = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case META_PLACEMENT_STATE_CONSTRAINED_FINISHED:
|
||||
can_move_now = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (constrained_rect.width != window->rect.width ||
|
||||
constrained_rect.height != window->rect.height ||
|
||||
flags & META_MOVE_RESIZE_STATE_CHANGED)
|
||||
{
|
||||
MetaWaylandWindowConfiguration *configuration;
|
||||
|
||||
@ -328,32 +380,18 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
constrained_rect.height == 1)
|
||||
return;
|
||||
|
||||
if (window->placement.rule)
|
||||
{
|
||||
configuration =
|
||||
meta_wayland_window_configuration_new_relative (rel_x,
|
||||
rel_y,
|
||||
configured_width,
|
||||
configured_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
configuration =
|
||||
meta_wayland_window_configuration_new (configured_x,
|
||||
configured_y,
|
||||
configured_width,
|
||||
configured_height,
|
||||
flags,
|
||||
gravity);
|
||||
}
|
||||
|
||||
configuration =
|
||||
meta_wayland_window_configuration_new (configured_x,
|
||||
configured_y,
|
||||
configured_width,
|
||||
configured_height,
|
||||
flags,
|
||||
gravity);
|
||||
meta_window_wayland_configure (wl_window, configuration);
|
||||
can_move_now = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're just moving the window, so we don't need to wait for a configure
|
||||
* and then ack to simply move the window. */
|
||||
can_move_now = TRUE;
|
||||
}
|
||||
}
|
||||
@ -365,33 +403,46 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
|
||||
if (can_move_now)
|
||||
{
|
||||
int new_x = constrained_rect.x;
|
||||
int new_y = constrained_rect.y;
|
||||
|
||||
if (new_x != window->rect.x || new_y != window->rect.y)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
window->rect.x = new_x;
|
||||
window->rect.y = new_y;
|
||||
}
|
||||
|
||||
int new_buffer_x = new_x - window->custom_frame_extents.left;
|
||||
int new_buffer_y = new_y - window->custom_frame_extents.top;
|
||||
|
||||
if (new_buffer_x != window->buffer_rect.x || new_buffer_y != window->buffer_rect.y)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
window->buffer_rect.x = new_buffer_x;
|
||||
window->buffer_rect.y = new_buffer_y;
|
||||
}
|
||||
|
||||
if (flags & META_MOVE_RESIZE_WAYLAND_STATE_CHANGED)
|
||||
*result |= META_MOVE_RESIZE_RESULT_STATE_CHANGED;
|
||||
new_x = constrained_rect.x;
|
||||
new_y = constrained_rect.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_window->has_pending_state_change = (flags & META_MOVE_RESIZE_STATE_CHANGED) != 0;
|
||||
new_x = temporary_rect.x;
|
||||
new_y = temporary_rect.y;
|
||||
|
||||
wl_window->has_pending_state_change |=
|
||||
!!(flags & META_MOVE_RESIZE_STATE_CHANGED);
|
||||
}
|
||||
|
||||
if (new_x != window->rect.x || new_y != window->rect.y)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
window->rect.x = new_x;
|
||||
window->rect.y = new_y;
|
||||
}
|
||||
|
||||
if (window->placement.rule &&
|
||||
window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_FINISHED)
|
||||
{
|
||||
window->placement.current.rel_x = rel_x;
|
||||
window->placement.current.rel_y = rel_y;
|
||||
}
|
||||
|
||||
new_buffer_x = new_x - window->custom_frame_extents.left;
|
||||
new_buffer_y = new_y - window->custom_frame_extents.top;
|
||||
|
||||
if (new_buffer_x != window->buffer_rect.x ||
|
||||
new_buffer_y != window->buffer_rect.y)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
window->buffer_rect.x = new_buffer_x;
|
||||
window->buffer_rect.y = new_buffer_y;
|
||||
}
|
||||
|
||||
if (can_move_now &&
|
||||
flags & META_MOVE_RESIZE_WAYLAND_STATE_CHANGED)
|
||||
*result |= META_MOVE_RESIZE_RESULT_STATE_CHANGED;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -857,8 +908,19 @@ meta_window_wayland_finish_move_resize (MetaWindow *window,
|
||||
{
|
||||
if (acked_configuration)
|
||||
{
|
||||
rect.x = acked_configuration->x;
|
||||
rect.y = acked_configuration->y;
|
||||
if (window->placement.rule)
|
||||
{
|
||||
MetaWindow *parent;
|
||||
|
||||
parent = meta_window_get_transient_for (window);
|
||||
rect.x = parent->rect.x + acked_configuration->rel_x;
|
||||
rect.y = parent->rect.y + acked_configuration->rel_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.x = acked_configuration->x;
|
||||
rect.y = acked_configuration->y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -872,6 +934,14 @@ meta_window_wayland_finish_move_resize (MetaWindow *window,
|
||||
if (rect.x != window->rect.x || rect.y != window->rect.y)
|
||||
flags |= META_MOVE_RESIZE_MOVE_ACTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (acked_configuration)
|
||||
{
|
||||
rect.x = acked_configuration->x;
|
||||
rect.y = acked_configuration->y;
|
||||
}
|
||||
}
|
||||
|
||||
if (wl_window->has_pending_state_change && acked_configuration)
|
||||
{
|
||||
@ -918,9 +988,24 @@ meta_window_place_with_placement_rule (MetaWindow *window,
|
||||
window->placement.rule = g_new0 (MetaPlacementRule, 1);
|
||||
*window->placement.rule = *placement_rule;
|
||||
|
||||
window->unconstrained_rect.x = window->rect.x;
|
||||
window->unconstrained_rect.y = window->rect.y;
|
||||
window->unconstrained_rect.width = placement_rule->width;
|
||||
window->unconstrained_rect.height = placement_rule->height;
|
||||
meta_window_force_placement (window, FALSE);
|
||||
meta_window_move_resize_internal (window,
|
||||
(META_MOVE_RESIZE_MOVE_ACTION |
|
||||
META_MOVE_RESIZE_RESIZE_ACTION |
|
||||
META_MOVE_RESIZE_PLACEMENT_CHANGED),
|
||||
META_GRAVITY_NORTH_WEST,
|
||||
window->unconstrained_rect);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_update_placement_rule (MetaWindow *window,
|
||||
MetaPlacementRule *placement_rule)
|
||||
{
|
||||
window->placement.state = META_PLACEMENT_STATE_INVALIDATED;
|
||||
meta_window_place_with_placement_rule (window, placement_rule);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,6 +53,9 @@ void meta_window_wayland_place_relative_to (MetaWindow *window,
|
||||
void meta_window_place_with_placement_rule (MetaWindow *window,
|
||||
MetaPlacementRule *placement_rule);
|
||||
|
||||
void meta_window_update_placement_rule (MetaWindow *window,
|
||||
MetaPlacementRule *placement_rule);
|
||||
|
||||
void meta_window_wayland_set_min_size (MetaWindow *window,
|
||||
int width,
|
||||
int height);
|
||||
|
@ -1312,6 +1312,7 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
MetaGravity gravity,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
MetaRectangle intermediate_rect,
|
||||
int rel_x,
|
||||
int rel_y,
|
||||
MetaMoveResizeFlags flags,
|
||||
|
Loading…
Reference in New Issue
Block a user