aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Primak <vyivel@eclair.cafe>2022-03-05 19:32:35 +0300
committerSimon Ser <contact@emersion.fr>2022-05-27 13:31:30 +0000
commit4a968576e44240b447330c848d6cd624d2a27c62 (patch)
tree8e7a8b424273ffab6b52b86a5d3dab02dc4cf2b7
parent4f5d6e474635ee75d57650e4f1ae0926011c1263 (diff)
xdg-popup: add proper configure flow
-rw-r--r--include/types/wlr_xdg_shell.h4
-rw-r--r--include/wlr/types/wlr_xdg_shell.h14
-rw-r--r--types/xdg_shell/wlr_xdg_popup.c34
-rw-r--r--types/xdg_shell/wlr_xdg_surface.c11
4 files changed, 49 insertions, 14 deletions
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;
}