From 6f1fce9cb450e22b6312369392d8835667825171 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Wed, 13 Apr 2022 20:22:14 +0300 Subject: [PATCH] xdg-popup: use current/pending state pattern --- include/wlr/types/wlr_xdg_shell.h | 10 +++++++--- types/scene/xdg_shell.c | 2 +- types/wlr_layer_shell_v1.c | 32 +++++++++++++++---------------- types/xdg_shell/wlr_xdg_popup.c | 9 ++++++--- types/xdg_shell/wlr_xdg_surface.c | 4 ++-- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 19378c16..bfb475fb 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -70,6 +70,12 @@ struct wlr_xdg_positioner { struct wlr_xdg_positioner_rules rules; }; +struct wlr_xdg_popup_state { + // Position of the popup relative to the upper left corner of + // the window geometry of the parent surface + struct wlr_box geometry; +}; + struct wlr_xdg_popup_configure { struct wlr_box geometry; struct wlr_xdg_positioner_rules rules; @@ -86,9 +92,7 @@ struct wlr_xdg_popup { struct wlr_xdg_popup_configure scheduled; - // Position of the popup relative to the upper left corner of the window - // geometry of the parent surface - struct wlr_box geometry; + struct wlr_xdg_popup_state current, pending; struct wl_list grab_link; // wlr_xdg_popup_grab.popups }; diff --git a/types/scene/xdg_shell.c b/types/scene/xdg_shell.c index 9b3ad71c..909719d1 100644 --- a/types/scene/xdg_shell.c +++ b/types/scene/xdg_shell.c @@ -60,7 +60,7 @@ static void scene_xdg_surface_update_position( if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { struct wlr_xdg_popup *popup = xdg_surface->popup; wlr_scene_node_set_position(&scene_xdg_surface->tree->node, - popup->geometry.x, popup->geometry.y); + popup->current.geometry.x, popup->current.geometry.y); } } diff --git a/types/wlr_layer_shell_v1.c b/types/wlr_layer_shell_v1.c index 107dac63..038ea1d8 100644 --- a/types/wlr_layer_shell_v1.c +++ b/types/wlr_layer_shell_v1.c @@ -552,16 +552,15 @@ void wlr_layer_surface_v1_for_each_surface(struct wlr_layer_surface_v1 *surface, void wlr_layer_surface_v1_for_each_popup_surface(struct wlr_layer_surface_v1 *surface, wlr_surface_iterator_func_t iterator, void *user_data){ - struct wlr_xdg_popup *popup_state; - wl_list_for_each(popup_state, &surface->popups, link) { - struct wlr_xdg_surface *popup = popup_state->base; - if (!popup->configured || !popup->mapped) { + struct wlr_xdg_popup *popup; + wl_list_for_each(popup, &surface->popups, link) { + if (!popup->base->configured || !popup->base->mapped) { continue; } double popup_sx, popup_sy; - popup_sx = popup->popup->geometry.x - popup->current.geometry.x; - popup_sy = popup->popup->geometry.y - popup->current.geometry.y; + popup_sx = popup->current.geometry.x - popup->base->current.geometry.x; + popup_sy = popup->current.geometry.y - popup->base->current.geometry.y; struct layer_surface_iterator_data data = { .user_iterator = iterator, @@ -569,7 +568,8 @@ void wlr_layer_surface_v1_for_each_popup_surface(struct wlr_layer_surface_v1 *su .x = popup_sx, .y = popup_sy, }; - wlr_xdg_surface_for_each_surface(popup, layer_surface_iterator, &data); + wlr_xdg_surface_for_each_surface(popup->base, + layer_surface_iterator, &data); } } @@ -587,20 +587,18 @@ struct wlr_surface *wlr_layer_surface_v1_surface_at( struct wlr_surface *wlr_layer_surface_v1_popup_surface_at( struct wlr_layer_surface_v1 *surface, double sx, double sy, double *sub_x, double *sub_y) { - struct wlr_xdg_popup *popup_state; - wl_list_for_each(popup_state, &surface->popups, link) { - struct wlr_xdg_surface *popup = popup_state->base; - if (!popup->mapped) { + struct wlr_xdg_popup *popup; + wl_list_for_each(popup, &surface->popups, link) { + if (!popup->base->mapped) { continue; } - double popup_sx = popup_state->geometry.x - popup->current.geometry.x; - double popup_sy = popup_state->geometry.y - popup->current.geometry.y; + double popup_sx, popup_sy; + popup_sx = popup->current.geometry.x - popup->base->current.geometry.x; + popup_sy = popup->current.geometry.y - popup->base->current.geometry.y; - struct wlr_surface *sub = wlr_xdg_surface_surface_at(popup, - sx - popup_sx, - sy - popup_sy, - sub_x, sub_y); + struct wlr_surface *sub = wlr_xdg_surface_surface_at( + popup->base, sx - popup_sx, sy - popup_sy, sub_x, sub_y); if (sub != NULL) { return sub; } diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index fda0d6aa..26b5f0ef 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -7,7 +7,7 @@ void handle_xdg_popup_ack_configure( struct wlr_xdg_popup *popup, struct wlr_xdg_popup_configure *configure) { - popup->geometry = configure->geometry; + popup->pending.geometry = configure->geometry; } struct wlr_xdg_popup_configure *send_xdg_popup_configure( @@ -238,7 +238,10 @@ void handle_xdg_popup_committed(struct wlr_xdg_popup *popup) { if (!popup->committed) { wlr_xdg_surface_schedule_configure(popup->base); popup->committed = true; + return; } + + popup->current = popup->pending; } static const struct xdg_popup_interface xdg_popup_implementation; @@ -440,8 +443,8 @@ void wlr_xdg_popup_get_toplevel_coords(struct wlr_xdg_popup *popup, wlr_xdg_surface_from_wlr_surface(parent); if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - popup_sx += xdg_surface->popup->geometry.x; - popup_sy += xdg_surface->popup->geometry.y; + popup_sx += xdg_surface->popup->current.geometry.x; + popup_sy += xdg_surface->popup->current.geometry.y; parent = xdg_surface->popup->parent; } else { popup_sx += xdg_surface->current.geometry.x; diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 80144fb6..9ea8fa33 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -464,9 +464,9 @@ void wlr_xdg_popup_get_position(struct wlr_xdg_popup *popup, wlr_xdg_surface_from_wlr_surface(popup->parent); struct wlr_box parent_geo; wlr_xdg_surface_get_geometry(parent, &parent_geo); - *popup_sx = parent_geo.x + popup->geometry.x - + *popup_sx = parent_geo.x + popup->current.geometry.x - popup->base->current.geometry.x; - *popup_sy = parent_geo.y + popup->geometry.y - + *popup_sy = parent_geo.y + popup->current.geometry.y - popup->base->current.geometry.y; }