summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandros Frantzis <alexandros.frantzis@collabora.com>2023-02-27 22:30:24 -0300
committerMarius Vlad <marius.vlad@collabora.com>2023-05-16 10:50:40 +0300
commit2d66d01cf58b0b079dc70f28e144aac020710d35 (patch)
treeda175e8c693f31df4e8b129c58472957b092bd29
parentd5a3ec5e5878fc9bc473ed53f732c3e93943ec83 (diff)
downloadweston-2d66d01cf58b0b079dc70f28e144aac020710d35.tar.gz
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)
-rw-r--r--xwayland/window-manager.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 9dc30e1c..71c63caf 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -2795,6 +2795,8 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
struct theme *t;
int new_width, new_height;
int vborder, hborder;
+ bool use_saved_dimensions = false;
+ bool use_current_dimensions = false;
if (!window || !window->wm)
return;
@@ -2809,20 +2811,46 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
vborder = 0;
}
- if (width > hborder)
- new_width = width - hborder;
- else
- new_width = 1;
-
- if (height > vborder)
- new_height = height - vborder;
- else
- new_height = 1;
+ /* A config event with width == 0 or height == 0 is a hint to the client
+ * to choose its own dimensions. Since X11 clients don't support such
+ * hints we make a best guess here by trying to use the last saved
+ * 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;
+ }
+
+ /* 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) {
window->width = new_width;
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 (weston_wm_window_is_maximized(window))
frame_set_flag(window->frame, FRAME_FLAG_MAXIMIZED);