From ea09fc385000d0590baf97a2a5e2da1fbc037edc Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Tue, 28 Feb 2023 11:30:42 -0500 Subject: [PATCH] xdg: Detect pending configure request timeouts --- include/view.h | 1 + src/xdg.c | 53 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/include/view.h b/include/view.h index aaff7fbe..c0732a8a 100644 --- a/include/view.h +++ b/include/view.h @@ -95,6 +95,7 @@ struct view { /* used by xdg-shell views */ uint32_t pending_configure_serial; + struct wl_event_source *pending_configure_timeout; struct ssd *ssd; diff --git a/src/xdg.c b/src/xdg.c index cadf9d33..086af390 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -7,6 +7,8 @@ #include "view-impl-common.h" #include "workspaces.h" +#define CONFIGURE_TIMEOUT_MS 100 + static struct xdg_toplevel_view * xdg_toplevel_view_from_view(struct view *view) { @@ -78,17 +80,53 @@ handle_commit(struct wl_listener *listener, void *data) || current->height != size.height; uint32_t serial = view->pending_configure_serial; - if (serial > 0 && serial >= xdg_surface->current.configure_serial) { + if (serial > 0 && serial == xdg_surface->current.configure_serial) { + assert(view->pending_configure_timeout); + wl_event_source_remove(view->pending_configure_timeout); + view->pending_configure_serial = 0; + view->pending_configure_timeout = NULL; update_required = true; - if (serial == xdg_surface->current.configure_serial) { - view->pending_configure_serial = 0; - } } + if (update_required) { view_impl_apply_geometry(view, size.width, size.height); } } +static int +handle_configure_timeout(void *data) +{ + struct view *view = data; + assert(view->pending_configure_serial > 0); + assert(view->pending_configure_timeout); + + const char *app_id = view_get_string_prop(view, "app_id"); + wlr_log(WLR_ERROR, "client (%s) did not respond to configure request " + "in %d ms", app_id, CONFIGURE_TIMEOUT_MS); + + wl_event_source_remove(view->pending_configure_timeout); + view->pending_configure_serial = 0; + view->pending_configure_timeout = NULL; + + view_impl_apply_geometry(view, view->current.width, + view->current.height); + + return 0; /* ignored per wl_event_loop docs */ +} + +static void +set_pending_configure_serial(struct view *view, uint32_t serial) +{ + view->pending_configure_serial = serial; + if (!view->pending_configure_timeout) { + view->pending_configure_timeout = + wl_event_loop_add_timer(view->server->wl_event_loop, + handle_configure_timeout, view); + } + wl_event_source_timer_update(view->pending_configure_timeout, + CONFIGURE_TIMEOUT_MS); +} + static void handle_map(struct wl_listener *listener, void *data) { @@ -118,6 +156,11 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&xdg_toplevel_view->set_app_id.link); wl_list_remove(&xdg_toplevel_view->new_popup.link); + if (view->pending_configure_timeout) { + wl_event_source_remove(view->pending_configure_timeout); + view->pending_configure_timeout = NULL; + } + view_destroy(view); } @@ -231,7 +274,7 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo) view->pending = geo; if (serial > 0) { - view->pending_configure_serial = serial; + set_pending_configure_serial(view, serial); } else if (view->pending_configure_serial == 0) { /* * We can't assume here that view->current is equal to