diff options
author | Kirill Primak <vyivel@eclair.cafe> | 2022-04-13 20:40:23 +0300 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2022-05-27 13:31:30 +0000 |
commit | 1761c3bbe22134644f79d07d62acaa8e288049da (patch) | |
tree | 00ca8c86f2c5c09361e767fd60c8fac2862f3547 | |
parent | 8a0835c59c5569d6e0d24b5d246cce069262ad3c (diff) |
xdg-popup: add reposition support
-rw-r--r-- | include/wlr/types/wlr_xdg_shell.h | 7 | ||||
-rw-r--r-- | types/xdg_shell/wlr_xdg_popup.c | 33 |
2 files changed, 39 insertions, 1 deletions
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 687883e9..04463d2c 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -86,6 +86,9 @@ struct wlr_xdg_popup_state { struct wlr_xdg_popup_configure { struct wlr_box geometry; struct wlr_xdg_positioner_rules rules; + + bool has_reposition_token; + uint32_t reposition_token; }; struct wlr_xdg_popup { @@ -101,6 +104,10 @@ struct wlr_xdg_popup { struct wlr_xdg_popup_state current, pending; + struct { + struct wl_signal reposition; + } events; + struct wl_list grab_link; // wlr_xdg_popup_grab.popups }; diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index eb405d96..5f8cd454 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -21,6 +21,12 @@ struct wlr_xdg_popup_configure *send_xdg_popup_configure( } *configure = popup->scheduled; + if (popup->scheduled.has_reposition_token) { + popup->scheduled.has_reposition_token = false; + xdg_popup_send_repositioned(popup->resource, + popup->scheduled.reposition_token); + } + struct wlr_box *geometry = &configure->geometry; xdg_popup_send_configure(popup->resource, geometry->x, geometry->y, @@ -295,6 +301,28 @@ static void xdg_popup_handle_grab(struct wl_client *client, &popup_grab->touch_grab); } +static void xdg_popup_handle_reposition( + struct wl_client *client, struct wl_resource *resource, + struct wl_resource *positioner_resource, uint32_t token) { + struct wlr_xdg_popup *popup = + wlr_xdg_popup_from_resource(resource); + if (!popup) { + return; + } + + struct wlr_xdg_positioner *positioner = + wlr_xdg_positioner_from_resource(positioner_resource); + wlr_xdg_positioner_rules_get_geometry( + &positioner->rules, &popup->scheduled.geometry); + popup->scheduled.rules = positioner->rules; + popup->scheduled.has_reposition_token = true; + popup->scheduled.reposition_token = token; + + wlr_xdg_surface_schedule_configure(popup->base); + + wlr_signal_emit_safe(&popup->events.reposition, NULL); +} + static void xdg_popup_handle_destroy(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_popup *popup = @@ -313,6 +341,7 @@ static void xdg_popup_handle_destroy(struct wl_client *client, static const struct xdg_popup_interface xdg_popup_implementation = { .destroy = xdg_popup_handle_destroy, .grab = xdg_popup_handle_grab, + .reposition = xdg_popup_handle_reposition, }; static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) { @@ -380,6 +409,8 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, &positioner->rules, &surface->popup->scheduled.geometry); surface->popup->scheduled.rules = positioner->rules; + wl_signal_init(&surface->popup->events.reposition); + if (parent) { surface->popup->parent = parent->surface; wl_list_insert(&parent->popups, &surface->popup->link); @@ -407,7 +438,7 @@ void unmap_xdg_popup(struct wlr_xdg_popup *popup) { if (grab->seat->touch_state.grab == &grab->touch_grab) { wlr_seat_touch_end_grab(grab->seat); } - + destroy_xdg_popup_grab(grab); } |