diff options
Diffstat (limited to 'src/cocoa')
| -rw-r--r-- | src/cocoa/api.h | 1 | ||||
| -rw-r--r-- | src/cocoa/window.m | 83 |
2 files changed, 73 insertions, 11 deletions
diff --git a/src/cocoa/api.h b/src/cocoa/api.h index ad259df..2fea415 100644 --- a/src/cocoa/api.h +++ b/src/cocoa/api.h @@ -10,6 +10,7 @@ struct cocoa_display *cocoa_display_open(struct yasl_loop *loop, const struct ya void cocoa_display_close(struct cocoa_display *d); uint32_t cocoa_display_caps(const struct cocoa_display *d); void cocoa_display_dispatch(struct cocoa_display *d); +int cocoa_display_dispatch_timeout(struct cocoa_display *d, int timeout_ms); void cocoa_display_flush(struct cocoa_display *d); int cocoa_display_modifiers(const struct cocoa_display *d); void cocoa_display_copy(struct cocoa_display *d, enum yasl_selection sel, const char *text); diff --git a/src/cocoa/window.m b/src/cocoa/window.m index bc6060f..8712ce8 100644 --- a/src/cocoa/window.m +++ b/src/cocoa/window.m @@ -320,14 +320,36 @@ static void push_pointer(struct cocoa_surface *w, NSEvent *ev, enum yasl_pointer w->mods = cocoa_mods(ev.modifierFlags); if (kind != YASL_PTR_LEAVE) w->pointer = event_pos(w, ev); + + enum yasl_pointer_device device = YASL_PTR_DEV_MOUSE; + struct yasl_pointer_pen pen = {0}; + + float press = (float)ev.pressure; + if (ev.subtype == NSEventSubtypeTabletPoint || press > 0.0f) { + if (ev.pointingDeviceType == NSPointingDeviceTypeEraser) + device = YASL_PTR_DEV_ERASER; + else if (ev.pointingDeviceType == NSPointingDeviceTypePen) + device = YASL_PTR_DEV_PEN; + + if (press > 1.0f) press = 1.0f; + if (press > 0.0f) + pen.pressure = (uint16_t)(press * 65535.0f); + + NSPoint tilt = ev.tilt; + pen.tilt_x = (int8_t)(tilt.x * 90.0); + pen.tilt_y = (int8_t)(tilt.y * 90.0); + } + struct yasl_input_event input_ev = { - .kind = YASL_INPUT_MOUSE, .surface = &w->base, + .kind = YASL_INPUT_MOUSE, .mouse = { .pos = w->pointer, - .button = button, + .button = (int16_t)button, .kind = kind, + .device = device, .mods = w->mods, + .pen = pen, }, }; input_queue_push(&w->input, &input_ev); @@ -871,29 +893,62 @@ static void pump_window(struct cocoa_surface *w) @autoreleasepool { render_and_commit(w); } } -void cocoa_display_dispatch(struct cocoa_display *d) +int cocoa_display_dispatch_timeout(struct cocoa_display *d, int timeout_ms) { assert([NSThread isMainThread]); if (!d || d->pumping) - return; + return -1; d->pumping = true; d->depth++; + int count = 0; @try { - for (;;) { - @autoreleasepool { - NSEvent *ev = [NSApp nextEventMatchingMask:NSEventMaskAny - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (!ev) break; + NSDate *limitDate; + if (timeout_ms == 0) + limitDate = [NSDate distantPast]; + else if (timeout_ms < 0) + limitDate = [NSDate distantFuture]; + else + limitDate = [NSDate dateWithTimeIntervalSinceNow:(double)timeout_ms / 1000.0]; + + @autoreleasepool { + NSEvent *ev = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:limitDate + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (ev) { + count++; [NSApp sendEvent:ev]; [NSApp updateWindows]; + + while ((ev = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES])) { + count++; + [NSApp sendEvent:ev]; + [NSApp updateWindows]; + } } } } @finally { d->depth--; d->pumping = false; } + return count; +} + +void cocoa_display_dispatch(struct cocoa_display *d) +{ + if (!d) return; + bool immediate = false; + for (int i = 0; i < d->count; i++) { + struct cocoa_surface *w = d->windows[i]; + if (w->input.count > 0 || (w->want_draw && (!w->link || w->frame_due || w->unpaced))) { + immediate = true; + break; + } + } + cocoa_display_dispatch_timeout(d, immediate ? 0 : -1); } void cocoa_display_flush(struct cocoa_display *d) @@ -1388,6 +1443,11 @@ static void impl_display_dispatch(struct yasl_display *d) cocoa_display_dispatch((struct cocoa_display *)d); } +static int impl_display_dispatch_timeout(struct yasl_display *d, int timeout_ms) +{ + return cocoa_display_dispatch_timeout((struct cocoa_display *)d, timeout_ms); +} + static void impl_display_flush(struct yasl_display *d) { cocoa_display_flush((struct cocoa_display *)d); @@ -1562,6 +1622,7 @@ const struct yasl_backend_ops yasl_cocoa_backend = { .display_close = impl_display_close, .display_caps = impl_display_caps, .display_dispatch = impl_display_dispatch, + .display_dispatch_timeout = impl_display_dispatch_timeout, .display_flush = impl_display_flush, .display_modifiers = impl_display_modifiers, .display_copy = impl_display_copy, |
