patches: squash perf fixes into respective patches, clean 9-patch series

Performance fixes folded back:
- BUF_CHARS_MODIFF → patch 0002 (implement buffer accessibility element)
- UAZoomEnabled cache + rate-limit → patch 0000 (Zoom integration)

Also in patch 0000: ns_zoom_face_is_selected (standalone compilation).
Also in patch 0001: ns_accessibility_enabled defaults to nil.
This commit is contained in:
2026-03-01 05:58:42 +01:00
parent 1bf05f1e22
commit 07826b61a0
10 changed files with 205 additions and 188 deletions

View File

@@ -1,7 +1,7 @@
From e0f4378588b0fea142d707e4b51269566e50536a Mon Sep 17 00:00:00 2001
From 5637c7ec4d3511e42bca8e5b1cb628cc2d2200ad Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 22:39:35 +0100
Subject: [PATCH 01/11] ns: integrate with macOS Zoom for cursor tracking
Subject: [PATCH 1/9] ns: integrate with macOS Zoom for cursor tracking
Inform macOS Zoom of the text cursor position so the zoomed viewport
follows keyboard focus in Emacs.
@@ -38,8 +38,8 @@ window splits, switches (C-x o), and completion frameworks.
---
etc/NEWS | 11 ++
src/nsterm.h | 6 +
src/nsterm.m | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 324 insertions(+)
src/nsterm.m | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 358 insertions(+)
diff --git a/etc/NEWS b/etc/NEWS
index ef36df5..80661a9 100644
@@ -81,10 +81,10 @@ index 7c1ee4c..ea6e7ba 100644
}
diff --git a/src/nsterm.m b/src/nsterm.m
index 74e4ad5..40b4bc9 100644
index 74e4ad5..f189c9e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1081,6 +1081,236 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
@@ -1081,6 +1081,270 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
}
@@ -93,6 +93,29 @@ index 74e4ad5..40b4bc9 100644
+#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
+ && MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+
+/* Cached wrapper around ns_zoom_enabled_p ().
+ ns_zoom_enabled_p () performs a synchronous Mach IPC roundtrip to the
+ macOS Accessibility server (~50-200 µs per call). With call sites
+ in ns_draw_window_cursor, ns_update_end, and ns_zoom_track_completion,
+ the overhead accumulates to ~150-600 µs per redisplay cycle. Zoom
+ state changes only on explicit user action in System Settings, so a
+ 1-second TTL is safe and indistinguishable from querying every frame.
+ Uses CFAbsoluteTimeGetCurrent() (~5 ns, a VDSO read) for timing. */
+static BOOL ns_zoom_cached_enabled;
+static CFAbsoluteTime ns_zoom_cache_time;
+
+static BOOL
+ns_zoom_enabled_p (void)
+{
+ CFAbsoluteTime now = CFAbsoluteTimeGetCurrent ();
+ if (now - ns_zoom_cache_time > 1.0)
+ {
+ ns_zoom_cached_enabled = UAZoomEnabled ();
+ ns_zoom_cache_time = now;
+ }
+ return ns_zoom_cached_enabled;
+}
+
+/* Identify faces that mark a selected completion candidate.
+ Matches vertico-current, corfu-current, icomplete-selected-match,
+ ivy-current-match, etc. by checking the face symbol name.
@@ -241,11 +264,22 @@ index 74e4ad5..40b4bc9 100644
+static void
+ns_zoom_track_completion (struct frame *f, EmacsView *view)
+{
+ if (!UAZoomEnabled ())
+ if (!ns_zoom_enabled_p ())
+ return;
+ if (!WINDOWP (f->selected_window))
+ return;
+
+ /* Rate-limit completion scan to 2 Hz. Completion state changes at
+ human interaction speed; checking every 500 ms eliminates
+ per-redisplay FOR_EACH_FRAME overhead with no perceptible lag. */
+ {
+ static CFAbsoluteTime last_check;
+ CFAbsoluteTime now = CFAbsoluteTimeGetCurrent ();
+ if (now - last_check < 0.5)
+ return;
+ last_check = now;
+ }
+
+ specpdl_ref count = SPECPDL_INDEX ();
+ record_unwind_current_buffer ();
+
@@ -321,7 +355,7 @@ index 74e4ad5..40b4bc9 100644
static void
ns_update_end (struct frame *f)
/* --------------------------------------------------------------------------
@@ -1104,6 +1334,41 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
@@ -1104,6 +1368,41 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
unblock_input ();
ns_updating_frame = NULL;
@@ -333,7 +367,7 @@ index 74e4ad5..40b4bc9 100644
+ (zoomCursorUpdated is NO). */
+#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
+ && MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+ if (view && !view->zoomCursorUpdated && UAZoomEnabled ()
+ if (view && !view->zoomCursorUpdated && ns_zoom_enabled_p ()
+ && !NSIsEmptyRect (view->lastCursorRect))
+ {
+ NSRect r = view->lastCursorRect;
@@ -363,7 +397,7 @@ index 74e4ad5..40b4bc9 100644
}
static void
@@ -3232,6 +3497,45 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
@@ -3232,6 +3531,45 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
/* Prevent the cursor from being drawn outside the text area. */
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
@@ -386,7 +420,7 @@ index 74e4ad5..40b4bc9 100644
+
+#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
+ && MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+ if (UAZoomEnabled ())
+ if (ns_zoom_enabled_p ())
+ {
+ NSRect windowRect = [view convertRect:r toView:nil];
+ NSRect screenRect
@@ -409,7 +443,7 @@ index 74e4ad5..40b4bc9 100644
ns_focus (f, NULL, 0);
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
@@ -8321,6 +8625,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
@@ -8321,6 +8659,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
windowClosing = NO;
processingCompose = NO;