From 76073fe5fad8799e5850805f2f090af2cb62c741 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Tue, 13 Oct 2026 23:41:31 +0300 Subject: Simplify the public event and CPU API Applications now need far less ceremony: hello.c is a 20-line loop that handles REFRESH, CLOSE and QUIT and draws into the surface's own pixels. - Fold GEOMETRY, STATE and FOCUS into one WINDOW event carrying size, scale and state; unchanged values send nothing. - Guarantee REFRESH once a window has a size and after every resize, never at size zero. - Merge DROP_HOVER into DROP with over/leave/data actions and give drag and drop actions enums. - Keep event strings valid until the next wait and drop yasl_event_release; empty or failed waits report NONE. - Replace copy-in presentation with a lent pixel buffer: yasl_cpu_pixels and yasl_cpu_present. - Remove yasl_poll_event, yasl_cpu_read_pixels, unused event fields and comments that restated names. - Wayland: resize floating windows in request_size instead of reporting it unsupported, and stop marking new GPU surfaces as Vulkan so yasl_vulkan_create_surface no longer fails with NATIVE_WINDOW_IN_USE. Also includes the in-progress public API refactor that was uncommitted in the tree (removal of the app/loop layer, new surface, GL and Vulkan entry points). Co-Authored-By: Claude Opus 5.5 --- src/platform/wayland/popup.c | 79 ++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 32 deletions(-) (limited to 'src/platform/wayland/popup.c') diff --git a/src/platform/wayland/popup.c b/src/platform/wayland/popup.c index 44c7206..c563eb4 100644 --- a/src/platform/wayland/popup.c +++ b/src/platform/wayland/popup.c @@ -24,9 +24,19 @@ static const struct xdg_popup_listener popup_listener = { }; static bool popup_spec_valid(const struct wayland_surface *parent, - const struct yasl_popup_spec *spec) + const struct yasl_private_popup_spec *spec) { if (!parent || !spec) return false; + if (spec->positioner_explicit && + (spec->anchor_edges > XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT || + spec->gravity > XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT || + (spec->constraints & ~(unsigned)(XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y)))) + 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 && @@ -37,29 +47,29 @@ static bool popup_spec_valid(const struct wayland_surface *parent, (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) +static bool popup_apply_spec(struct wayland_surface *w, const struct yasl_private_popup_spec *spec) { uint32_t scale = w->parent->scale_120; - struct yasl_vector2i logical = { - .x = (int)(((int64_t)spec->size.x * YASL_SCALE_UNIT + scale - 1) / scale), - .y = (int)(((int64_t)spec->size.y * YASL_SCALE_UNIT + scale - 1) / scale), + struct yasl_private_vector2i logical = { + .x = (int)(((int64_t)spec->size.x * YASL_PRIVATE_SCALE_UNIT + scale - 1) / scale), + .y = (int)(((int64_t)spec->size.y * YASL_PRIVATE_SCALE_UNIT + scale - 1) / 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; + struct yasl_private_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->scale_factor = (double)scale / YASL_PRIVATE_SCALE_UNIT; w->width = width; w->height = height; w->logical_width = logical.x; w->logical_height = logical.y; - w->content = (struct yasl_rect2i){ + w->content = (struct yasl_private_rect2i){ .x = spec->content_offset.x, .y = spec->content_offset.y, .width = content.x, .height = content.y }; @@ -67,20 +77,20 @@ static bool popup_apply_spec(struct wayland_surface *w, const struct yasl_popup_ 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 && + else if ((rescaled || !w->configured) && scale % YASL_PRIVATE_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)); + wl_surface_set_buffer_scale(w->surface, (int32_t)(scale / YASL_PRIVATE_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); + int gx = yasl_private_scale_to_logical(w->content.x, scale); + int gy = yasl_private_scale_to_logical(w->content.y, scale); + int gw = yasl_private_scale_to_logical(w->content.width, scale); + int gh = yasl_private_scale_to_logical(w->content.height, scale); if (gw < 1) gw = 1; if (gh < 1) gh = 1; if (gx + gw > w->logical_width) @@ -91,41 +101,45 @@ static void popup_set_geometry(struct wayland_surface *w) } static struct xdg_positioner *popup_positioner(struct wayland_surface *w, - const struct yasl_popup_spec *spec) + const struct yasl_private_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); + int gw = yasl_private_scale_to_logical(w->content.width, scale); + int gh = yasl_private_scale_to_logical(w->content.height, scale); xdg_positioner_set_size(pos, gw > 0 ? gw : 1, gh > 0 ? gh : 1); - struct yasl_vector2i at = { + struct yasl_private_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); + int aw = yasl_private_scale_to_logical(spec->anchor.width, scale); + int ah = yasl_private_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), + yasl_private_scale_to_logical(at.x, scale), + yasl_private_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, + uint32_t anchor = spec->positioner_explicit ? spec->anchor_edges : + (spec->beside ? XDG_POSITIONER_ANCHOR_TOP_RIGHT : XDG_POSITIONER_ANCHOR_TOP_LEFT); + uint32_t gravity = spec->positioner_explicit ? spec->gravity : + XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT; + uint32_t constraints = spec->positioner_explicit ? spec->constraints : XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y); + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y; + xdg_positioner_set_anchor(pos, anchor); + xdg_positioner_set_gravity(pos, gravity); + xdg_positioner_set_constraint_adjustment(pos, constraints); 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) + const struct yasl_private_popup_spec *spec) { struct wayland_display *c = parent ? parent->conn : NULL; struct seat *seat = c ? (c->active_seat ? c->active_seat : c->seats) : NULL; @@ -137,7 +151,8 @@ struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *par if (!w) return NULL; w->base.display = &c->base; - w->base.state = YASL_STATE_CSD; + w->base.state = YASL_PRIVATE_STATE_CSD; + w->base.presenter = YASL_PRIVATE_PRESENTER_CPU; w->input.leave_ends_press = true; w->conn = c; w->conn_next = c->surfaces; @@ -150,7 +165,7 @@ struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *par 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.size = (struct yasl_private_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) @@ -180,13 +195,13 @@ err: return NULL; } -bool wayland_surface_popup_reposition(struct wayland_surface *w, const struct yasl_popup_spec *spec) +bool wayland_surface_popup_reposition(struct wayland_surface *w, const struct yasl_private_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 = { + struct yasl_private_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 }, -- cgit v1.2.3