summaryrefslogtreecommitdiff
path: root/src/cocoa
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-11 23:27:41 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-11 23:27:41 +0300
commit472ed3e4e50a165638acecaf071ec3c2c13c451f (patch)
treed1894debde800d8e87d3c242ae6c3f4760c68787 /src/cocoa
parent8d9f7c7cb39359d62bf28ef1775b944a7dddd6fb (diff)
core: optimize struct layouts, eliminate branches, and fix event loop dispatch
- Fix Wayland event loop lockout by properly decoupling read arming and adding poll-backed dispatching - Support standalone display lifecycle without requiring caller to manage a loop - Eliminate alignment holes across yasl_surface, yasl_display, seat, touch_point, and conn_drag using pahole - Replace branching state/button decoders with compile-time locked LUTs and branchless bitwise operations - Accelerate UTF-8 validation with 64-bit word scanning for ASCII runs
Diffstat (limited to 'src/cocoa')
-rw-r--r--src/cocoa/window.m51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/cocoa/window.m b/src/cocoa/window.m
index 0edf694..6c28f3f 100644
--- a/src/cocoa/window.m
+++ b/src/cocoa/window.m
@@ -843,29 +843,62 @@ static void pump_window(struct yasl_surface *w)
@autoreleasepool { render_and_commit(w); }
}
-void yasl_display_dispatch(struct yasl_display *d)
+int yasl_display_dispatch_timeout(struct yasl_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 yasl_display_dispatch(struct yasl_display *d)
+{
+ if (!d) return;
+ bool immediate = false;
+ for (int i = 0; i < d->count; i++) {
+ struct yasl_surface *w = d->windows[i];
+ if (w->input.count > 0 || (w->want_draw && (!w->link || w->frame_due || w->unpaced))) {
+ immediate = true;
+ break;
+ }
+ }
+ yasl_display_dispatch_timeout(d, immediate ? 0 : -1);
}
void yasl_display_flush(struct yasl_display *d)