summaryrefslogtreecommitdiff
path: root/src/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/cocoa')
-rw-r--r--src/cocoa/api.h1
-rw-r--r--src/cocoa/window.m83
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,