wayland/xdg-shell: Add toplevel bounds support

This implements the new 'bounds' event that is part of the xdg_toplevel
interface in the xdg-shell protocol. It aims to let clients create
"good" default window sizes that depends on e.g. the resolution of the
monitor the window will be mapped on, whether there are panels taking up
space, and things like that.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2167>
This commit is contained in:
Jonas Ådahl 2021-12-18 00:15:56 +01:00 committed by Marge Bot
parent f9d6bccf0c
commit fadffe3fad
10 changed files with 697 additions and 5 deletions

View File

@ -307,6 +307,7 @@ GList * meta_monitor_manager_get_logical_monitors (MetaMonitorManage
MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_from_number (MetaMonitorManager *manager,
int number);
META_EXPORT_TEST
MetaLogicalMonitor *meta_monitor_manager_get_primary_logical_monitor (MetaMonitorManager *manager);
MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_at (MetaMonitorManager *manager,

View File

@ -53,6 +53,7 @@ wayland_test_clients = [
'invalid-xdg-shell-actions',
'xdg-apply-limits',
'xdg-activation',
'xdg-toplevel-bounds',
]
foreach test : wayland_test_clients

View File

@ -0,0 +1,358 @@
/*
* Copyright (C) 2021 Red Hat Inc.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client.h>
#include "wayland-test-client-utils.h"
#include "test-driver-client-protocol.h"
#include "xdg-shell-client-protocol.h"
typedef enum _State
{
STATE_INIT = 0,
STATE_WAIT_FOR_CONFIGURE_1,
STATE_WAIT_FOR_FRAME_1,
} State;
static struct wl_display *display;
static struct wl_registry *registry;
static struct wl_compositor *compositor;
static struct xdg_wm_base *xdg_wm_base;
static struct wl_shm *shm;
static struct test_driver *test_driver;
static struct wl_surface *surface;
static struct xdg_surface *xdg_surface;
static struct xdg_toplevel *xdg_toplevel;
static struct wl_callback *frame_callback;
static gboolean running;
static State state;
static int32_t pending_bounds_width;
static int32_t pending_bounds_height;
static void
init_surface (void)
{
xdg_toplevel_set_title (xdg_toplevel, "toplevel-bounds-test");
wl_surface_commit (surface);
}
static void
handle_buffer_release (void *data,
struct wl_buffer *buffer)
{
wl_buffer_destroy (buffer);
}
static const struct wl_buffer_listener buffer_listener = {
handle_buffer_release
};
static gboolean
create_shm_buffer (int width,
int height,
struct wl_buffer **out_buffer,
void **out_data,
int *out_size)
{
struct wl_shm_pool *pool;
static struct wl_buffer *buffer;
int fd, size, stride;
int bytes_per_pixel;
void *data;
bytes_per_pixel = 4;
stride = width * bytes_per_pixel;
size = stride * height;
fd = create_anonymous_file (size);
if (fd < 0)
{
fprintf (stderr, "Creating a buffer file for %d B failed: %m\n",
size);
return FALSE;
}
data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED)
{
fprintf (stderr, "mmap failed: %m\n");
close (fd);
return FALSE;
}
pool = wl_shm_create_pool (shm, fd, size);
buffer = wl_shm_pool_create_buffer (pool, 0,
width, height,
stride,
WL_SHM_FORMAT_ARGB8888);
wl_buffer_add_listener (buffer, &buffer_listener, buffer);
wl_shm_pool_destroy (pool);
close (fd);
*out_buffer = buffer;
*out_data = data;
*out_size = size;
return TRUE;
}
static void
fill (void *buffer_data,
int width,
int height,
uint32_t color)
{
uint32_t *pixels = buffer_data;
int x, y;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
pixels[y * width + x] = color;
}
}
static void
draw (struct wl_surface *surface,
int width,
int height,
uint32_t color)
{
struct wl_buffer *buffer;
void *buffer_data;
int size;
if (!create_shm_buffer (width, height,
&buffer, &buffer_data, &size))
g_error ("Failed to create shm buffer");
fill (buffer_data, width, height, color);
wl_surface_attach (surface, buffer, 0, 0);
}
static void
draw_main (int width,
int height)
{
draw (surface, width, height, 0xff00ff00);
}
static void
handle_xdg_toplevel_configure (void *data,
struct xdg_toplevel *xdg_toplevel,
int32_t width,
int32_t height,
struct wl_array *state)
{
}
static void
handle_xdg_toplevel_close(void *data,
struct xdg_toplevel *xdg_toplevel)
{
g_assert_not_reached ();
}
static void
handle_xdg_toplevel_configure_bounds (void *data,
struct xdg_toplevel *xdg_toplevel,
int32_t bounds_width,
int32_t bounds_height)
{
pending_bounds_width = bounds_width;
pending_bounds_height = bounds_height;
}
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
handle_xdg_toplevel_configure,
handle_xdg_toplevel_close,
handle_xdg_toplevel_configure_bounds,
};
static void
handle_frame_callback (void *data,
struct wl_callback *callback,
uint32_t time)
{
switch (state)
{
case STATE_WAIT_FOR_FRAME_1:
test_driver_sync_point (test_driver, 1, NULL);
break;
case STATE_INIT:
case STATE_WAIT_FOR_CONFIGURE_1:
g_assert_not_reached ();
}
}
static const struct wl_callback_listener frame_listener = {
handle_frame_callback,
};
static void
handle_xdg_surface_configure (void *data,
struct xdg_surface *xdg_surface,
uint32_t serial)
{
switch (state)
{
case STATE_INIT:
g_assert_not_reached ();
case STATE_WAIT_FOR_CONFIGURE_1:
g_assert (pending_bounds_width > 0);
g_assert (pending_bounds_height > 0);
draw_main (pending_bounds_width - 10,
pending_bounds_height - 10);
state = STATE_WAIT_FOR_FRAME_1;
break;
case STATE_WAIT_FOR_FRAME_1:
break;
}
xdg_surface_ack_configure (xdg_surface, serial);
frame_callback = wl_surface_frame (surface);
wl_callback_add_listener (frame_callback, &frame_listener, NULL);
wl_surface_commit (surface);
wl_display_flush (display);
}
static const struct xdg_surface_listener xdg_surface_listener = {
handle_xdg_surface_configure,
};
static void
handle_xdg_wm_base_ping (void *data,
struct xdg_wm_base *xdg_wm_base,
uint32_t serial)
{
xdg_wm_base_pong (xdg_wm_base, serial);
}
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
handle_xdg_wm_base_ping,
};
static void
test_driver_handle_sync_event (void *data,
struct test_driver *test_driver,
uint32_t serial)
{
g_assert (serial == 0);
exit (EXIT_SUCCESS);
}
static const struct test_driver_listener test_driver_listener = {
test_driver_handle_sync_event,
};
static void
handle_registry_global (void *data,
struct wl_registry *registry,
uint32_t id,
const char *interface,
uint32_t version)
{
if (strcmp (interface, "wl_compositor") == 0)
{
compositor = wl_registry_bind (registry, id, &wl_compositor_interface, 1);
}
else if (strcmp (interface, "xdg_wm_base") == 0)
{
xdg_wm_base = wl_registry_bind (registry, id,
&xdg_wm_base_interface, 4);
xdg_wm_base_add_listener (xdg_wm_base, &xdg_wm_base_listener, NULL);
}
else if (strcmp (interface, "wl_shm") == 0)
{
shm = wl_registry_bind (registry,
id, &wl_shm_interface, 1);
}
else if (strcmp (interface, "test_driver") == 0)
{
test_driver = wl_registry_bind (registry, id, &test_driver_interface, 1);
test_driver_add_listener (test_driver, &test_driver_listener, NULL);
}
}
static void
handle_registry_global_remove (void *data,
struct wl_registry *registry,
uint32_t name)
{
}
static const struct wl_registry_listener registry_listener = {
handle_registry_global,
handle_registry_global_remove
};
int
main (int argc,
char **argv)
{
display = wl_display_connect (NULL);
registry = wl_display_get_registry (display);
wl_registry_add_listener (registry, &registry_listener, NULL);
wl_display_roundtrip (display);
if (!shm)
{
fprintf (stderr, "No wl_shm global\n");
return EXIT_FAILURE;
}
if (!xdg_wm_base)
{
fprintf (stderr, "No xdg_wm_base global\n");
return EXIT_FAILURE;
}
wl_display_roundtrip (display);
surface = wl_compositor_create_surface (compositor);
xdg_surface = xdg_wm_base_get_xdg_surface (xdg_wm_base, surface);
xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL);
xdg_toplevel = xdg_surface_get_toplevel (xdg_surface);
xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL);
init_surface ();
state = STATE_WAIT_FOR_CONFIGURE_1;
wl_surface_commit (surface);
running = TRUE;
while (running)
{
if (wl_display_dispatch (display) == -1)
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -25,6 +25,8 @@
#include "core/window-private.h"
#include "meta-test/meta-context-test.h"
#include "tests/meta-test-utils.h"
#include "meta/meta-later.h"
#include "meta/meta-workspace-manager.h"
#include "tests/meta-wayland-test-driver.h"
#include "tests/meta-wayland-test-utils.h"
#include "wayland/meta-wayland-surface.h"
@ -363,6 +365,276 @@ toplevel_activation (void)
meta_wayland_test_client_finish (data.wayland_test_client);
}
static void
on_sync_point (MetaWaylandTestDriver *test_driver,
unsigned int sequence,
struct wl_resource *surface_resource,
struct wl_client *wl_client,
unsigned int *latest_sequence)
{
*latest_sequence = sequence;
}
static void
wait_for_sync_point (unsigned int sync_point)
{
gulong handler_id;
unsigned int latest_sequence = 0;
handler_id = g_signal_connect (test_driver, "sync-point",
G_CALLBACK (on_sync_point),
&latest_sequence);
while (latest_sequence != sync_point)
g_main_context_iteration (NULL, TRUE);
g_signal_handler_disconnect (test_driver, handler_id);
}
static gboolean
mark_later_as_done (gpointer user_data)
{
gboolean *done = user_data;
*done = TRUE;
return G_SOURCE_REMOVE;
}
static void
wait_until_after_paint (void)
{
MetaDisplay *display = meta_context_get_display (test_context);
MetaCompositor *compositor = meta_display_get_compositor (display);
MetaLaters *laters = meta_compositor_get_laters (compositor);
gboolean done;
done = FALSE;
meta_laters_add (laters,
META_LATER_BEFORE_REDRAW,
mark_later_as_done,
&done,
NULL);
while (!done)
g_main_context_iteration (NULL, FALSE);
done = FALSE;
meta_laters_add (laters,
META_LATER_IDLE,
mark_later_as_done,
&done,
NULL);
while (!done)
g_main_context_iteration (NULL, FALSE);
}
static void
set_struts (MetaRectangle rect,
MetaSide side)
{
MetaDisplay *display = meta_context_get_display (test_context);
MetaWorkspaceManager *workspace_manager =
meta_display_get_workspace_manager (display);
GList *workspaces =
meta_workspace_manager_get_workspaces (workspace_manager);
MetaStrut strut;
g_autoptr (GSList) struts = NULL;
GList *l;
strut = (MetaStrut) { .rect = rect, .side = side };
struts = g_slist_append (NULL, &strut);
for (l = workspaces; l; l = l->next)
{
MetaWorkspace *workspace = l->data;
meta_workspace_set_builtin_struts (workspace, struts);
}
}
static void
clear_struts (void)
{
MetaDisplay *display = meta_context_get_display (test_context);
MetaWorkspaceManager *workspace_manager =
meta_display_get_workspace_manager (display);
GList *workspaces =
meta_workspace_manager_get_workspaces (workspace_manager);
GList *l;
for (l = workspaces; l; l = l->next)
{
MetaWorkspace *workspace = l->data;
meta_workspace_set_builtin_struts (workspace, NULL);
}
}
static MetaRectangle
get_primary_logical_monitor_layout (void)
{
MetaBackend *backend = meta_context_get_backend (test_context);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor;
logical_monitor =
meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
return meta_logical_monitor_get_layout (logical_monitor);
}
static void
toplevel_bounds_struts (void)
{
MetaWaylandTestClient *wayland_test_client;
MetaWindow *window;
MetaRectangle logical_monitor_layout;
MetaRectangle work_area;
/*
* This test case makes sure that setting and changing struts result in the
* right bounds are sent.
*/
logical_monitor_layout = get_primary_logical_monitor_layout ();
set_struts ((MetaRectangle) {
.x = 0,
.y = 0,
.width = logical_monitor_layout.width,
.height = 10,
},
META_SIDE_TOP);
wayland_test_client = meta_wayland_test_client_new ("xdg-toplevel-bounds");
wait_for_sync_point (1);
wait_until_after_paint ();
window = find_client_window ("toplevel-bounds-test");
g_assert_nonnull (window->monitor);
meta_window_get_work_area_current_monitor (window, &work_area);
g_assert_cmpint (work_area.width, ==, logical_monitor_layout.width);
g_assert_cmpint (work_area.height, ==, logical_monitor_layout.height - 10);
g_assert_cmpint (window->rect.width, ==, work_area.width - 10);
g_assert_cmpint (window->rect.height, ==, work_area.height - 10);
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
meta_wayland_test_client_finish (wayland_test_client);
clear_struts ();
wayland_test_client = meta_wayland_test_client_new ("xdg-toplevel-bounds");
wait_for_sync_point (1);
wait_until_after_paint ();
window = find_client_window ("toplevel-bounds-test");
g_assert_nonnull (window->monitor);
meta_window_get_work_area_current_monitor (window, &work_area);
g_assert_cmpint (work_area.width, ==, logical_monitor_layout.width);
g_assert_cmpint (work_area.height, ==, logical_monitor_layout.height);
g_assert_cmpint (window->rect.width, ==, work_area.width - 10);
g_assert_cmpint (window->rect.height, ==, work_area.height - 10);
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
meta_wayland_test_client_finish (wayland_test_client);
}
static void
wait_for_cursor_position (float x,
float y)
{
MetaBackend *backend = meta_context_get_backend (test_context);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
graphene_point_t point;
while (TRUE)
{
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
if (G_APPROX_VALUE (x, point.x, FLT_EPSILON) &&
G_APPROX_VALUE (y, point.y, FLT_EPSILON))
break;
g_main_context_iteration (NULL, TRUE);
}
}
static void
toplevel_bounds_monitors (void)
{
MetaBackend *backend = meta_context_get_backend (test_context);
ClutterSeat *seat;
g_autoptr (MetaVirtualMonitor) second_virtual_monitor = NULL;
MetaWaylandTestClient *wayland_test_client;
MetaRectangle logical_monitor_layout;
MetaRectangle work_area;
MetaWindow *window;
/*
* This test case creates two monitors, with different sizes, with a fake
* panel on top of the primary monitor. It then makes sure launching on both
* monitors results in the correct bounds.
*/
seat = meta_backend_get_default_seat (backend);
virtual_pointer = clutter_seat_create_virtual_device (seat,
CLUTTER_POINTER_DEVICE);
second_virtual_monitor = meta_create_test_monitor (test_context,
300, 200, 60.0);
logical_monitor_layout = get_primary_logical_monitor_layout ();
set_struts ((MetaRectangle) {
.x = 0,
.y = 0,
.width = logical_monitor_layout.width,
.height = 10,
},
META_SIDE_TOP);
wayland_test_client = meta_wayland_test_client_new ("xdg-toplevel-bounds");
wait_for_sync_point (1);
wait_until_after_paint ();
window = find_client_window ("toplevel-bounds-test");
g_assert_nonnull (window->monitor);
meta_window_get_work_area_current_monitor (window, &work_area);
g_assert_cmpint (work_area.width, ==, logical_monitor_layout.width);
g_assert_cmpint (work_area.height, ==, logical_monitor_layout.height - 10);
g_assert_cmpint (window->rect.width, ==, work_area.width - 10);
g_assert_cmpint (window->rect.height, ==, work_area.height - 10);
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
meta_wayland_test_client_finish (wayland_test_client);
clutter_virtual_input_device_notify_absolute_motion (virtual_pointer,
CLUTTER_CURRENT_TIME,
550.0, 100.0);
wait_for_cursor_position (550.0, 100.0);
wayland_test_client = meta_wayland_test_client_new ("xdg-toplevel-bounds");
wait_for_sync_point (1);
wait_until_after_paint ();
window = find_client_window ("toplevel-bounds-test");
g_assert_nonnull (window->monitor);
meta_window_get_work_area_current_monitor (window, &work_area);
g_assert_cmpint (work_area.width, ==, 300);
g_assert_cmpint (work_area.height, ==, 200);
g_assert_cmpint (window->rect.width, ==, 300 - 10);
g_assert_cmpint (window->rect.height, ==, 200 - 10);
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
meta_wayland_test_client_finish (wayland_test_client);
}
static void
on_before_tests (void)
{
@ -398,6 +670,10 @@ init_tests (void)
toplevel_apply_limits);
g_test_add_func ("/wayland/toplevel/activation",
toplevel_activation);
g_test_add_func ("/wayland/toplevel/bounds/struts",
toplevel_bounds_struts);
g_test_add_func ("/wayland/toplevel/bounds/monitors",
toplevel_bounds_monitors);
}
int

