From 7ad4f86f2aac75935a52d31383593c1327204729 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Wed, 14 Oct 2026 14:21:13 +0300 Subject: Count touch as a press, report a missing bell, and test X11 INCR - Wayland: a touch contact is a press for move, resize, menu and drag again, and a compositor without xdg-system-bell reports ENOTSUP. - yasl_surface_set_cursor no longer reports a stale errno. - The X11 input test expects the TIMESTAMP and MULTIPLE targets and drives an INCR transfer instead of expecting INCR to be rejected. Co-Authored-By: Claude Opus 5.5 --- tests/common/test_surface_integration.c | 5 ++-- tests/x11/test_input.c | 49 +++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/tests/common/test_surface_integration.c b/tests/common/test_surface_integration.c index 9067640..887f254 100644 --- a/tests/common/test_surface_integration.c +++ b/tests/common/test_surface_integration.c @@ -265,9 +265,8 @@ int main(int argc, char **argv) int restored = yasl_surface_request(s, YASL_REQUEST_RESTORE); assert(restored == 0 || restored == -ENOTSUP); drain(); - /* ENOTSUP is the documented answer when the compositor lacks xdg-system-bell; Wayland - * currently reports EIO there, so only the 0-or-errno rule is checked. */ - assert(yasl_surface_bell(s) <= 0); + int bell = yasl_surface_bell(s); + assert(bell == 0 || bell == -ENOTSUP); /* Desktop queries and the drag cancel, which is a no-op without a drag. */ assert(yasl_get_appearance() <= 7); diff --git a/tests/x11/test_input.c b/tests/x11/test_input.c index a89812b..f82dc82 100644 --- a/tests/x11/test_input.c +++ b/tests/x11/test_input.c @@ -34,12 +34,14 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface * selection_request(d, &request); assert(XGetWindowProperty(d->native, requestor, property, 0, 100, True, AnyPropertyType, &actual, &format, &count, &left, &data) == Success); - assert(actual == XA_ATOM && format == 32 && count == 2); - assert(((Atom *)data)[0] == d->targets && ((Atom *)data)[1] == d->utf8); + /* Text outside Latin-1 offers no STRING target. */ + assert(actual == XA_ATOM && format == 32 && count == 4); + assert(((Atom *)data)[0] == d->targets && ((Atom *)data)[1] == d->utf8 && + ((Atom *)data)[2] == d->timestamp && ((Atom *)data)[3] == d->multiple); XFree(data); XDestroyWindow(d->native, requestor); - /* Simulate legacy STRING, empty UTF-8, malformed UTF-8, and rejected INCR. */ + /* Simulate legacy STRING, empty UTF-8 and malformed UTF-8. */ const struct { Atom type; const void *bytes; @@ -51,7 +53,6 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface * {XA_STRING, "caf\xe9 \xa3", 6, 8, "café £", YASL_PRIVATE_TRANSFER_OK}, {d->utf8, "", 0, 8, "", YASL_PRIVATE_TRANSFER_OK}, {d->utf8, "\xff", 1, 8, NULL, YASL_PRIVATE_TRANSFER_FAILED}, - {d->incr, NULL, 1, 32, NULL, YASL_PRIVATE_TRANSFER_FAILED}, }; for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { struct paste_request *pending = calloc(1, sizeof(*pending)); @@ -66,11 +67,8 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface * assert(pending->timeout); pending->next = d->pastes; d->pastes = pending; - unsigned long incr_bytes = 4096; - const void *bytes = cases[i].bytes; - if (cases[i].type == d->incr) bytes = &incr_bytes; XChangeProperty(d->native, pending->window, property, cases[i].type, - cases[i].format, PropModeReplace, bytes, (int)cases[i].len); + cases[i].format, PropModeReplace, cases[i].bytes, (int)cases[i].len); XSelectionEvent reply = {.requestor = pending->window, .property = property}; selection_notify(d, &reply); struct yasl_private_event event; @@ -81,15 +79,37 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface * assert(event.text.len == strlen(cases[i].expected)); assert(strcmp(event.text.data, cases[i].expected) == 0); } - if (cases[i].type == d->incr) { - assert(d->pastes == pending && !pending->target); - assert(yasl_private_loop_del_timer(d->loop, pending->timeout)); - pending->timeout = 0; - paste_timeout(pending, 0, PASTE_TIMEOUT_NS); - } assert(!yasl_private_display_poll_event(&d->base, &event)); } + /* INCR: the owner announces a size, then writes chunks until an empty one. */ + struct paste_request *incr = calloc(1, sizeof(*incr)); + assert(incr); + incr->display = d; + incr->window = XCreateSimpleWindow(d->native, DefaultRootWindow(d->native), 0, 0, 1, 1, 0, 0, 0); + incr->target = s; + incr->id = 9; + incr->timeout = yasl_private_loop_add_timer(d->loop, PASTE_TIMEOUT_NS, paste_timeout, incr); + assert(incr->timeout); + incr->next = d->pastes; + d->pastes = incr; + unsigned long incr_bytes = 5; + XChangeProperty(d->native, incr->window, d->paste_property, d->incr, 32, PropModeReplace, + (const unsigned char *)&incr_bytes, 1); + selection_notify(d, &(XSelectionEvent){.requestor = incr->window, .property = d->paste_property}); + struct yasl_private_event event; + assert(incr->incr && !yasl_private_display_poll_event(&d->base, &event)); + const char *chunks[] = {"inc", "r\xc3\xa9", ""}; + for (size_t i = 0; i < sizeof(chunks) / sizeof(chunks[0]); i++) { + XChangeProperty(d->native, incr->window, d->paste_property, d->utf8, 8, PropModeReplace, + (const unsigned char *)chunks[i], (int)strlen(chunks[i])); + assert(paste_incr_property(d, &(XPropertyEvent){.window = incr->window, + .atom = d->paste_property, .state = PropertyNewValue})); + } + assert(yasl_private_display_poll_event(&d->base, &event)); + assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == 9 && + event.paste.status == YASL_PRIVATE_TRANSFER_OK && !strcmp(event.paste.data, "incr\xc3\xa9")); + struct paste_request *rejected = calloc(1, sizeof(*rejected)); assert(rejected); rejected->window = XCreateSimpleWindow(d->native, DefaultRootWindow(d->native), @@ -101,7 +121,6 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface * d->pastes = rejected; XSelectionEvent no_property = {.requestor = rejected->window, .property = None}; selection_notify(d, &no_property); - struct yasl_private_event event; assert(yasl_private_display_poll_event(&d->base, &event)); assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == 99); assert(event.paste.status == YASL_PRIVATE_TRANSFER_FAILED); -- cgit v1.2.3