diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-14 14:21:13 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-14 14:21:13 +0300 |
| commit | 7ad4f86f2aac75935a52d31383593c1327204729 (patch) | |
| tree | 6a2fa7baad55232e79fee613f342abe31c4d4336 | |
| parent | 7e8bf8d2a81f37303e0c9ae430f1acbff106da22 (diff) | |
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 <noreply@anthropic.com>
| -rw-r--r-- | src/common/surface.c | 1 | ||||
| -rw-r--r-- | src/platform/wayland/pointer.c | 3 | ||||
| -rw-r--r-- | src/platform/wayland/shell.c | 8 | ||||
| -rw-r--r-- | tests/common/test_surface_integration.c | 5 | ||||
| -rw-r--r-- | tests/x11/test_input.c | 49 |
5 files changed, 47 insertions, 19 deletions
diff --git a/src/common/surface.c b/src/common/surface.c index b9231ea..fa8ee3d 100644 --- a/src/common/surface.c +++ b/src/common/surface.c @@ -392,6 +392,7 @@ int yasl_surface_set_cursor(yasl_surface *s, enum yasl_cursor cursor) if ((unsigned)cursor > YASL_CURSOR_LOCKED) return yasl_public_error(EINVAL); bool locked = cursor == YASL_CURSOR_LOCKED; + errno = 0; if (!yasl_private_surface_set_pointer_mode(s, locked ? YASL_PRIVATE_POINTER_RELATIVE : YASL_PRIVATE_POINTER_NORMAL)) return yasl_public_error(errno); diff --git a/src/platform/wayland/pointer.c b/src/platform/wayland/pointer.c index 9f8ca49..571bb12 100644 --- a/src/platform/wayland/pointer.c +++ b/src/platform/wayland/pointer.c @@ -59,6 +59,9 @@ uint32_t seat_held_press_serial(const struct seat *s) { if (!s) return 0; bool held = s->pointer_buttons != 0 || (s->tool && s->tool->in_contact); + /* A touch contact is a press too; touch_down records its serial. */ + for (int i = 0; !held && i < SEAT_TOUCH_POINTS; i++) + held = s->touch_points[i].active; return held ? s->press_serial : 0; } diff --git a/src/platform/wayland/shell.c b/src/platform/wayland/shell.c index 8e6b67e..12c73e0 100644 --- a/src/platform/wayland/shell.c +++ b/src/platform/wayland/shell.c @@ -1,5 +1,7 @@ #include "internal.h" +#include <errno.h> + static void wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial); static const struct xdg_wm_base_listener wm_base_listener; @@ -421,7 +423,11 @@ int surface_init_shell(struct wayland_surface *w, const char *title) bool wayland_surface_bell(struct wayland_surface *w) { - if (!w || w->closed || !w->conn || !w->conn->system_bell || !w->surface) return false; + if (!w || w->closed || !w->conn || !w->surface) return false; + if (!w->conn->system_bell) { + errno = ENOTSUP; /* The compositor lacks xdg-system-bell. */ + return false; + } xdg_system_bell_v1_ring(w->conn->system_bell, w->surface); return true; } 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); |
