xdg-popup: add proper configure flow

This commit is contained in:
Kirill Primak 2022-03-05 19:32:35 +03:00 committed by Simon Ser
parent 4f5d6e4746
commit 4a968576e4
4 changed files with 49 additions and 14 deletions

View file

@ -26,6 +26,10 @@ void create_xdg_popup(struct wlr_xdg_surface *surface,
void unmap_xdg_popup(struct wlr_xdg_popup *popup); void unmap_xdg_popup(struct wlr_xdg_popup *popup);
void destroy_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); 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, void create_xdg_toplevel(struct wlr_xdg_surface *surface,
uint32_t id); uint32_t id);

View file

@ -70,6 +70,11 @@ struct wlr_xdg_positioner {
struct wlr_xdg_positioner_rules rules; 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_popup {
struct wlr_xdg_surface *base; struct wlr_xdg_surface *base;
struct wl_list link; struct wl_list link;
@ -79,12 +84,12 @@ struct wlr_xdg_popup {
struct wlr_surface *parent; struct wlr_surface *parent;
struct wlr_seat *seat; struct wlr_seat *seat;
struct wlr_xdg_popup_configure scheduled;
// Position of the popup relative to the upper left corner of the window // Position of the popup relative to the upper left corner of the window
// geometry of the parent surface // geometry of the parent surface
struct wlr_box geometry; struct wlr_box geometry;
struct wlr_xdg_positioner_rules positioner_rules;
struct wl_list grab_link; // wlr_xdg_popup_grab.popups 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 struct wl_list link; // wlr_xdg_surface.configure_list
uint32_t serial; 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 { struct wlr_xdg_surface_state {

View file

@ -4,6 +4,30 @@
#include "types/wlr_xdg_shell.h" #include "types/wlr_xdg_shell.h"
#include "util/signal.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) { static void xdg_popup_grab_end(struct wlr_xdg_popup_grab *popup_grab) {
struct wlr_xdg_popup *popup, *tmp; struct wlr_xdg_popup *popup, *tmp;
wl_list_for_each_safe(popup, tmp, &popup_grab->popups, grab_link) { 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; surface->role = WLR_XDG_SURFACE_ROLE_POPUP;
memcpy(&surface->popup->positioner_rules,
&positioner->rules, sizeof(positioner->rules));
wlr_xdg_positioner_rules_get_geometry( 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) { if (parent) {
surface->popup->parent = parent->surface; 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, .width = toplevel_space_box->width,
.height = toplevel_space_box->height, .height = toplevel_space_box->height,
}; };
wlr_xdg_positioner_rules_unconstrain_box(&popup->positioner_rules, wlr_xdg_positioner_rules_unconstrain_box(&popup->scheduled.rules,
&popup_constraint, &popup->geometry); &popup_constraint, &popup->scheduled.geometry);
wlr_xdg_surface_schedule_configure(popup->base);
} }

View file

@ -107,9 +107,11 @@ static void xdg_surface_handle_ack_configure(struct wl_client *client,
break; break;
case WLR_XDG_SURFACE_ROLE_TOPLEVEL: case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
handle_xdg_toplevel_ack_configure(surface->toplevel, handle_xdg_toplevel_ack_configure(surface->toplevel,
configure->toplevel_configure); configure->toplevel_configure);
break; break;
case WLR_XDG_SURFACE_ROLE_POPUP: case WLR_XDG_SURFACE_ROLE_POPUP:
handle_xdg_popup_ack_configure(surface->popup,
configure->popup_configure);
break; break;
} }
@ -145,11 +147,8 @@ static void surface_send_configure(void *user_data) {
send_xdg_toplevel_configure(surface->toplevel); send_xdg_toplevel_configure(surface->toplevel);
break; break;
case WLR_XDG_SURFACE_ROLE_POPUP: case WLR_XDG_SURFACE_ROLE_POPUP:
xdg_popup_send_configure(surface->popup->resource, configure->popup_configure =
surface->popup->geometry.x, send_xdg_popup_configure(surface->popup);
surface->popup->geometry.y,
surface->popup->geometry.width,
surface->popup->geometry.height);
break; break;
} }