]> git.mdlowis.com Git - proto/labwc.git/commitdiff
xdg: support xdg-shell v3 with popup repositioning
authorJohn Lindgren <john@jlindgren.net>
Thu, 27 Jun 2024 23:17:38 +0000 (19:17 -0400)
committerJohan Malm <johanmalm@users.noreply.github.com>
Mon, 1 Jul 2024 19:16:31 +0000 (20:16 +0100)
See https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3514
which added support on the wlroots side.

We now re-run popup positioning (for both xdg-shell and layer-shell
popups) when the "reposition" event is received. This allows popups that
change size (such as qmpanel's applications menu) to be positioned
correctly.

xdg-shell v3 also gives the compositor some additional "hints" for popup
positioning (reactive, parent_size, and parent_configure_serial) which
are available but we don't make use of currently.

include/layers.h
src/layers.c
src/xdg-popup.c
src/xdg.c

index 7b6270ed9a249be0d5e37259b8d4b42488d36248..827c2adac9b162cfb9cb1c35591be3534312ebb9 100644 (file)
@@ -32,6 +32,7 @@ struct lab_layer_popup {
        struct wl_listener commit;
        struct wl_listener destroy;
        struct wl_listener new_popup;
+       struct wl_listener reposition;
 };
 
 void layers_init(struct server *server);
index 4a853fe3e40d9ac4913f35642031f8266799d28e..df556761b26d1103df59ace4cfd9255fd4f01a3f 100644 (file)
@@ -356,6 +356,7 @@ popup_handle_destroy(struct wl_listener *listener, void *data)
                wl_container_of(listener, popup, destroy);
        wl_list_remove(&popup->destroy.link);
        wl_list_remove(&popup->new_popup.link);
+       wl_list_remove(&popup->reposition.link);
 
        /* Usually already removed unless there was no commit at all */
        if (popup->commit.notify) {
@@ -381,6 +382,15 @@ popup_handle_commit(struct wl_listener *listener, void *data)
        }
 }
 
+static void
+popup_handle_reposition(struct wl_listener *listener, void *data)
+{
+       struct lab_layer_popup *popup =
+               wl_container_of(listener, popup, reposition);
+       wlr_xdg_popup_unconstrain_from_box(popup->wlr_popup,
+               &popup->output_toplevel_sx_box);
+}
+
 static void popup_handle_new_popup(struct wl_listener *listener, void *data);
 
 static struct lab_layer_popup *
@@ -410,6 +420,9 @@ create_popup(struct wlr_xdg_popup *wlr_popup, struct wlr_scene_tree *parent)
        popup->commit.notify = popup_handle_commit;
        wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
 
+       popup->reposition.notify = popup_handle_reposition;
+       wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
+
        return popup;
 }
 
index 0d1ed909aa32be2e396f3402a1d170c6b0eaf98d..d6bc99f0b3557bec2e04191e91bc54f134b4d52c 100644 (file)
@@ -19,6 +19,7 @@ struct xdg_popup {
        struct wl_listener commit;
        struct wl_listener destroy;
        struct wl_listener new_popup;
+       struct wl_listener reposition;
 };
 
 static void
@@ -47,6 +48,7 @@ handle_xdg_popup_destroy(struct wl_listener *listener, void *data)
        struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
        wl_list_remove(&popup->destroy.link);
        wl_list_remove(&popup->new_popup.link);
+       wl_list_remove(&popup->reposition.link);
 
        /* Usually already removed unless there was no commit at all */
        if (popup->commit.notify) {
@@ -69,6 +71,13 @@ handle_xdg_popup_commit(struct wl_listener *listener, void *data)
        }
 }
 
+static void
+handle_xdg_popup_reposition(struct wl_listener *listener, void *data)
+{
+       struct xdg_popup *popup = wl_container_of(listener, popup, reposition);
+       popup_unconstrain(popup);
+}
+
 static void
 popup_handle_new_xdg_popup(struct wl_listener *listener, void *data)
 {
@@ -100,6 +109,9 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup)
        popup->commit.notify = handle_xdg_popup_commit;
        wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
 
+       popup->reposition.notify = handle_xdg_popup_reposition;
+       wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
+
        /*
         * We must add xdg popups to the scene graph so they get rendered. The
         * wlroots scene graph provides a helper for this, but to use it we must
index 2b8bf96ec93e21ea79057aa9262a629f83bd289b..86ee06c38c8cafb914f751797b3c705261cfa10d 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -14,7 +14,7 @@
 #include "window-rules.h"
 #include "workspaces.h"
 
-#define LAB_XDG_SHELL_VERSION (2)
+#define LAB_XDG_SHELL_VERSION (3)
 #define CONFIGURE_TIMEOUT_MS 100
 
 static struct xdg_toplevel_view *