xwayland: Handle shell hint for client to choose dimensions

A config event with width == 0 or height == 0 from the shell is a hint
to the client to choose its own dimensions. Since X11 clients don't
support such hints we make a best guess by trying to use the last saved
dimensions or, as a fallback, the current dimensions.

This hint is mainly used by libweston/desktop shells when transitioning
to a normal state from maximized, fullscreen or after a resize [1].
Without support for this hint the aforementioned transition causes
xwayland surfaces to be configured to a 1x1 size.

To be able to use the last saved dimensions with xwayland surface, the
shell needs to first set the maximized/fullscreen state and only then
set the new size, which is currently the case for desktop-shell.
Otherwise, if the new size is set first, then the last saved dimensions
will be set to the fullscreen/maximized values and won't be useful when
restoring to a normal window size.

[1] Recently we've introduced ba82af938a87ff088b4aacff3b8ac1b6bb461be2
"desktop-shell: do not forget to reset pending config size after
resizes". As we were not handling the 0x0 size hint, resizing X
applications started to fail. This patch fixes that.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Co-authored-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
(cherry picked from commit 2acd2c74891cd0548c1ff410ccfe81952bed27b3)
dev
Alexandros Frantzis 2 years ago committed by Marius Vlad
parent d5a3ec5e58
commit 2d66d01cf5
  1. 46
      xwayland/window-manager.c

@ -2795,6 +2795,8 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
struct theme *t; struct theme *t;
int new_width, new_height; int new_width, new_height;
int vborder, hborder; int vborder, hborder;
bool use_saved_dimensions = false;
bool use_current_dimensions = false;
if (!window || !window->wm) if (!window || !window->wm)
return; return;
@ -2809,20 +2811,46 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
vborder = 0; vborder = 0;
} }
if (width > hborder) /* A config event with width == 0 or height == 0 is a hint to the client
new_width = width - hborder; * to choose its own dimensions. Since X11 clients don't support such
else * hints we make a best guess here by trying to use the last saved
new_width = 1; * dimensions or, as a fallback, the current dimensions. */
if (width == 0 || height == 0) {
if (height > vborder) use_saved_dimensions = window->saved_width > 0 &&
new_height = height - vborder; window->saved_height > 0;
else use_current_dimensions = !use_saved_dimensions &&
new_height = 1; window->width > 0 &&
window->height > 0;
}
/* The saved or current dimensions are the plain window content
* dimensions without the borders, so we can use them directly for
* new_width and new_height below. */
if (use_current_dimensions) {
new_width = window->width;
new_height = window->height;
} else if (use_saved_dimensions) {
new_width = window->saved_width;
new_height = window->saved_height;
} else {
new_width = (width > hborder) ? (width - hborder) : 1;
new_height = (height > vborder) ? (height - vborder) : 1;
}
if (window->width != new_width || window->height != new_height) { if (window->width != new_width || window->height != new_height) {
window->width = new_width; window->width = new_width;
window->height = new_height; window->height = new_height;
/* Save the toplevel size so that we can pick up a reasonable
* value when the compositor tell us to choose a size. We are
* already saving the size before going fullscreen/maximized,
* but this covers the case in which our size is changed but we
* continue on a normal state. */
if (!weston_wm_window_is_maximized(window) && !window->fullscreen) {
window->saved_width = new_width;
window->saved_height = new_height;
}
if (window->frame) { if (window->frame) {
if (weston_wm_window_is_maximized(window)) if (weston_wm_window_is_maximized(window))
frame_set_flag(window->frame, FRAME_FLAG_MAXIMIZED); frame_set_flag(window->frame, FRAME_FLAG_MAXIMIZED);

Loading…
Cancel
Save