summaryrefslogtreecommitdiff
path: root/src/wayland/popup.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 13:44:13 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 13:44:13 +0300
commitc059e3aa7f93da470f052a5cd8ee0d8dc969e679 (patch)
tree63ffa378287ed2c606eda2e940501b9edc3d2b8b /src/wayland/popup.c
parent87d0bc50d53dc216efb2b04495f090616318bc5c (diff)
rename and simplification
Diffstat (limited to 'src/wayland/popup.c')
-rw-r--r--src/wayland/popup.c205
1 files changed, 0 insertions, 205 deletions
diff --git a/src/wayland/popup.c b/src/wayland/popup.c
deleted file mode 100644
index 3a85435..0000000
--- a/src/wayland/popup.c
+++ /dev/null
@@ -1,205 +0,0 @@
-#include "internal.h"
-
-static void popup_configure(void *data, struct xdg_popup *popup,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- (void)data; (void)popup; (void)x; (void)y; (void)width; (void)height;
-}
-
-static void popup_done(void *data, struct xdg_popup *popup)
-{
- (void)popup;
- surface_fail(data);
-}
-
-static void popup_repositioned(void *data, struct xdg_popup *popup, uint32_t token)
-{
- (void)data; (void)popup; (void)token;
-}
-
-static const struct xdg_popup_listener popup_listener = {
- .configure = popup_configure,
- .popup_done = popup_done,
- .repositioned = popup_repositioned,
-};
-
-static bool popup_spec_valid(const struct wayland_surface *parent,
- const struct yasl_popup_spec *spec)
-{
- if (!parent || !spec) return false;
- int64_t x = (int64_t)spec->anchor.x - parent->content.x;
- int64_t y = (int64_t)spec->anchor.y - parent->content.y;
- return x >= INT_MIN && x <= INT_MAX && y >= INT_MIN && y <= INT_MAX &&
- spec->size.x > 0 && spec->size.y > 0 &&
- spec->content_offset.x >= 0 && spec->content_offset.y >= 0 &&
- spec->content_size.x >= 0 && spec->content_size.y >= 0 &&
- (int64_t)spec->content_offset.x + spec->content_size.x <= spec->size.x &&
- (int64_t)spec->content_offset.y + spec->content_size.y <= spec->size.y;
-}
-
-static bool popup_apply_spec(struct wayland_surface *w, const struct yasl_popup_spec *spec)
-{
- uint32_t scale = w->parent->scale_120;
- struct yasl_vector2i logical = {
- .x = logical_px_ceil(spec->size.x, scale),
- .y = logical_px_ceil(spec->size.y, scale),
- };
- int width = device_px(logical.x, scale);
- int height = device_px(logical.y, scale);
- size_t bytes;
- if (logical.x <= 0 || logical.y <= 0 || !buffer_size(width, height, &bytes))
- return false;
- struct yasl_vector2i content = spec->content_size;
- if (!content.x) content.x = spec->size.x - spec->content_offset.x;
- if (!content.y) content.y = spec->size.y - spec->content_offset.y;
- bool rescaled = scale != w->scale_120;
- w->scale_120 = w->pending_scale_120 = scale;
- w->scale_factor = (double)scale / YASL_SCALE_UNIT;
- w->width = width;
- w->height = height;
- w->logical_width = logical.x;
- w->logical_height = logical.y;
- w->content = (struct yasl_rect2i){
- .x = spec->content_offset.x, .y = spec->content_offset.y,
- .width = content.x, .height = content.y
- };
- for (int i = 0; i < NBUF; i++)
- w->buffers[i].presented = false;
- if (w->viewport)
- wp_viewport_set_destination(w->viewport, logical.x, logical.y);
- else if ((rescaled || !w->configured) && scale % YASL_SCALE_UNIT == 0 &&
- wl_proxy_get_version((struct wl_proxy *)w->surface) >=
- WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
- wl_surface_set_buffer_scale(w->surface, (int32_t)(scale / YASL_SCALE_UNIT));
- return true;
-}
-
-static void popup_set_geometry(struct wayland_surface *w)
-{
- uint32_t scale = w->scale_120;
- int gx = yasl_scale_to_logical(w->content.x, scale);
- int gy = yasl_scale_to_logical(w->content.y, scale);
- int gw = yasl_scale_to_logical(w->content.width, scale);
- int gh = yasl_scale_to_logical(w->content.height, scale);
- if (gw < 1) gw = 1;
- if (gh < 1) gh = 1;
- if (gx + gw > w->logical_width)
- gx = w->logical_width - gw > 0 ? w->logical_width - gw : 0;
- if (gy + gh > w->logical_height)
- gy = w->logical_height - gh > 0 ? w->logical_height - gh : 0;
- xdg_surface_set_window_geometry(w->xdg_surface, gx, gy, gw, gh);
-}
-
-static struct xdg_positioner *popup_positioner(struct wayland_surface *w,
- const struct yasl_popup_spec *spec)
-{
- struct wayland_surface *parent = w->parent;
- struct xdg_positioner *pos = xdg_wm_base_create_positioner(w->conn->wm_base);
- if (!pos)
- return NULL;
- uint32_t scale = parent->scale_120;
- int gw = yasl_scale_to_logical(w->content.width, scale);
- int gh = yasl_scale_to_logical(w->content.height, scale);
- xdg_positioner_set_size(pos, gw > 0 ? gw : 1, gh > 0 ? gh : 1);
- struct yasl_vector2i at = {
- .x = spec->anchor.x - parent->content.x,
- .y = spec->anchor.y - parent->content.y,
- };
- int aw = yasl_scale_to_logical(spec->anchor.width, scale);
- int ah = yasl_scale_to_logical(spec->anchor.height, scale);
- xdg_positioner_set_anchor_rect(pos,
- yasl_scale_to_logical(at.x, scale),
- yasl_scale_to_logical(at.y, scale),
- aw > 0 ? aw : 1, ah > 0 ? ah : 1);
- xdg_positioner_set_anchor(pos, spec->beside ? XDG_POSITIONER_ANCHOR_TOP_RIGHT
- : XDG_POSITIONER_ANCHOR_TOP_LEFT);
- xdg_positioner_set_gravity(pos, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
- xdg_positioner_set_constraint_adjustment(pos,
- XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X |
- XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y |
- XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X |
- XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
- if (xdg_positioner_get_version(pos) >= XDG_POSITIONER_SET_REACTIVE_SINCE_VERSION)
- xdg_positioner_set_reactive(pos);
- return pos;
-}
-
-struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *parent,
- const struct yasl_popup_spec *spec)
-{
- struct wayland_display *c = parent ? parent->conn : NULL;
- struct seat *seat = c ? conn_active_seat(c) : NULL;
- if (!c || c->lost || parent->closed || !parent->xdg_surface || !seat ||
- !seat->input_serial || !popup_spec_valid(parent, spec))
- return NULL;
-
- struct wayland_surface *w = calloc(1, sizeof(*w));
- if (!w)
- return NULL;
- w->base.display = &c->base;
- w->conn = c;
- w->conn_next = c->surfaces;
- c->surfaces = w;
- w->parent = parent;
- wayland_surface_set_callbacks(w, NULL, NULL);
- w->clock.refresh_ns = parent->clock.refresh_ns;
-
- w->surface = wl_compositor_create_surface(c->compositor);
- if (!w->surface)
- goto err;
- w->base.native_handle = w->surface;
- w->base.size = (struct yasl_vector2i){spec->size.x, spec->size.y};
- w->base.scale_120 = parent->scale_120;
- wl_surface_set_user_data(w->surface, w);
- if (surface_init_scaling(w) < 0)
- goto err;
- w->xdg_surface = xdg_wm_base_get_xdg_surface(c->wm_base, w->surface);
- if (!w->xdg_surface)
- goto err;
- xdg_surface_add_listener(w->xdg_surface, &shell_surface_listener, w);
- if (!popup_apply_spec(w, spec))
- goto err;
- struct xdg_positioner *pos = popup_positioner(w, spec);
- if (!pos)
- goto err;
- w->popup = xdg_surface_get_popup(w->xdg_surface, parent->xdg_surface, pos);
- xdg_positioner_destroy(pos);
- if (!w->popup)
- goto err;
- xdg_popup_add_listener(w->popup, &popup_listener, w);
- popup_set_geometry(w);
- xdg_popup_grab(w->popup, seat->proxy, seat->input_serial);
- w->want_draw = true;
- wl_surface_commit(w->surface);
- return w;
-
-err:
- wayland_surface_destroy(w);
- return NULL;
-}
-
-bool wayland_surface_popup_reposition(struct wayland_surface *w, const struct yasl_popup_spec *spec)
-{
- if (!w || !w->popup || w->closed || !w->conn || w->conn->lost ||
- !popup_spec_valid(w->parent, spec) ||
- xdg_popup_get_version(w->popup) < XDG_POPUP_REPOSITION_SINCE_VERSION)
- return false;
- struct yasl_popup_spec old = {
- .size = { .x = w->width, .y = w->height },
- .content_offset = { .x = w->content.x, .y = w->content.y },
- .content_size = { .x = w->content.width, .y = w->content.height },
- };
- if (!popup_apply_spec(w, spec)) {
- popup_apply_spec(w, &old);
- return false;
- }
- struct xdg_positioner *pos = popup_positioner(w, spec);
- if (!pos)
- return false;
- popup_set_geometry(w);
- static uint32_t token;
- xdg_popup_reposition(w->popup, pos, ++token);
- xdg_positioner_destroy(pos);
- wayland_surface_schedule_redraw(w);
- return true;
-}