summaryrefslogtreecommitdiff
path: root/tests/wayland/test_app_input.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 /tests/wayland/test_app_input.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 'tests/wayland/test_app_input.c')
-rw-r--r--tests/wayland/test_app_input.c174
1 files changed, 60 insertions, 114 deletions
diff --git a/tests/wayland/test_app_input.c b/tests/wayland/test_app_input.c
index 7e0e9a0..c8e4d2b 100644
--- a/tests/wayland/test_app_input.c
+++ b/tests/wayland/test_app_input.c
@@ -1,132 +1,78 @@
-/* An input event callback that destroys its own surface. The app runner
- * must not touch the surface's entry after the callback, and must not
- * deliver the surface's remaining input. Needs a Wayland compositor. */
-#include "platform/wayland/internal.h"
-#include "yasl/app.h"
+/* The public event queue must retain FIFO order and discard events targeted
+ * at a surface when that surface is destroyed. Native input is injected
+ * through the backend queue, without requiring a compositor. */
+#include "yasl/yasl.h"
+#include "common/backend.h"
#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
+#include <string.h>
-struct test_state {
- bool initialized;
- int keys;
- int buttons, motions, resets;
- int end;
+static struct input_queue *surface_queue(struct yasl_surface *s)
+{
+ return &s->input;
+}
+
+static const struct yasl_private_backend_ops test_ops = {
+ .surface_input_queue = surface_queue,
};
-static void push_key(struct yasl_surface *s)
+static void setup(struct yasl_private_display *display, struct yasl_surface *surface)
{
- struct yasl_event ev = {
- .surface = s,
- .type = YASL_EVENT_KEY,
- .key = { .key = YASL_KEY_A, .action = YASL_KEY_PRESS },
- };
- assert(input_queue_push(&((struct wayland_surface *)s)->input, &ev));
+ *display = (struct yasl_private_display){.ops = &test_ops};
+ *surface = (struct yasl_surface){.display = display, .scale_120 = 120};
+ assert(yasl_private_events_open(display));
+ assert(yasl_private_events_register(surface));
}
-static enum yasl_app_result on_init(void *ud, struct yasl_display *d)
+static void destroy_surface(struct yasl_surface *surface)
{
- struct test_state *state = ud;
- state->initialized = true;
- if (state->end == 3) {
- /* With no event callback, a close request alone stops the runner. */
- struct yasl_surface *s = yasl_surface_create_toplevel(d,
- &(struct yasl_window_spec){ .title = "App Close Test", .size = {64, 64} });
- assert(s);
- yasl_surface_notify_close(s);
- return YASL_APP_CONTINUE;
- }
- if (state->end) {
- if (state->end == 1)
- yasl_display_notify_event(d, YASL_EVENT_DISPLAY_QUIT);
- else
- yasl_display_notify_event(d, YASL_EVENT_DISPLAY_LOST);
- return YASL_APP_CONTINUE;
- }
- struct yasl_surface *s = yasl_surface_create_toplevel(d,
- &(struct yasl_window_spec){ .title = "App Input Test", .size = {64, 64} });
- assert(s);
- struct input_queue *queue = &((struct wayland_surface *)s)->input;
- input_queue_clear(queue);
- struct yasl_event event = {.surface = s, .type = YASL_EVENT_POINTER_DOWN,
- .pointer = {.device = YASL_PTR_DEV_ERASER, .button = YASL_BUTTON_PRIMARY,
- .pos = {12, 34}, .pen = {.pressure = 50000, .tilt_x = -20, .tilt_y = 30}}};
- assert(input_queue_push(queue, &event));
- event.type = YASL_EVENT_POINTER_MOTION;
- event.pointer.pos = (struct yasl_vector2i){15, 39};
- assert(input_queue_push(queue, &event));
- struct yasl_event reset = {.surface = s, .type = YASL_EVENT_INPUT_RESET};
- assert(input_queue_push(queue, &reset));
- event.pointer.device = YASL_PTR_DEV_PEN;
- event.pointer.pos = (struct yasl_vector2i){100, 200};
- assert(input_queue_push(queue, &event));
- push_key(s);
- push_key(s);
- return YASL_APP_CONTINUE;
+ yasl_private_events_unregister(surface);
+ input_queue_clear(&surface->input);
}
-static enum yasl_app_result on_event(void *ud, const struct yasl_event *ev)
+static void test_fifo_and_destroy(void)
{
- struct test_state *state = ud;
- if (ev->type == YASL_EVENT_POINTER_DOWN) {
- assert(ev->pointer.device == YASL_PTR_DEV_ERASER);
- assert(ev->pointer.button == YASL_BUTTON_PRIMARY);
- assert(ev->pointer.pos.x == 12 && ev->pointer.pos.y == 34);
- assert(ev->pointer.pen.pressure == 50000);
- assert(ev->pointer.pen.tilt_x == -20 && ev->pointer.pen.tilt_y == 30);
- state->buttons++;
- } else if (ev->type == YASL_EVENT_POINTER_MOTION) {
- if (!state->motions) {
- assert(ev->pointer.device == YASL_PTR_DEV_ERASER);
- assert(ev->pointer.delta.x == 3 && ev->pointer.delta.y == 5);
- } else {
- assert(ev->pointer.device == YASL_PTR_DEV_PEN);
- assert(!ev->pointer.delta.x && !ev->pointer.delta.y);
- }
- assert(ev->pointer.pen.pressure == 50000);
- state->motions++;
- } else if (ev->type == YASL_EVENT_INPUT_RESET) {
- state->resets++;
- } else if (ev->type == YASL_EVENT_KEY) {
- state->keys++;
- yasl_surface_destroy(ev->surface);
- }
- return YASL_APP_CONTINUE;
+ struct yasl_private_display display;
+ struct yasl_surface surface;
+ setup(&display, &surface);
+
+ assert(input_queue_push(&surface.input, &(struct yasl_private_event){
+ .type = YASL_PRIVATE_EVENT_KEY,
+ .surface = &surface,
+ .key = {.key = YASL_KEY_A, .action = YASL_KEY_PRESS},
+ }));
+ assert(input_queue_push(&surface.input, &(struct yasl_private_event){
+ .type = YASL_PRIVATE_EVENT_TEXT,
+ .surface = &surface,
+ .text = {.data = "hello", .len = 5},
+ }));
+
+ struct yasl_private_event event;
+ assert(yasl_private_display_poll_event(&display, &event));
+ assert(event.type == YASL_PRIVATE_EVENT_KEY && event.key.key == YASL_KEY_A);
+ assert(yasl_private_display_poll_event(&display, &event));
+ assert(event.type == YASL_PRIVATE_EVENT_TEXT && event.text.len == 5);
+ assert(!strcmp(event.text.data, "hello"));
+
+ /* Queue multiple events, then destroy the target before consumption. */
+ assert(input_queue_push(&surface.input, &(struct yasl_private_event){
+ .type = YASL_PRIVATE_EVENT_KEY, .surface = &surface,
+ .key = {.key = YASL_KEY_B, .action = YASL_KEY_PRESS},
+ }));
+ assert(input_queue_push(&surface.input, &(struct yasl_private_event){
+ .type = YASL_PRIVATE_EVENT_TEXT, .surface = &surface,
+ .text = {.data = "discard", .len = 7},
+ }));
+ destroy_surface(&surface);
+ assert(!yasl_private_display_poll_event(&display, &event));
+ yasl_private_events_close(&display);
+
+ /* Public event names remain the event stream consumed by applications. */
+ assert(YASL_EVENT_KEY != YASL_EVENT_TEXT);
}
int main(void)
{
- if (!getenv("WAYLAND_DISPLAY"))
- return 77;
- struct test_state state = {0};
- int res = yasl_run(&(struct yasl_app_desc){
- .app_id = "org.yasl.test.app-input",
- .backend = YASL_BACKEND_WAYLAND,
- .userdata = &state,
- .init = on_init,
- .event = on_event,
- });
- /* A display variable may exist even when the test sandbox cannot connect
- * to that compositor. Keep this as an integration test in that case. */
- if (res < 0 && !state.initialized &&
- (errno == EACCES || errno == EPERM || errno == ENOENT ||
- errno == ECONNREFUSED || errno == ENODEV))
- return 77;
- assert(res == 0);
- assert(state.keys == 1);
- assert(state.buttons == 1 && state.motions == 2 && state.resets == 1);
- for (int end = 1; end <= 2; end++) {
- state = (struct test_state){.end = end};
- res = yasl_run(&(struct yasl_app_desc){
- .backend = YASL_BACKEND_WAYLAND, .userdata = &state, .init = on_init,
- });
- assert(end == 1 ? res == 0 : res < 0);
- }
- state = (struct test_state){.end = 3};
- res = yasl_run(&(struct yasl_app_desc){
- .backend = YASL_BACKEND_WAYLAND, .userdata = &state, .init = on_init,
- });
- assert(res == 0);
+ test_fifo_and_destroy();
return 0;
}