summaryrefslogtreecommitdiff
path: root/src/platform/wayland/popup.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 23:41:31 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 23:41:31 +0300
commit76073fe5fad8799e5850805f2f090af2cb62c741 (patch)
tree9658019babe4760a3634bdab4da0731a10e42e68 /src/platform/wayland/popup.c
parentdd1775a9927922c14f8679ccbc4d3ca8d5917e20 (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'src/platform/wayland/popup.c')
-rw-r--r--src/platform/wayland/popup.c79
1 files changed, 47 insertions, 32 deletions
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 },