Three fixes: 1. Patch 0000 now compiles standalone: replaced forward declaration of ns_ax_face_is_selected (defined in VoiceOver patches) with self-contained ns_zoom_face_is_selected in the Zoom patch. 2. ns_accessibility_enabled defaults to nil: eliminates ALL VoiceOver overhead (text cache rebuild, AX notifications, Mach IPC to AX server) when VoiceOver is not in use. Zero per-redisplay cost. Enable with (setq ns-accessibility-enabled t). 3. UAZoomEnabled() cached for 1s + ns_zoom_track_completion rate- limited to 2Hz: eliminates 150-600µs/frame of IPC overhead.
78 lines
3.4 KiB
Diff
78 lines
3.4 KiB
Diff
From ec00458c25db0fbf4af2eeb4c88e59c0af7d2063 Mon Sep 17 00:00:00 2001
|
|
From: Daneel <daneel@sukany.cz>
|
|
Date: Sun, 1 Mar 2026 04:56:16 +0100
|
|
Subject: [PATCH 10/11] perf: use BUF_CHARS_MODIFF for AX text cache validity
|
|
in ensureTextCache
|
|
|
|
The cache validity check in -[EmacsAccessibilityBuffer ensureTextCache]
|
|
used BUF_MODIFF, which is bumped by every text-property change ---
|
|
including face applications by font-lock on each redisplay cycle.
|
|
Since the AX text value contains only characters (no face or property
|
|
data), property-only changes do not affect it. Rebuilding the full
|
|
buffer text on each font-lock pass is O(buffer-size) per redisplay,
|
|
causing progressive slowdown proportional to how far the cursor is
|
|
from the beginning of the file.
|
|
|
|
Switch to BUF_CHARS_MODIFF, which is bumped only when characters are
|
|
actually inserted or deleted. This matches the semantic of 'did the
|
|
text change' and is the approach used by WebKit and NSTextView.
|
|
|
|
BUF_OVERLAY_MODIFF is intentionally not tracked here (unchanged):
|
|
overlay content is handled by separate announcements in
|
|
postAccessibilityNotificationsForFrame, and including it in this
|
|
check would prevent those announcements from firing.
|
|
---
|
|
src/nsterm.m | 27 ++++++++++++++++++---------
|
|
1 file changed, 18 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/src/nsterm.m b/src/nsterm.m
|
|
index d576512..1da6f41 100644
|
|
--- a/src/nsterm.m
|
|
+++ b/src/nsterm.m
|
|
@@ -8168,16 +8168,25 @@ - (void)ensureTextCache
|
|
if (!b)
|
|
return;
|
|
|
|
- ptrdiff_t modiff = BUF_MODIFF (b);
|
|
- ptrdiff_t pt = BUF_PT (b);
|
|
- NSUInteger textLen = cachedText ? [cachedText length] : 0;
|
|
- /* Cache validity: track BUF_MODIFF and buffer narrowing.
|
|
+ /* Use BUF_CHARS_MODIFF, not BUF_MODIFF, for cache validity.
|
|
+ BUF_MODIFF is bumped by every text-property change, including
|
|
+ font-lock face applications on every redisplay. AX text contains
|
|
+ only characters, not face data, so property-only changes do not
|
|
+ affect the cached value. Rebuilding the full buffer text on
|
|
+ each font-lock pass is O(buffer-size) per redisplay --- this
|
|
+ causes progressive slowdown when scrolling through large files.
|
|
+ BUF_CHARS_MODIFF is bumped only on actual character insertions
|
|
+ and deletions, matching the semantic of "did the text change".
|
|
+ This is the pattern used by WebKit and NSTextView.
|
|
Do NOT track BUF_OVERLAY_MODIFF here --- overlay text is not
|
|
included in the cached AX text (it is handled separately via
|
|
- explicit announcements). Including overlay_modiff would
|
|
- silently update cachedOverlayModiff and prevent the
|
|
- notification dispatch from detecting overlay changes. */
|
|
- if (cachedText && cachedTextModiff == modiff
|
|
+ explicit announcements in postAccessibilityNotificationsForFrame).
|
|
+ Including overlay_modiff would silently update cachedOverlayModiff
|
|
+ and prevent the notification dispatch from detecting changes. */
|
|
+ ptrdiff_t chars_modiff = BUF_CHARS_MODIFF (b);
|
|
+ ptrdiff_t pt = BUF_PT (b);
|
|
+ NSUInteger textLen = cachedText ? [cachedText length] : 0;
|
|
+ if (cachedText && cachedTextModiff == chars_modiff
|
|
&& cachedTextStart == BUF_BEGV (b)
|
|
&& pt >= cachedTextStart
|
|
&& (textLen == 0
|
|
@@ -8193,7 +8202,7 @@ included in the cached AX text (it is handled separately via
|
|
{
|
|
[cachedText release];
|
|
cachedText = [text retain];
|
|
- cachedTextModiff = modiff;
|
|
+ cachedTextModiff = chars_modiff;
|
|
cachedTextStart = start;
|
|
|
|
if (visibleRuns)
|
|
--
|
|
2.43.0
|
|
|