View File

@ -685,7 +685,7 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
{
MetaWaylandWindowConfiguration *configuration;
configuration = meta_wayland_window_configuration_new_empty ();
configuration = meta_wayland_window_configuration_new_empty (0, 0);
meta_wayland_zxdg_toplevel_v6_send_configure (xdg_toplevel,
configuration);
meta_wayland_window_configuration_free (configuration);

View File

@ -37,7 +37,7 @@
/* Global/master objects (version exported by wl_registry and negotiated through bind) */
#define META_WL_COMPOSITOR_VERSION 4
#define META_WL_DATA_DEVICE_MANAGER_VERSION 3
#define META_XDG_WM_BASE_VERSION 3
#define META_XDG_WM_BASE_VERSION 4
#define META_ZXDG_SHELL_V6_VERSION 1
#define META_WL_SEAT_VERSION 5
#define META_WL_OUTPUT_VERSION 2

View File

@ -43,6 +43,8 @@ is_window_size_fixed (MetaWindow *window)
MetaWaylandWindowConfiguration *
meta_wayland_window_configuration_new (MetaWindow *window,
MetaRectangle rect,
int bounds_width,
int bounds_height,
int scale,
MetaMoveResizeFlags flags,
MetaGravity gravity)
@ -53,6 +55,9 @@ meta_wayland_window_configuration_new (MetaWindow *window,
*configuration = (MetaWaylandWindowConfiguration) {
.serial = ++global_serial_counter,
.bounds_width = bounds_width,
.bounds_height = bounds_height,
.scale = scale,
.gravity = gravity,
.flags = flags,
@ -108,7 +113,8 @@ meta_wayland_window_configuration_new_relative (int rel_x,
}
MetaWaylandWindowConfiguration *
meta_wayland_window_configuration_new_empty (void)
meta_wayland_window_configuration_new_empty (int bounds_width,
int bounds_height)
{
MetaWaylandWindowConfiguration *configuration;
@ -116,6 +122,8 @@ meta_wayland_window_configuration_new_empty (void)
*configuration = (MetaWaylandWindowConfiguration) {
.serial = ++global_serial_counter,
.scale = 1,
.bounds_width = bounds_width,
.bounds_height = bounds_height,
};
return configuration;

View File

@ -46,10 +46,15 @@ struct _MetaWaylandWindowConfiguration
int scale;
MetaGravity gravity;
MetaMoveResizeFlags flags;
int bounds_width;
int bounds_height;
};
MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new (MetaWindow *window,
MetaRectangle rect,
int max_width,
int max_height,
int scale,
MetaMoveResizeFlags flags,
MetaGravity gravity);
@ -60,7 +65,8 @@ MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_relative
int height,
int scale);
MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_empty (void);
MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_empty (int bounds_width,
int bounds_height);
void meta_wayland_window_configuration_free (MetaWaylandWindowConfiguration *configuration);

View File

@ -700,6 +700,18 @@ meta_wayland_xdg_toplevel_send_configure (MetaWaylandXdgToplevel *xdg_to
wl_array_init (&states);
fill_states (xdg_toplevel, &states);
if (wl_resource_get_version (xdg_toplevel->resource) >=
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION &&
configuration->bounds_width > 0 &&
configuration->bounds_height > 0)
{
xdg_toplevel_send_configure_bounds (xdg_toplevel->resource,
(configuration->bounds_width /
configuration->scale),
(configuration->bounds_height /
configuration->scale));
}
xdg_toplevel_send_configure (xdg_toplevel->resource,
configuration->width / configuration->scale,
configuration->height / configuration->scale,
@ -777,8 +789,18 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
if (!xdg_surface_priv->configure_sent)
{
MetaWaylandWindowConfiguration *configuration;
int bounds_width;
int bounds_height;
configuration = meta_wayland_window_configuration_new_empty ();
if (!meta_window_calculate_bounds (window, &bounds_width, &bounds_height))
{
bounds_width = 0;
bounds_height = 0;
}
configuration =
meta_wayland_window_configuration_new_empty (bounds_width,
bounds_height);
meta_wayland_xdg_toplevel_send_configure (xdg_toplevel, configuration);
meta_wayland_window_configuration_free (configuration);
return;

View File

@ -181,6 +181,8 @@ surface_state_changed (MetaWindow *window)
{
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
MetaWaylandWindowConfiguration *configuration;
int bounds_width;
int bounds_height;
/* don't send notify when the window is being unmanaged */
if (window->unmanaging)
@ -188,9 +190,16 @@ surface_state_changed (MetaWindow *window)
g_return_if_fail (wl_window->has_last_sent_configuration);
if (!meta_window_calculate_bounds (window, &bounds_width, &bounds_height))
{
bounds_width = 0;
bounds_height = 0;
}
configuration =
meta_wayland_window_configuration_new (window,
wl_window->last_sent_rect,
bounds_width, bounds_height,
wl_window->last_sent_geometry_scale,
META_MOVE_RESIZE_STATE_CHANGED,
wl_window->last_sent_gravity);
@ -345,6 +354,8 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
flags & META_MOVE_RESIZE_STATE_CHANGED)
{
MetaWaylandWindowConfiguration *configuration;
int bounds_width;
int bounds_height;
if (!meta_wayland_surface_get_buffer (window->surface) &&
!META_WINDOW_MAXIMIZED (window) &&
@ -352,9 +363,18 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
!meta_window_is_fullscreen (window))
return;
if (!meta_window_calculate_bounds (window,
&bounds_width,
&bounds_height))
{
bounds_width = 0;
bounds_height = 0;
}
configuration =
meta_wayland_window_configuration_new (window,
configured_rect,
bounds_width, bounds_height,
geometry_scale,
flags,
gravity);