From 76073fe5fad8799e5850805f2f090af2cb62c741 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Tue, 13 Oct 2026 23:41:31 +0300 Subject: 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 --- tests/cocoa/test_ownership.m | 154 +++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 57 deletions(-) (limited to 'tests/cocoa/test_ownership.m') diff --git a/tests/cocoa/test_ownership.m b/tests/cocoa/test_ownership.m index 6d69907..4efd164 100644 --- a/tests/cocoa/test_ownership.m +++ b/tests/cocoa/test_ownership.m @@ -1,7 +1,9 @@ -#include "yasl/native.h" -#include "yasl/native/cocoa.h" +#include "common/private_native.h" +#include "common/private_native_cocoa.h" +#include "common/backend.h" #import -#include "yasl/yasl.h" +#import +#include "common/types.h" #include #include #include @@ -9,60 +11,98 @@ int main(void) { - struct yasl_display *d = yasl_display_open(NULL, NULL); + struct yasl_private_display *d = yasl_private_display_open(NULL, NULL); assert(d); - struct yasl_window_spec spec = {.title = "Ownership test", .size = {160, 100}}; - struct yasl_surface *s = yasl_surface_create_toplevel(d, &spec); + assert(yasl_private_display_caps(d) & YASL_PRIVATE_CAP_TEXT_INPUT); + struct yasl_private_window_spec spec = {.title = "Ownership test", .size = {160, 100}}; + struct yasl_surface *s = yasl_private_surface_create_toplevel(d, &spec); assert(s); - assert(yasl_display_get_native_handle(d) == (void *)NSApp); - assert(yasl_cocoa_display_get_application(d) == NSApp); - NSWindow *window = (NSWindow *)yasl_surface_get_native_handle(s); - assert(yasl_cocoa_surface_get_window(s) == window); - assert(yasl_cocoa_surface_get_view(s) == window.contentView); + assert(yasl_private_display_get_native_handle(d) == (void *)NSApp); + assert(yasl_private_cocoa_display_get_application(d) == NSApp); + NSWindow *window = (NSWindow *)yasl_private_surface_get_native_handle(s); + assert(yasl_private_cocoa_surface_get_window(s) == window); + assert(yasl_private_cocoa_surface_get_view(s) == window.contentView); assert([window isKindOfClass:[NSWindow class]] && window.contentView); - struct yasl_event event; - while (yasl_display_poll_event(d, &event)) {} + struct yasl_private_event event; + while (yasl_private_display_poll_event(d, &event)) {} - assert(yasl_surface_set_size(s, (struct yasl_vector2i){180, 110})); - assert(yasl_surface_set_fullscreen(s, false)); - assert(yasl_surface_set_maximized(s, false)); - assert(!yasl_surface_set_size(s, (struct yasl_vector2i){0, 100})); + struct yasl_private_window_spec gpu_spec = { + .flags = YASL_PRIVATE_SURFACE_HIDDEN | YASL_PRIVATE_SURFACE_UNDECORATED | + YASL_PRIVATE_SURFACE_FIXED_SIZE, + .external_gpu = true, + .title = "External GPU test", + .size = {160, 100}, + }; + struct yasl_surface *gpu = yasl_private_surface_create_toplevel(d, &gpu_spec); + assert(gpu && gpu->presenter == YASL_PRIVATE_PRESENTER_NONE); + CAMetalLayer *metal = (CAMetalLayer *)d->ops->surface_get_metal_layer(gpu); + assert(metal && [metal isKindOfClass:[CAMetalLayer class]] && !metal.device); + NSWindow *hidden = (NSWindow *)yasl_private_surface_get_native_handle(gpu); + assert(!hidden.isVisible && hidden.styleMask == NSWindowStyleMaskBorderless); + yasl_private_surface_destroy(gpu); + + struct yasl_surface *gl = d->ops->surface_create_gl(d, &gpu_spec, NULL, NULL); + if (gl) { + assert(gl->presenter == YASL_PRIVATE_PRESENTER_GL); + assert(d->ops->gl_make_current(d, gl)); + assert(d->ops->gl_get_proc_address(d, "glClear") != NULL); + assert(d->ops->gl_swap_interval(d, gl, 1)); + assert(d->ops->gl_swap_buffers(d, gl)); + assert(d->ops->gl_make_current(d, NULL)); + d->ops->surface_destroy(gl); + } + + assert(yasl_private_surface_set_size(s, (struct yasl_private_vector2i){180, 110})); + assert(yasl_private_surface_set_fullscreen(s, false)); + assert(yasl_private_surface_set_maximized(s, false)); + assert(!yasl_private_surface_set_size(s, (struct yasl_private_vector2i){0, 100})); assert(errno == EINVAL); - struct yasl_popup_spec popup_spec = { + struct yasl_private_popup_spec popup_spec = { + .positioner_explicit = true, + .anchor_edges = 4, .gravity = 3, .constraints = 63, .size = {80, 40}, .anchor = {10, 10, 2, 2}, }; - struct yasl_surface *popup = yasl_surface_create_popup(s, &popup_spec); + struct yasl_surface *popup = yasl_private_surface_create_popup(s, &popup_spec); assert(popup); - assert(!yasl_surface_set_size(popup, (struct yasl_vector2i){80, 40})); + popup_spec.anchor_edges = 8; + popup_spec.gravity = 5; + assert(yasl_private_surface_popup_reposition(popup, &popup_spec)); + assert(!yasl_private_surface_set_size(popup, (struct yasl_private_vector2i){80, 40})); assert(errno == EINVAL); - assert(!yasl_surface_set_fullscreen(popup, true) && errno == EINVAL); - assert(!yasl_surface_set_maximized(popup, true) && errno == EINVAL); - assert(!yasl_surface_minimize(popup) && errno == EINVAL); - yasl_surface_destroy(popup); - while (yasl_display_poll_event(d, &event)) {} + assert(!yasl_private_surface_set_fullscreen(popup, true) && errno == EINVAL); + assert(!yasl_private_surface_set_maximized(popup, true) && errno == EINVAL); + assert(!yasl_private_surface_minimize(popup) && errno == EINVAL); + yasl_private_surface_destroy(popup); + while (yasl_private_display_poll_event(d, &event)) {} - id text_input = (id)yasl_cocoa_surface_get_view(s); + s->text_input_active = true; + s->text_surrounding = strdup("é漢"); + s->text_length = strlen(s->text_surrounding); + s->text_begin = 0; + s->text_end = s->text_length; + assert(d->ops->surface_update_text_input(s)); + id text_input = (id)yasl_private_cocoa_surface_get_view(s); [text_input setMarkedText:@"é漢" selectedRange:NSMakeRange(1, 1) replacementRange:NSMakeRange(NSNotFound, 0)]; - assert(strcmp(yasl_surface_ime_preedit(s), "é漢") == 0); + assert(strcmp(yasl_private_surface_ime_preedit(s), "é漢") == 0); [text_input unmarkText]; - assert(yasl_surface_ime_preedit(s) == NULL); - assert(yasl_display_poll_event(d, &event)); - assert(event.type == YASL_EVENT_COMPOSITION && event.composition.active); + assert(yasl_private_surface_ime_preedit(s) == NULL); + assert(yasl_private_display_poll_event(d, &event)); + assert(event.type == YASL_PRIVATE_EVENT_COMPOSITION && event.composition.active); assert(strcmp(event.composition.data, "é漢") == 0); assert(event.composition.begin == 2 && event.composition.end == 5); - assert(yasl_display_poll_event(d, &event)); - assert(event.type == YASL_EVENT_COMPOSITION && !event.composition.active); + assert(yasl_private_display_poll_event(d, &event)); + assert(event.type == YASL_PRIVATE_EVENT_COMPOSITION && !event.composition.active); assert(event.composition.begin == -1 && event.composition.end == -1); - while (yasl_display_poll_event(d, &event)) {} + while (yasl_private_display_poll_event(d, &event)) {} uint64_t request_ids[600]; @autoreleasepool { for (int i = 0; i < 600; i++) { char text[32]; snprintf(text, sizeof(text), "paste-%d", i); - assert(yasl_clipboard_set(d, YASL_CLIPBOARD, text)); - request_ids[i] = yasl_clipboard_request(s, YASL_CLIPBOARD); + assert(yasl_private_clipboard_set(d, YASL_PRIVATE_CLIPBOARD, text)); + request_ids[i] = yasl_private_clipboard_request(s, YASL_PRIVATE_CLIPBOARD); assert(request_ids[i] != 0); memset(text, 'x', sizeof(text)); } @@ -71,32 +111,32 @@ int main(void) for (int i = 0; i < 600; i++) { char text[32]; snprintf(text, sizeof(text), "paste-%d", i); - assert(yasl_display_poll_event(d, &event)); - assert(event.type == YASL_EVENT_PASTE && event.paste.request_id == request_ids[i]); - assert(event.paste.status == YASL_TRANSFER_OK && strcmp(event.paste.data, text) == 0); + assert(yasl_private_display_poll_event(d, &event)); + assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == request_ids[i]); + assert(event.paste.status == YASL_PRIVATE_TRANSFER_OK && strcmp(event.paste.data, text) == 0); } const char *last = event.paste.data; - assert(!yasl_display_poll_event(d, &event)); - @autoreleasepool { yasl_display_copy(d, YASL_CLIPBOARD, "new selection"); } + assert(!yasl_private_display_poll_event(d, &event)); + @autoreleasepool { yasl_private_display_copy(d, YASL_PRIVATE_CLIPBOARD, "new selection"); } assert(strcmp(last, "paste-599") == 0); - assert(!yasl_clipboard_set(d, YASL_CLIPBOARD, "\xc3")); + assert(!yasl_private_clipboard_set(d, YASL_PRIVATE_CLIPBOARD, "\xc3")); assert(errno == EILSEQ); - assert(yasl_clipboard_set(d, YASL_CLIPBOARD, "")); - uint64_t empty_id = yasl_clipboard_request(s, YASL_CLIPBOARD); - assert(empty_id && yasl_display_poll_event(d, &event)); - assert(event.type == YASL_EVENT_PASTE && event.paste.request_id == empty_id); - assert(event.paste.status == YASL_TRANSFER_OK && !event.paste.len && !event.paste.data[0]); + assert(yasl_private_clipboard_set(d, YASL_PRIVATE_CLIPBOARD, "")); + uint64_t empty_id = yasl_private_clipboard_request(s, YASL_PRIVATE_CLIPBOARD); + assert(empty_id && yasl_private_display_poll_event(d, &event)); + assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == empty_id); + assert(event.paste.status == YASL_PRIVATE_TRANSFER_OK && !event.paste.len && !event.paste.data[0]); [NSPasteboard.generalPasteboard clearContents]; - uint64_t unavailable_id = yasl_clipboard_request(s, YASL_CLIPBOARD); - assert(unavailable_id && yasl_display_poll_event(d, &event)); - assert(event.type == YASL_EVENT_PASTE && event.paste.request_id == unavailable_id); - assert(event.paste.status == YASL_TRANSFER_UNAVAILABLE && !event.paste.len); - yasl_display_copy(d, YASL_CLIPBOARD, "legacy paste"); - yasl_display_paste(d, YASL_CLIPBOARD, s); - assert(yasl_display_poll_event(d, &event)); - assert(event.type == YASL_EVENT_PASTE && event.paste.request_id == 0); - assert(event.paste.status == YASL_TRANSFER_OK && strcmp(event.text.data, "legacy paste") == 0); - yasl_surface_destroy(s); - yasl_display_close(d); + uint64_t unavailable_id = yasl_private_clipboard_request(s, YASL_PRIVATE_CLIPBOARD); + assert(unavailable_id && yasl_private_display_poll_event(d, &event)); + assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == unavailable_id); + assert(event.paste.status == YASL_PRIVATE_TRANSFER_UNAVAILABLE && !event.paste.len); + yasl_private_display_copy(d, YASL_PRIVATE_CLIPBOARD, "legacy paste"); + yasl_private_display_paste(d, YASL_PRIVATE_CLIPBOARD, s); + assert(yasl_private_display_poll_event(d, &event)); + assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == 0); + assert(event.paste.status == YASL_PRIVATE_TRANSFER_OK && strcmp(event.text.data, "legacy paste") == 0); + yasl_private_surface_destroy(s); + yasl_private_display_close(d); return 0; } -- cgit v1.2.3