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 ba82af938a
"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>
This commit is contained in:
parent
12a7e4e163
commit
2acd2c7489
@ -2809,6 +2809,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;
|
||||||
@ -2823,20 +2825,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) {
|
||||||
|
use_saved_dimensions = window->saved_width > 0 &&
|
||||||
|
window->saved_height > 0;
|
||||||
|
use_current_dimensions = !use_saved_dimensions &&
|
||||||
|
window->width > 0 &&
|
||||||
|
window->height > 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (height > vborder)
|
/* The saved or current dimensions are the plain window content
|
||||||
new_height = height - vborder;
|
* dimensions without the borders, so we can use them directly for
|
||||||
else
|
* new_width and new_height below. */
|
||||||
new_height = 1;
|
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…
Reference in New Issue
Block a user