xdg: support xdg-shell v3 with popup repositioning

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.
This commit is contained in:
John Lindgren 2024-06-27 19:17:38 -04:00 committed by Johan Malm
parent 45b197b8a4
commit a98f2635ea
4 changed files with 27 additions and 1 deletions

View 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);

View 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;
}

View 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

View file

@ -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 *