]> git.mdlowis.com Git - proto/labwc.git/commitdiff
xdg: Detect pending configure request timeouts
authorJohn Lindgren <john@jlindgren.net>
Tue, 28 Feb 2023 16:30:42 +0000 (11:30 -0500)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sun, 5 Mar 2023 08:46:55 +0000 (08:46 +0000)
include/view.h
src/xdg.c

index aaff7fbe54b48fe9befd2f6309c215d9c8a320d5..c0732a8a1402274991a889f47b2db9feb53e9914 100644 (file)
@@ -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;
 
index cadf9d336c8f99169befd8d419682bef18c27815..086af390a5452c32ae2fe6dba38f009bc977ed0d 100644 (file)
--- 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