diff --git a/src/wayland/meta-wayland-window-configuration.c b/src/wayland/meta-wayland-window-configuration.c index 702c95a62..fb8657017 100644 --- a/src/wayland/meta-wayland-window-configuration.c +++ b/src/wayland/meta-wayland-window-configuration.c @@ -21,25 +21,10 @@ #include "config.h" #include "wayland/meta-wayland-window-configuration.h" +#include "wayland/meta-window-wayland.h" static uint32_t global_serial_counter = 0; -static gboolean -is_window_size_fixed (MetaWindow *window) -{ - if (meta_window_is_fullscreen (window)) - return TRUE; - - if (meta_window_get_maximized (window) & - (META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL)) - return TRUE; - - if (meta_window_get_tile_mode (window) != META_TILE_NONE) - return TRUE; - - return FALSE; -} - MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new (MetaWindow *window, MetaRectangle rect, @@ -49,6 +34,7 @@ meta_wayland_window_configuration_new (MetaWindow *window, MetaMoveResizeFlags flags, MetaGravity gravity) { + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); MetaWaylandWindowConfiguration *configuration; configuration = g_new0 (MetaWaylandWindowConfiguration, 1); @@ -72,26 +58,24 @@ meta_wayland_window_configuration_new (MetaWindow *window, configuration->y = rect.y; } - if (flags & META_MOVE_RESIZE_RESIZE_ACTION || - is_window_size_fixed (window) || - window->rect.width != rect.width || - window->rect.height != rect.height) - { - configuration->has_size = TRUE; - configuration->width = rect.width; - configuration->height = rect.height; - } + configuration->has_size = (rect.width != 0 && rect.height != 0); + configuration->is_resizing = flags & META_MOVE_RESIZE_RESIZE_ACTION || + meta_window_wayland_is_resize (wl_window, rect.width, rect.height); + configuration->width = rect.width; + configuration->height = rect.height; return configuration; } MetaWaylandWindowConfiguration * -meta_wayland_window_configuration_new_relative (int rel_x, - int rel_y, - int width, - int height, - int scale) +meta_wayland_window_configuration_new_relative (MetaWindow *window, + int rel_x, + int rel_y, + int width, + int height, + int scale) { + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); MetaWaylandWindowConfiguration *configuration; configuration = g_new0 (MetaWaylandWindowConfiguration, 1); @@ -102,7 +86,8 @@ meta_wayland_window_configuration_new_relative (int rel_x, .rel_x = rel_x, .rel_y = rel_y, - .has_size = TRUE, + .has_size = (width != 0 && height != 0), + .is_resizing = meta_window_wayland_is_resize (wl_window, width, height), .width = width, .height = height, diff --git a/src/wayland/meta-wayland-window-configuration.h b/src/wayland/meta-wayland-window-configuration.h index c4c0f2e55..a3d184bd8 100644 --- a/src/wayland/meta-wayland-window-configuration.h +++ b/src/wayland/meta-wayland-window-configuration.h @@ -40,6 +40,7 @@ struct _MetaWaylandWindowConfiguration int rel_y; gboolean has_size; + gboolean is_resizing; int width; int height; @@ -59,11 +60,12 @@ MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new (MetaWind MetaMoveResizeFlags flags, MetaGravity gravity); -MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_relative (int rel_x, - int rel_y, - int width, - int height, - int scale); +MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_relative (MetaWindow *window, + int rel_x, + int rel_y, + int width, + int height, + int scale); MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_empty (int bounds_width, int bounds_height); diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index d0fbde843..2b389bfbf 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -321,7 +321,8 @@ meta_window_wayland_move_resize_internal (MetaWindow *window, MetaWaylandWindowConfiguration *configuration; configuration = - meta_wayland_window_configuration_new_relative (rel_x, + meta_wayland_window_configuration_new_relative (window, + rel_x, rel_y, configured_rect.width, configured_rect.height, @@ -824,9 +825,39 @@ meta_window_wayland_peek_configuration (MetaWindowWayland *wl_window, static MetaWaylandWindowConfiguration * acquire_acked_configuration (MetaWindowWayland *wl_window, - MetaWaylandSurfaceState *pending) + MetaWaylandSurfaceState *pending, + gboolean *is_client_resize) { GList *l; + gboolean has_pending_resize = FALSE; + + /* There can be 3 different cases where a resizing configurations can be found + * in the list of pending configurations. We consider resizes in any of these + * cases to be requested by the server: + * 1. Acked serial is resizing. This is obviously a server requested resize. + * 2. Acked serial is larger than the serial of a pending resizing + * configuration. This means there was a server requested resize in the + * past that has not been acked yet. This covers cases such as a resizing + * configure followed by a status change configure before the client had + * time to ack the former. + * 3. Acked serial is smaller than the serial of a pending resizing + * configuration. This means there will be a server requested resize in the + * future. In this case we want to avoid marking this as a client resize, + * because it will change in the future again anyway and considering it + * a client resize could trigger another move_resize on the server due to + * enforcing constraints based on an already outdated size. */ + for (l = wl_window->pending_configurations; l; l = l->next) + { + MetaWaylandWindowConfiguration *configuration = l->data; + + if (configuration->is_resizing) + { + has_pending_resize = TRUE; + break; + } + } + + *is_client_resize = !has_pending_resize; if (!pending->has_acked_configure_serial) return NULL; @@ -869,20 +900,30 @@ acquire_acked_configuration (MetaWindowWayland *wl_window, return NULL; } -static gboolean -has_pending_resize (MetaWindowWayland *wl_window) +gboolean +meta_window_wayland_is_resize (MetaWindowWayland *wl_window, + int width, + int height) { - GList *l; + int old_width; + int old_height; - for (l = wl_window->pending_configurations; l; l = l->next) + if (wl_window->pending_configurations) { - MetaWaylandWindowConfiguration *configuration = l->data; + old_width = wl_window->last_sent_rect.width; + old_height = wl_window->last_sent_rect.height; + } + else + { + MetaWindow *window = META_WINDOW (wl_window); - if (configuration->has_size) - return TRUE; + old_width = window->rect.width; + old_height = window->rect.height; } - return FALSE; + return !wl_window->has_last_sent_configuration || + old_width != width || + old_height != height; } int @@ -945,6 +986,7 @@ meta_window_wayland_finish_move_resize (MetaWindow *window, MetaMoveResizeFlags flags; MetaWaylandWindowConfiguration *acked_configuration; gboolean is_window_being_resized; + gboolean is_client_resize; /* new_geom is in the logical pixel coordinate space, but MetaWindow wants its * rects to represent what in turn will end up on the stage, i.e. we need to @@ -968,10 +1010,8 @@ meta_window_wayland_finish_move_resize (MetaWindow *window, flags = META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE; - if (!has_pending_resize (wl_window)) - flags |= META_MOVE_RESIZE_WAYLAND_CLIENT_RESIZE; - - acked_configuration = acquire_acked_configuration (wl_window, pending); + acked_configuration = acquire_acked_configuration (wl_window, pending, + &is_client_resize); /* x/y are ignored when we're doing interactive resizing */ is_window_being_resized = (meta_grab_op_is_resizing (display->grab_op) && @@ -1021,7 +1061,11 @@ meta_window_wayland_finish_move_resize (MetaWindow *window, } if (rect.width != window->rect.width || rect.height != window->rect.height) - flags |= META_MOVE_RESIZE_RESIZE_ACTION; + { + flags |= META_MOVE_RESIZE_RESIZE_ACTION; + if (is_client_resize) + flags |= META_MOVE_RESIZE_WAYLAND_CLIENT_RESIZE; + } if (window->display->grab_window == window) gravity = meta_resize_gravity_from_grab_op (window->display->grab_op); diff --git a/src/wayland/meta-window-wayland.h b/src/wayland/meta-window-wayland.h index db152daaa..154e9a6f2 100644 --- a/src/wayland/meta-window-wayland.h +++ b/src/wayland/meta-window-wayland.h @@ -77,4 +77,8 @@ void meta_window_wayland_get_max_size (MetaWindow *window, int *width, int *height); +gboolean meta_window_wayland_is_resize (MetaWindowWayland *wl_window, + int width, + int height); + #endif