summaryrefslogtreecommitdiff
path: root/tests/wayland
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 21:23:03 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 21:23:03 +0300
commitdd1775a9927922c14f8679ccbc4d3ca8d5917e20 (patch)
tree3acc442bb4a3470364b74aa82ff67cb84d555c45 /tests/wayland
parentecb81aeea4c0c880b3a60a0dc8418c4bf2a7cf85 (diff)
public api refactor
Diffstat (limited to 'tests/wayland')
-rw-r--r--tests/wayland/test_app_input.c17
-rw-r--r--tests/wayland/test_clipboard.c75
2 files changed, 81 insertions, 11 deletions
diff --git a/tests/wayland/test_app_input.c b/tests/wayland/test_app_input.c
index 88f9ead..7e0e9a0 100644
--- a/tests/wayland/test_app_input.c
+++ b/tests/wayland/test_app_input.c
@@ -5,9 +5,11 @@
#include "yasl/app.h"
#include <assert.h>
+#include <errno.h>
#include <stdlib.h>
struct test_state {
+ bool initialized;
int keys;
int buttons, motions, resets;
int end;
@@ -26,21 +28,20 @@ static void push_key(struct yasl_surface *s)
static enum yasl_app_result on_init(void *ud, struct yasl_display *d)
{
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);
- struct wayland_surface *w = (struct wayland_surface *)s;
- w->cbs->close(s, w->ud);
+ yasl_surface_notify_close(s);
return YASL_APP_CONTINUE;
}
if (state->end) {
- struct wayland_display *display = (struct wayland_display *)d;
if (state->end == 1)
- display->cbs->quit(display->ud);
+ yasl_display_notify_event(d, YASL_EVENT_DISPLAY_QUIT);
else
- display->cbs->lost(display->ud);
+ yasl_display_notify_event(d, YASL_EVENT_DISPLAY_LOST);
return YASL_APP_CONTINUE;
}
struct yasl_surface *s = yasl_surface_create_toplevel(d,
@@ -106,6 +107,12 @@ int main(void)
.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);
diff --git a/tests/wayland/test_clipboard.c b/tests/wayland/test_clipboard.c
index ff84209..1778ad2 100644
--- a/tests/wayland/test_clipboard.c
+++ b/tests/wayland/test_clipboard.c
@@ -1,24 +1,46 @@
#include "../../src/platform/wayland/clipboard.c"
+#include "common/loop.h"
#include <assert.h>
-struct received { int count; size_t len; char text[32]; };
+struct received {
+ int count;
+ size_t len;
+ uint64_t request_id;
+ enum yasl_transfer_status status;
+ struct clipboard *clipboard;
+ bool forget_on_receive;
+ char text[32];
+};
static void receive(const char *text, size_t len, bool uri_list,
- struct wl_surface *surface, void *ud)
+ struct wl_surface *surface, uint64_t request_id,
+ enum yasl_transfer_status status, void *ud)
{
(void)surface;
struct received *r = ud;
assert(!uri_list && len < sizeof(r->text));
- memcpy(r->text, text, len);
- r->text[len] = '\0';
+ if (status == YASL_TRANSFER_OK) {
+ assert(text);
+ memcpy(r->text, text, len);
+ r->text[len] = '\0';
+ } else {
+ assert(!text && len == 0);
+ }
r->len = len;
+ r->request_id = request_id;
+ r->status = status;
r->count++;
+ if (r->forget_on_receive) {
+ r->forget_on_receive = false;
+ clipboard_forget_surface(r->clipboard, surface);
+ }
}
int main(void)
{
struct received received = {0};
struct clipboard c = {.loop = yasl_loop_create(), .receive = receive, .ud = &received};
+ received.clipboard = &c;
assert(c.loop);
const struct { const char *bytes; size_t len; bool valid; } cases[] = {
{"é字😀", sizeof("é字😀") - 1, true},
@@ -28,20 +50,61 @@ int main(void)
};
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
received = (struct received){0};
+ received.clipboard = &c;
int fds[2];
assert(pipe(fds) == 0);
- assert(start_transfer_text(&c, fds[0], false, false, c.text));
+ struct transfer *transfer = start_transfer_text(&c, fds[0], false, false, c.text);
+ assert(transfer);
+ yasl_timer_id timeout_id = transfer->timeout;
+ assert(timeout_id && yasl_loop_timer_armed(c.loop, timeout_id));
+ transfer->paste = true;
+ transfer->request_id = 42;
assert(write(fds[1], cases[i].bytes, cases[i].len) == (ssize_t)cases[i].len);
close(fds[1]);
for (int steps = 0; c.transfers && steps < 10; steps++)
assert(yasl_loop_step(c.loop, 0) >= 0);
assert(!c.transfers);
- assert(received.count == (int)cases[i].valid);
+ assert(!yasl_loop_timer_armed(c.loop, timeout_id));
+ assert(received.count == 1);
+ assert(received.request_id == 42);
+ assert(received.status == (cases[i].valid ? YASL_TRANSFER_OK : YASL_TRANSFER_FAILED));
if (cases[i].valid) {
assert(received.len == cases[i].len);
assert(memcmp(received.text, cases[i].bytes, received.len) == 0);
}
}
+ received = (struct received){0};
+ received.clipboard = &c;
+ int cancel_fds[2];
+ assert(pipe(cancel_fds) == 0);
+ struct transfer *pending = start_transfer_text(&c, cancel_fds[0], false, false, NULL);
+ assert(pending);
+ yasl_timer_id cancel_timeout_id = pending->timeout;
+ assert(cancel_timeout_id && yasl_loop_timer_armed(c.loop, cancel_timeout_id));
+ pending->paste = true;
+ pending->request_id = 99;
+ struct wl_surface *target = (struct wl_surface *)(uintptr_t)1;
+ pending->drop_surface = target;
+ clipboard_forget_surface(&c, target);
+ close(cancel_fds[1]);
+ assert(!c.transfers && received.count == 0);
+ assert(!yasl_loop_timer_armed(c.loop, cancel_timeout_id));
+
+ received.forget_on_receive = true;
+ int timeout_fds[2];
+ assert(pipe(timeout_fds) == 0);
+ struct transfer *timed = start_transfer_text(&c, timeout_fds[0], false, false, NULL);
+ assert(timed && timed->timeout);
+ timed->paste = true;
+ timed->request_id = 100;
+ struct wl_surface *timeout_target = (struct wl_surface *)(uintptr_t)2;
+ timed->drop_surface = timeout_target;
+ yasl_timer_id timeout_id = timed->timeout;
+ assert(yasl_loop_del_timer(c.loop, timeout_id));
+ (void)transfer_timeout(timed, timeout_id, CLIPBOARD_TRANSFER_TIMEOUT_NS);
+ close(timeout_fds[1]);
+ assert(!c.transfers && received.count == 1);
+ assert(received.request_id == 100 && received.status == YASL_TRANSFER_FAILED);
yasl_loop_destroy(c.loop);
return 0;
}