diff --git a/include/types/wlr_xdg_shell.h b/include/types/wlr_xdg_shell.h index cfed6ee1..37ef2a95 100644 --- a/include/types/wlr_xdg_shell.h +++ b/include/types/wlr_xdg_shell.h @@ -26,6 +26,10 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, void unmap_xdg_popup(struct wlr_xdg_popup *popup); void destroy_xdg_popup(struct wlr_xdg_popup *popup); void handle_xdg_popup_committed(struct wlr_xdg_popup *popup); +struct wlr_xdg_popup_configure *send_xdg_popup_configure( + struct wlr_xdg_popup *popup); +void handle_xdg_popup_ack_configure(struct wlr_xdg_popup *popup, + struct wlr_xdg_popup_configure *configure); void create_xdg_toplevel(struct wlr_xdg_surface *surface, uint32_t id); diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 51ba0584..19378c16 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -70,6 +70,11 @@ struct wlr_xdg_positioner { struct wlr_xdg_positioner_rules rules; }; +struct wlr_xdg_popup_configure { + struct wlr_box geometry; + struct wlr_xdg_positioner_rules rules; +}; + struct wlr_xdg_popup { struct wlr_xdg_surface *base; struct wl_list link; @@ -79,12 +84,12 @@ struct wlr_xdg_popup { struct wlr_surface *parent; struct wlr_seat *seat; + 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_positioner_rules positioner_rules; - struct wl_list grab_link; // wlr_xdg_popup_grab.popups }; @@ -173,7 +178,10 @@ struct wlr_xdg_surface_configure { struct wl_list link; // wlr_xdg_surface.configure_list uint32_t serial; - struct wlr_xdg_toplevel_configure *toplevel_configure; + union { + struct wlr_xdg_toplevel_configure *toplevel_configure; + struct wlr_xdg_popup_configure *popup_configure; + }; }; struct wlr_xdg_surface_state { diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index 973a339b..fda0d6aa 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -4,6 +4,30 @@ #include "types/wlr_xdg_shell.h" #include "util/signal.h" +void handle_xdg_popup_ack_configure( + struct wlr_xdg_popup *popup, + struct wlr_xdg_popup_configure *configure) { + popup->geometry = configure->geometry; +} + +struct wlr_xdg_popup_configure *send_xdg_popup_configure( + struct wlr_xdg_popup *popup) { + struct wlr_xdg_popup_configure *configure = + calloc(1, sizeof(*configure)); + if (configure == NULL) { + wl_resource_post_no_memory(popup->resource); + return NULL; + } + *configure = popup->scheduled; + + struct wlr_box *geometry = &configure->geometry; + xdg_popup_send_configure(popup->resource, + geometry->x, geometry->y, + geometry->width, geometry->height); + + return configure; +} + static void xdg_popup_grab_end(struct wlr_xdg_popup_grab *popup_grab) { struct wlr_xdg_popup *popup, *tmp; wl_list_for_each_safe(popup, tmp, &popup_grab->popups, grab_link) { @@ -348,10 +372,9 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, surface->role = WLR_XDG_SURFACE_ROLE_POPUP; - memcpy(&surface->popup->positioner_rules, - &positioner->rules, sizeof(positioner->rules)); wlr_xdg_positioner_rules_get_geometry( - &positioner->rules, &surface->popup->geometry); + &positioner->rules, &surface->popup->scheduled.geometry); + surface->popup->scheduled.rules = positioner->rules; if (parent) { surface->popup->parent = parent->surface; @@ -443,6 +466,7 @@ void wlr_xdg_popup_unconstrain_from_box(struct wlr_xdg_popup *popup, .width = toplevel_space_box->width, .height = toplevel_space_box->height, }; - wlr_xdg_positioner_rules_unconstrain_box(&popup->positioner_rules, - &popup_constraint, &popup->geometry); + wlr_xdg_positioner_rules_unconstrain_box(&popup->scheduled.rules, + &popup_constraint, &popup->scheduled.geometry); + wlr_xdg_surface_schedule_configure(popup->base); } diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 73ed66c9..80144fb6 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -107,9 +107,11 @@ static void xdg_surface_handle_ack_configure(struct wl_client *client, break; case WLR_XDG_SURFACE_ROLE_TOPLEVEL: handle_xdg_toplevel_ack_configure(surface->toplevel, - configure->toplevel_configure); + configure->toplevel_configure); break; case WLR_XDG_SURFACE_ROLE_POPUP: + handle_xdg_popup_ack_configure(surface->popup, + configure->popup_configure); break; } @@ -145,11 +147,8 @@ static void surface_send_configure(void *user_data) { send_xdg_toplevel_configure(surface->toplevel); break; case WLR_XDG_SURFACE_ROLE_POPUP: - xdg_popup_send_configure(surface->popup->resource, - surface->popup->geometry.x, - surface->popup->geometry.y, - surface->popup->geometry.width, - surface->popup->geometry.height); + configure->popup_configure = + send_xdg_popup_configure(surface->popup); break; }