2014-03-19 09:26:17 -04:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 Red Hat
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* Written by:
|
|
|
|
* Jasper St. Pierre <jstpierre@mecheye.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "window-wayland.h"
|
|
|
|
|
2014-05-20 09:08:11 -04:00
|
|
|
#include <meta/errors.h>
|
2014-03-19 09:26:17 -04:00
|
|
|
#include "window-private.h"
|
2014-03-19 10:30:12 -04:00
|
|
|
#include "boxes-private.h"
|
2014-03-19 09:36:15 -04:00
|
|
|
#include "stack-tracker.h"
|
|
|
|
#include "meta-wayland-surface.h"
|
2014-03-19 09:26:17 -04:00
|
|
|
|
|
|
|
struct _MetaWindowWayland
|
|
|
|
{
|
|
|
|
MetaWindow parent;
|
2014-04-28 16:19:06 -04:00
|
|
|
|
wayland-surface: Don't do pending move/resizes on all commits
We assume in meta_window_wayland_move_resize that the next commit that
changes the geometry will always be for our next pending operation, so
if we have a move pending on a resize, the next commit will trigger the
move. This is, of course, fundamentally wrong.
We broke this assumption even more now that we don't fizzle out calls to
meta_window_move_resize_internal and now call it on every commit, which
means that a simple damage and then commit would complete a pending
move.
This was even broken by apps like weston-terminal, which, when clicking
on the maximize button, first redraws the terminal with the maximize
button state back on hover on press, and would only redraw when it got
the configure event with the coordinates.
To track the correct commit to apply the move for, we implement the
ack_configure request and ignore all move/resizes that happen before
that.
Right now, we actually fizzle out the entire move/resize if there's a
future pending configure we're waiting on.
2014-07-27 11:23:17 -04:00
|
|
|
MetaWaylandSerial pending_configure_serial;
|
2014-07-27 11:37:18 -04:00
|
|
|
gboolean has_pending_move;
|
|
|
|
int pending_move_x;
|
|
|
|
int pending_move_y;
|
2014-05-12 18:05:31 -04:00
|
|
|
|
|
|
|
int last_sent_width;
|
|
|
|
int last_sent_height;
|
2014-03-19 09:26:17 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _MetaWindowWaylandClass
|
|
|
|
{
|
|
|
|
MetaWindowClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW)
|
|
|
|
|
2014-03-19 09:36:15 -04:00
|
|
|
static void
|
|
|
|
meta_window_wayland_manage (MetaWindow *window)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = window->display;
|
|
|
|
|
|
|
|
meta_display_register_wayland_window (display, window);
|
|
|
|
|
|
|
|
{
|
|
|
|
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
2014-09-08 21:20:14 -04:00
|
|
|
window->stamp,
|
2014-03-19 09:36:15 -04:00
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_wayland_unmanage (MetaWindow *window)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
2014-09-08 21:20:14 -04:00
|
|
|
window->stamp,
|
2014-03-19 09:36:15 -04:00
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_display_unregister_wayland_window (window->display, window);
|
|
|
|
}
|
|
|
|
|
2014-03-20 15:12:44 -04:00
|
|
|
static void
|
|
|
|
meta_window_wayland_ping (MetaWindow *window,
|
|
|
|
guint32 serial)
|
|
|
|
{
|
|
|
|
meta_wayland_surface_ping (window->surface, serial);
|
|
|
|
}
|
|
|
|
|
2014-03-20 15:07:44 -04:00
|
|
|
static void
|
|
|
|
meta_window_wayland_delete (MetaWindow *window,
|
|
|
|
guint32 timestamp)
|
|
|
|
{
|
|
|
|
meta_wayland_surface_delete (window->surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_wayland_kill (MetaWindow *window)
|
|
|
|
{
|
2014-03-25 12:05:21 -04:00
|
|
|
MetaWaylandSurface *surface = window->surface;
|
|
|
|
struct wl_resource *resource = surface->resource;
|
|
|
|
|
|
|
|
/* Send the client an unrecoverable error to kill the client. */
|
|
|
|
wl_resource_post_error (resource,
|
|
|
|
WL_DISPLAY_ERROR_NO_MEMORY,
|
|
|
|
"User requested that we kill you. Sorry. Don't take it too personally.");
|
2014-03-20 15:07:44 -04:00
|
|
|
}
|
|
|
|
|
2014-03-20 15:16:57 -04:00
|
|
|
static void
|
|
|
|
meta_window_wayland_focus (MetaWindow *window,
|
|
|
|
guint32 timestamp)
|
|
|
|
{
|
|
|
|
meta_display_set_input_focus_window (window->display,
|
|
|
|
window,
|
|
|
|
FALSE,
|
|
|
|
timestamp);
|
|
|
|
}
|
|
|
|
|
2014-05-20 15:54:39 -04:00
|
|
|
static void
|
|
|
|
surface_state_changed (MetaWindow *window)
|
|
|
|
{
|
|
|
|
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
|
|
|
|
|
|
|
meta_wayland_surface_configure_notify (window->surface,
|
|
|
|
wl_window->last_sent_width,
|
wayland-surface: Don't do pending move/resizes on all commits
We assume in meta_window_wayland_move_resize that the next commit that
changes the geometry will always be for our next pending operation, so
if we have a move pending on a resize, the next commit will trigger the
move. This is, of course, fundamentally wrong.
We broke this assumption even more now that we don't fizzle out calls to
meta_window_move_resize_internal and now call it on every commit, which
means that a simple damage and then commit would complete a pending
move.
This was even broken by apps like weston-terminal, which, when clicking
on the maximize button, first redraws the terminal with the maximize
button state back on hover on press, and would only redraw when it got
the configure event with the coordinates.
To track the correct commit to apply the move for, we implement the
ack_configure request and ignore all move/resizes that happen before
that.
Right now, we actually fizzle out the entire move/resize if there's a
future pending configure we're waiting on.
2014-07-27 11:23:17 -04:00
|
|
|
wl_window->last_sent_height,
|
|
|
|
&wl_window->pending_configure_serial);
|
2014-05-20 15:54:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_wayland_grab_op_began (MetaWindow *window,
|
|
|
|
MetaGrabOp op)
|
|
|
|
{
|
2014-07-17 15:53:38 -04:00
|
|
|
if (meta_grab_op_is_resizing (op))
|
|
|
|
surface_state_changed (window);
|
2014-05-20 15:54:39 -04:00
|
|
|
|
|
|
|
META_WINDOW_CLASS (meta_window_wayland_parent_class)->grab_op_began (window, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_wayland_grab_op_ended (MetaWindow *window,
|
|
|
|
MetaGrabOp op)
|
|
|
|
{
|
2014-07-17 15:53:38 -04:00
|
|
|
if (meta_grab_op_is_resizing (op))
|
|
|
|
surface_state_changed (window);
|
2014-05-20 15:54:39 -04:00
|
|
|
|
|
|
|
META_WINDOW_CLASS (meta_window_wayland_parent_class)->grab_op_ended (window, op);
|
|
|
|
}
|
|
|
|
|
2014-03-19 10:30:12 -04:00
|
|
|
static void
|
|
|
|
meta_window_wayland_move_resize_internal (MetaWindow *window,
|
|
|
|
int gravity,
|
2014-05-21 13:59:13 -04:00
|
|
|
MetaRectangle unconstrained_rect,
|
2014-03-19 10:30:12 -04:00
|
|
|
MetaRectangle constrained_rect,
|
|
|
|
MetaMoveResizeFlags flags,
|
|
|
|
MetaMoveResizeResultFlags *result)
|
|
|
|
{
|
2014-04-28 16:19:06 -04:00
|
|
|
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
2014-07-27 11:47:40 -04:00
|
|
|
gboolean can_move_now;
|
2014-04-16 16:28:43 -04:00
|
|
|
|
2014-03-19 10:30:12 -04:00
|
|
|
g_assert (window->frame == NULL);
|
|
|
|
|
|
|
|
/* For wayland clients, the size is completely determined by the client,
|
|
|
|
* and while this allows to avoid some trickery with frames and the resulting
|
|
|
|
* lagging, we also need to insist a bit when the constraints would apply
|
|
|
|
* a different size than the client decides.
|
|
|
|
*
|
|
|
|
* Note that this is not generally a problem for normal toplevel windows (the
|
|
|
|
* constraints don't see the size hints, or just change the position), but
|
|
|
|
* it can be for maximized or fullscreen.
|
|
|
|
*/
|
|
|
|
|
2014-12-15 16:28:47 -05:00
|
|
|
if (flags & META_MOVE_RESIZE_WAYLAND_RESIZE)
|
2014-03-19 10:30:12 -04:00
|
|
|
{
|
|
|
|
/* This is a call to wl_surface_commit(), ignore the constrained_rect and
|
|
|
|
* update the real client size to match the buffer size.
|
|
|
|
*/
|
|
|
|
|
2014-07-17 17:26:22 -04:00
|
|
|
if (window->rect.width != unconstrained_rect.width ||
|
|
|
|
window->rect.height != unconstrained_rect.height)
|
|
|
|
{
|
|
|
|
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
|
|
|
window->rect.width = unconstrained_rect.width;
|
|
|
|
window->rect.height = unconstrained_rect.height;
|
|
|
|
}
|
|
|
|
|
2014-04-16 16:28:43 -04:00
|
|
|
/* This is a commit of an attach. We should move the window to match the
|
|
|
|
* new position the client wants. */
|
2014-07-27 11:47:40 -04:00
|
|
|
can_move_now = TRUE;
|
2014-03-19 10:30:12 -04:00
|
|
|
}
|
2014-07-27 12:30:33 -04:00
|
|
|
else
|
2014-03-19 10:30:12 -04:00
|
|
|
{
|
2014-07-27 12:30:33 -04:00
|
|
|
if (constrained_rect.width != window->rect.width ||
|
|
|
|
constrained_rect.height != window->rect.height)
|
|
|
|
{
|
2014-09-17 11:36:31 -04:00
|
|
|
/* If we get a 0x0 size, this means that we're trying to resize
|
|
|
|
* a surface that doesn't have any buffer attached. This can happen
|
|
|
|
* when a client requests an xdg surface before bringing it up.
|
|
|
|
* The constrained_rect will be 1x1 because of how our constraints
|
|
|
|
* code works, and sending that to the window would cause it to
|
|
|
|
* redraw itself, so just don't send anything.
|
|
|
|
*/
|
|
|
|
if (unconstrained_rect.width == 0 &&
|
|
|
|
unconstrained_rect.height == 0)
|
|
|
|
return;
|
|
|
|
|
2014-07-27 12:30:33 -04:00
|
|
|
meta_wayland_surface_configure_notify (window->surface,
|
|
|
|
constrained_rect.width,
|
|
|
|
constrained_rect.height,
|
|
|
|
&wl_window->pending_configure_serial);
|
2014-07-27 11:47:40 -04:00
|
|
|
|
2014-07-27 12:30:33 -04:00
|
|
|
/* We need to wait until the resize completes before we can move */
|
|
|
|
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;
|
|
|
|
}
|
2014-04-16 16:28:43 -04:00
|
|
|
}
|
2014-03-19 10:30:12 -04:00
|
|
|
|
2014-09-16 21:16:19 -04:00
|
|
|
wl_window->last_sent_width = constrained_rect.width;
|
|
|
|
wl_window->last_sent_height = constrained_rect.height;
|
2014-09-16 21:11:56 -04:00
|
|
|
|
2014-07-27 11:47:40 -04:00
|
|
|
if (can_move_now)
|
2014-04-16 16:16:01 -04:00
|
|
|
{
|
2014-04-28 18:15:03 -04:00
|
|
|
int new_x = constrained_rect.x;
|
|
|
|
int new_y = constrained_rect.y;
|
2014-04-28 16:20:53 -04:00
|
|
|
|
2014-04-28 15:51:41 -04:00
|
|
|
if (new_x != window->rect.x || new_y != window->rect.y)
|
2014-04-28 15:50:40 -04:00
|
|
|
{
|
|
|
|
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
2014-06-26 11:02:57 -04:00
|
|
|
window->rect.x = new_x;
|
|
|
|
window->rect.y = new_y;
|
2014-07-07 13:06:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int new_buffer_x = new_x - window->custom_frame_extents.left;
|
|
|
|
int new_buffer_y = new_y - window->custom_frame_extents.top;
|
2014-06-26 11:02:57 -04:00
|
|
|
|
2014-07-07 13:06:47 -04:00
|
|
|
if (new_buffer_x != window->buffer_rect.x || new_buffer_y != window->buffer_rect.y)
|
|
|
|
{
|
|
|
|
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
2014-07-17 15:27:47 -04:00
|
|
|
window->buffer_rect.x = new_buffer_x;
|
|
|
|
window->buffer_rect.y = new_buffer_y;
|
2014-04-28 15:50:40 -04:00
|
|
|
}
|
2014-03-19 10:30:12 -04:00
|
|
|
}
|
2014-07-27 11:47:40 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int new_x = constrained_rect.x;
|
|
|
|
int new_y = constrained_rect.y;
|
|
|
|
|
|
|
|
if (new_x != window->rect.x || new_y != window->rect.y)
|
|
|
|
{
|
|
|
|
wl_window->has_pending_move = TRUE;
|
|
|
|
wl_window->pending_move_x = new_x;
|
|
|
|
wl_window->pending_move_y = new_y;
|
|
|
|
}
|
|
|
|
}
|
2014-03-19 10:30:12 -04:00
|
|
|
}
|
|
|
|
|
2014-03-19 09:26:17 -04:00
|
|
|
static void
|
2014-05-12 18:19:11 -04:00
|
|
|
appears_focused_changed (GObject *object,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
2014-03-19 09:26:17 -04:00
|
|
|
{
|
2014-05-12 18:19:11 -04:00
|
|
|
MetaWindow *window = META_WINDOW (object);
|
|
|
|
|
|
|
|
/* When we're unmanaging, we remove focus from the window,
|
|
|
|
* causing this to fire. Don't do anything in that case. */
|
|
|
|
if (window->unmanaging)
|
|
|
|
return;
|
|
|
|
|
2014-05-05 19:09:22 -04:00
|
|
|
surface_state_changed (window);
|
2014-05-12 18:19:11 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_wayland_init (MetaWindowWayland *wl_window)
|
|
|
|
{
|
|
|
|
MetaWindow *window = META_WINDOW (wl_window);
|
|
|
|
|
|
|
|
g_signal_connect (window, "notify::appears-focused",
|
|
|
|
G_CALLBACK (appears_focused_changed), NULL);
|
2014-03-19 09:26:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
|
|
|
{
|
2014-03-19 09:36:15 -04:00
|
|
|
MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
|
|
|
|
|
|
|
|
window_class->manage = meta_window_wayland_manage;
|
|
|
|
window_class->unmanage = meta_window_wayland_unmanage;
|
2014-03-20 15:12:44 -04:00
|
|
|
window_class->ping = meta_window_wayland_ping;
|
2014-03-20 15:07:44 -04:00
|
|
|
window_class->delete = meta_window_wayland_delete;
|
|
|
|
window_class->kill = meta_window_wayland_kill;
|
2014-03-20 15:16:57 -04:00
|
|
|
window_class->focus = meta_window_wayland_focus;
|
2014-05-20 15:54:39 -04:00
|
|
|
window_class->grab_op_began = meta_window_wayland_grab_op_began;
|
|
|
|
window_class->grab_op_ended = meta_window_wayland_grab_op_ended;
|
2014-03-19 10:30:12 -04:00
|
|
|
window_class->move_resize_internal = meta_window_wayland_move_resize_internal;
|
2014-03-19 09:26:17 -04:00
|
|
|
}
|
2014-04-28 17:44:45 -04:00
|
|
|
|
2014-05-20 09:08:11 -04:00
|
|
|
MetaWindow *
|
|
|
|
meta_window_wayland_new (MetaDisplay *display,
|
|
|
|
MetaWaylandSurface *surface)
|
|
|
|
{
|
|
|
|
XWindowAttributes attrs;
|
|
|
|
MetaScreen *scr = display->screen;
|
|
|
|
MetaWindow *window;
|
|
|
|
|
|
|
|
attrs.x = 0;
|
|
|
|
attrs.y = 0;
|
2014-09-16 23:09:13 -04:00
|
|
|
attrs.width = 0;
|
|
|
|
attrs.height = 0;
|
2014-05-20 09:08:11 -04:00
|
|
|
attrs.border_width = 0;
|
|
|
|
attrs.depth = 24;
|
|
|
|
attrs.visual = NULL;
|
|
|
|
attrs.root = scr->xroot;
|
|
|
|
attrs.class = InputOutput;
|
|
|
|
attrs.bit_gravity = NorthWestGravity;
|
|
|
|
attrs.win_gravity = NorthWestGravity;
|
|
|
|
attrs.backing_store = 0;
|
|
|
|
attrs.backing_planes = ~0;
|
|
|
|
attrs.backing_pixel = 0;
|
|
|
|
attrs.save_under = 0;
|
|
|
|
attrs.colormap = 0;
|
|
|
|
attrs.map_installed = 1;
|
|
|
|
attrs.map_state = IsUnmapped;
|
|
|
|
attrs.all_event_masks = ~0;
|
|
|
|
attrs.your_event_mask = 0;
|
|
|
|
attrs.do_not_propagate_mask = 0;
|
|
|
|
attrs.override_redirect = 0;
|
|
|
|
attrs.screen = scr->xscreen;
|
|
|
|
|
|
|
|
/* XXX: Note: In the Wayland case we currently still trap X errors while
|
|
|
|
* creating a MetaWindow because we will still be making various redundant
|
|
|
|
* X requests (passing a window xid of None) until we thoroughly audit all
|
|
|
|
* the code to make sure it knows about non X based clients...
|
|
|
|
*/
|
|
|
|
meta_error_trap_push (display); /* Push a trap over all of window
|
|
|
|
* creation, to reduce XSync() calls
|
|
|
|
*/
|
|
|
|
|
|
|
|
window = _meta_window_shared_new (display,
|
|
|
|
scr,
|
|
|
|
META_WINDOW_CLIENT_TYPE_WAYLAND,
|
|
|
|
surface,
|
|
|
|
None,
|
|
|
|
WithdrawnState,
|
|
|
|
META_COMP_EFFECT_CREATE,
|
|
|
|
&attrs);
|
|
|
|
window->can_ping = TRUE;
|
|
|
|
|
|
|
|
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
|
|
|
|
|
|
|
return window;
|
|
|
|
}
|
|
|
|
|
2014-07-28 06:04:23 -04:00
|
|
|
static gboolean
|
|
|
|
should_do_pending_move (MetaWindowWayland *wl_window,
|
|
|
|
MetaWaylandSerial *acked_configure_serial)
|
|
|
|
{
|
|
|
|
if (!wl_window->has_pending_move)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (wl_window->pending_configure_serial.set)
|
|
|
|
{
|
|
|
|
/* If we're waiting for a configure and this isn't an ACK for
|
|
|
|
* any configure, then fizzle it out. */
|
|
|
|
if (!acked_configure_serial->set)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* If we're waiting for a configure and this isn't an ACK for
|
|
|
|
* the configure we're waiting for, then fizzle it out. */
|
|
|
|
if (acked_configure_serial->value != wl_window->pending_configure_serial.value)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-04-28 17:44:45 -04:00
|
|
|
/**
|
|
|
|
* meta_window_move_resize_wayland:
|
|
|
|
*
|
|
|
|
* Complete a resize operation from a wayland client.
|
|
|
|
*/
|
|
|
|
void
|
wayland-surface: Don't do pending move/resizes on all commits
We assume in meta_window_wayland_move_resize that the next commit that
changes the geometry will always be for our next pending operation, so
if we have a move pending on a resize, the next commit will trigger the
move. This is, of course, fundamentally wrong.
We broke this assumption even more now that we don't fizzle out calls to
meta_window_move_resize_internal and now call it on every commit, which
means that a simple damage and then commit would complete a pending
move.
This was even broken by apps like weston-terminal, which, when clicking
on the maximize button, first redraws the terminal with the maximize
button state back on hover on press, and would only redraw when it got
the configure event with the coordinates.
To track the correct commit to apply the move for, we implement the
ack_configure request and ignore all move/resizes that happen before
that.
Right now, we actually fizzle out the entire move/resize if there's a
future pending configure we're waiting on.
2014-07-27 11:23:17 -04:00
|
|
|
meta_window_wayland_move_resize (MetaWindow *window,
|
|
|
|
MetaWaylandSerial *acked_configure_serial,
|
|
|
|
MetaRectangle new_geom,
|
|
|
|
int dx,
|
|
|
|
int dy)
|
2014-04-28 17:44:45 -04:00
|
|
|
{
|
2014-04-28 18:15:03 -04:00
|
|
|
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
2014-05-01 19:09:13 -04:00
|
|
|
int gravity;
|
|
|
|
MetaRectangle rect;
|
2014-04-28 17:44:45 -04:00
|
|
|
MetaMoveResizeFlags flags;
|
|
|
|
|
2014-07-17 15:24:06 -04:00
|
|
|
/* XXX: Find a better place to store the window geometry offsets. */
|
2014-07-17 16:42:41 -04:00
|
|
|
window->custom_frame_extents.left = new_geom.x;
|
|
|
|
window->custom_frame_extents.top = new_geom.y;
|
2014-07-17 15:24:06 -04:00
|
|
|
|
2014-12-15 16:28:47 -05:00
|
|
|
flags = META_MOVE_RESIZE_WAYLAND_RESIZE;
|
2014-04-28 17:44:45 -04:00
|
|
|
|
2014-05-01 18:55:34 -04:00
|
|
|
/* x/y are ignored when we're doing interactive resizing */
|
2014-04-28 17:44:45 -04:00
|
|
|
if (!meta_grab_op_is_resizing (window->display->grab_op))
|
|
|
|
{
|
2014-07-28 06:04:23 -04:00
|
|
|
if (wl_window->has_pending_move && should_do_pending_move (wl_window, acked_configure_serial))
|
2014-05-01 18:55:34 -04:00
|
|
|
{
|
2014-07-27 11:37:18 -04:00
|
|
|
rect.x = wl_window->pending_move_x;
|
|
|
|
rect.y = wl_window->pending_move_y;
|
|
|
|
wl_window->has_pending_move = FALSE;
|
2014-12-15 16:28:47 -05:00
|
|
|
flags |= META_MOVE_RESIZE_MOVE_ACTION;
|
2014-05-01 18:55:34 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-14 16:45:48 -04:00
|
|
|
rect.x = window->rect.x;
|
|
|
|
rect.y = window->rect.y;
|
2014-05-01 18:55:34 -04:00
|
|
|
}
|
|
|
|
|
2014-04-28 17:44:45 -04:00
|
|
|
if (dx != 0 || dy != 0)
|
|
|
|
{
|
2014-05-01 19:09:13 -04:00
|
|
|
rect.x += dx;
|
|
|
|
rect.y += dy;
|
2014-12-15 16:28:47 -05:00
|
|
|
flags |= META_MOVE_RESIZE_MOVE_ACTION;
|
2014-04-28 17:44:45 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-28 06:04:23 -04:00
|
|
|
wl_window->pending_configure_serial.set = FALSE;
|
|
|
|
|
2014-07-17 15:24:06 -04:00
|
|
|
rect.width = new_geom.width;
|
|
|
|
rect.height = new_geom.height;
|
2014-05-01 19:09:13 -04:00
|
|
|
|
|
|
|
if (rect.width != window->rect.width || rect.height != window->rect.height)
|
2014-12-15 16:28:47 -05:00
|
|
|
flags |= META_MOVE_RESIZE_RESIZE_ACTION;
|
2014-04-28 17:44:45 -04:00
|
|
|
|
2014-05-01 19:09:13 -04:00
|
|
|
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
|
|
|
|
meta_window_move_resize_internal (window, flags, gravity, rect);
|
2014-04-28 17:44:45 -04:00
|
|
|
}
|