From 452f45cd3d6695299d8014c271db094da11fad05 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Tue, 1 Oct 2024 10:16:29 -0400 Subject: [PATCH] xdg: try to handle slow un-maximize with empty natural geometry better In the case of an initially-maximized view which is taking a long time to un-maximize (seen for example with Thunderbird on slow machines), we may end up in handle_configure_timeout() with an empty pending geometry. In that case we have no great options (we can't center the view since we don't know the un-maximized size yet), so set a fallback position. v2: check wlr_box_empty() before comparing pending and current Fixes: #2191 --- include/view.h | 10 ++++++++++ src/view.c | 10 ++-------- src/xdg.c | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/include/view.h b/include/view.h index 296b4845..7a1b5dde 100644 --- a/include/view.h +++ b/include/view.h @@ -13,6 +13,16 @@ #define LAB_MIN_VIEW_HEIGHT 60 +/* + * Fallback view geometry used in some cases where a better position + * and/or size can't be determined. Try to avoid using these except as + * a last resort. + */ +#define VIEW_FALLBACK_X 100 +#define VIEW_FALLBACK_Y 100 +#define VIEW_FALLBACK_WIDTH 640 +#define VIEW_FALLBACK_HEIGHT 480 + /* * In labwc, a view is a container for surfaces which can be moved around by * the user. In practice this means XDG toplevel and XWayland windows. diff --git a/src/view.c b/src/view.c index 00618a18..c1b8bfca 100644 --- a/src/view.c +++ b/src/view.c @@ -29,9 +29,6 @@ #include #endif -#define LAB_FALLBACK_WIDTH 640 -#define LAB_FALLBACK_HEIGHT 480 - struct view * view_from_wlr_surface(struct wlr_surface *surface) { @@ -827,8 +824,8 @@ adjust_floating_geometry(struct view *view, struct wlr_box *geometry, void view_set_fallback_natural_geometry(struct view *view) { - view->natural_geometry.width = LAB_FALLBACK_WIDTH; - view->natural_geometry.height = LAB_FALLBACK_HEIGHT; + view->natural_geometry.width = VIEW_FALLBACK_WIDTH; + view->natural_geometry.height = VIEW_FALLBACK_HEIGHT; view_compute_centered_position(view, NULL, view->natural_geometry.width, view->natural_geometry.height, @@ -836,9 +833,6 @@ view_set_fallback_natural_geometry(struct view *view) &view->natural_geometry.y); } -#undef LAB_FALLBACK_WIDTH -#undef LAB_FALLBACK_HEIGHT - void view_store_natural_geometry(struct view *view) { diff --git a/src/xdg.c b/src/xdg.c index 92a99fdc..f8939ddd 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -251,16 +251,35 @@ handle_configure_timeout(void *data) view->pending_configure_serial = 0; view->pending_configure_timeout = NULL; - /* - * We do not use view_impl_apply_geometry() here since in the timeout - * case we prefer to always put the top-left corner of the view at the - * desired position rather than anchoring some other edge or corner - */ - bool moved = view->current.x != view->pending.x - || view->current.y != view->pending.y; - view->current.x = view->pending.x; - view->current.y = view->pending.y; - if (moved) { + bool empty_pending = wlr_box_empty(&view->pending); + if (empty_pending || view->pending.x != view->current.x + || view->pending.y != view->current.y) { + /* + * This is a pending move + resize and the client is + * taking too long to respond to the resize. Apply the + * move now (while keeping the current size) so that the + * desktop doesn't appear unresponsive. + * + * We do not use view_impl_apply_geometry() here since + * in this case we prefer to always put the top-left + * corner of the view at the desired position rather + * than anchoring some other edge or corner. + * + * Corner case: we may get here with an empty pending + * geometry in the case of an initially-maximized view + * which is taking a long time to un-maximize (seen for + * example with Thunderbird on slow machines). In that + * case we have no great options (we can't center the + * view since we don't know the un-maximized size yet), + * so set a fallback position. + */ + if (empty_pending) { + wlr_log(WLR_INFO, "using fallback position"); + view->pending.x = VIEW_FALLBACK_X; + view->pending.y = VIEW_FALLBACK_Y; + } + view->current.x = view->pending.x; + view->current.y = view->pending.y; view_moved(view); }