patches: fix fold/unfold AX cache regression (BUF_OVERLAY_MODIFF)

This commit is contained in:
2026-03-01 13:43:25 +01:00
parent e969011b87
commit 6703914305

View File

@@ -1,4 +1,4 @@
From 17cd7eabf984a7de09ac277b4831836a44c4cf81 Mon Sep 17 00:00:00 2001 From 1cbef245410db30407aa55f7d1290e879705a491 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 16:01:29 +0100 Date: Sat, 28 Feb 2026 16:01:29 +0100
Subject: [PATCH 8/8] ns: announce child frame completion candidates for Subject: [PATCH 8/8] ns: announce child frame completion candidates for
@@ -19,9 +19,9 @@ element when a child frame completion closes.
--- ---
doc/emacs/macos.texi | 6 - doc/emacs/macos.texi | 6 -
etc/NEWS | 4 +- etc/NEWS | 4 +-
src/nsterm.h | 5 + src/nsterm.h | 9 ++
src/nsterm.m | 265 +++++++++++++++++++++++++++++++++++++++++-- src/nsterm.m | 275 +++++++++++++++++++++++++++++++++++++++++--
4 files changed, 262 insertions(+), 18 deletions(-) 4 files changed, 276 insertions(+), 18 deletions(-)
diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index 6514dfc..f47929e 100644 index 6514dfc..f47929e 100644
@@ -63,10 +63,21 @@ index 2b1f9e6..8a40850 100644
for the *Completions* buffer. The implementation uses a virtual for the *Completions* buffer. The implementation uses a virtual
accessibility tree with per-window elements, hybrid SelectedTextChanged accessibility tree with per-window elements, hybrid SelectedTextChanged
diff --git a/src/nsterm.h b/src/nsterm.h diff --git a/src/nsterm.h b/src/nsterm.h
index 21a93bc..75c731f 100644 index 21a93bc..bbce9fe 100644
--- a/src/nsterm.h --- a/src/nsterm.h
+++ b/src/nsterm.h +++ b/src/nsterm.h
@@ -596,6 +596,10 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType) @@ -507,6 +507,10 @@ typedef struct ns_ax_visible_run
}
@property (nonatomic, retain) NSString *cachedText;
@property (nonatomic, assign) ptrdiff_t cachedTextModiff;
+/* Overlay modiff at last text cache rebuild. Tracked separately from
+ cachedOverlayModiff (which is used for completion announcements) so
+ that fold/unfold detection is independent of notification dispatch. */
+@property (nonatomic, assign) ptrdiff_t cachedOverlayModiffForText;
@property (nonatomic, assign) ptrdiff_t cachedOverlayModiff;
@property (nonatomic, assign) ptrdiff_t cachedTextStart;
@property (nonatomic, assign) ptrdiff_t cachedModiff;
@@ -596,6 +600,10 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType)
Lisp_Object lastRootWindow; Lisp_Object lastRootWindow;
BOOL accessibilityTreeValid; BOOL accessibilityTreeValid;
BOOL accessibilityUpdating; BOOL accessibilityUpdating;
@@ -77,7 +88,7 @@ index 21a93bc..75c731f 100644
#endif #endif
BOOL font_panel_active; BOOL font_panel_active;
NSFont *font_panel_result; NSFont *font_panel_result;
@@ -665,6 +669,7 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType) @@ -665,6 +673,7 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType)
- (void)rebuildAccessibilityTree; - (void)rebuildAccessibilityTree;
- (void)invalidateAccessibilityTree; - (void)invalidateAccessibilityTree;
- (void)postAccessibilityUpdates; - (void)postAccessibilityUpdates;
@@ -86,7 +97,7 @@ index 21a93bc..75c731f 100644
@end @end
diff --git a/src/nsterm.m b/src/nsterm.m diff --git a/src/nsterm.m b/src/nsterm.m
index 8d44b5f..8d88273 100644 index 8d44b5f..8548c68 100644
--- a/src/nsterm.m --- a/src/nsterm.m
+++ b/src/nsterm.m +++ b/src/nsterm.m
@@ -7415,6 +7415,112 @@ visual line index for Zoom (skip whitespace-only lines @@ -7415,6 +7415,112 @@ visual line index for Zoom (skip whitespace-only lines
@@ -202,7 +213,15 @@ index 8d44b5f..8d88273 100644
/* Build accessibility text for window W, skipping invisible text. /* Build accessibility text for window W, skipping invisible text.
Populates *OUT_START with the buffer start charpos. Populates *OUT_START with the buffer start charpos.
Populates *OUT_RUNS with an array of visible runs and *OUT_NRUNS Populates *OUT_RUNS with an array of visible runs and *OUT_NRUNS
@@ -8159,16 +8265,25 @@ - (void)ensureTextCache @@ -8046,6 +8152,7 @@ that remapped bindings (e.g., C-j -> next-line) are recognized.
@implementation EmacsAccessibilityBuffer
@synthesize cachedText;
@synthesize cachedTextModiff;
+@synthesize cachedOverlayModiffForText;
@synthesize cachedOverlayModiff;
@synthesize cachedTextStart;
@synthesize cachedModiff;
@@ -8159,16 +8266,33 @@ - (void)ensureTextCache
if (!b) if (!b)
return; return;
@@ -230,22 +249,31 @@ index 8d44b5f..8d88273 100644
+ Including overlay_modiff would silently update cachedOverlayModiff + Including overlay_modiff would silently update cachedOverlayModiff
+ and prevent the notification dispatch from detecting changes. */ + and prevent the notification dispatch from detecting changes. */
+ ptrdiff_t chars_modiff = BUF_CHARS_MODIFF (b); + ptrdiff_t chars_modiff = BUF_CHARS_MODIFF (b);
+ ptrdiff_t overlay_modiff = BUF_OVERLAY_MODIFF (b);
+ ptrdiff_t pt = BUF_PT (b); + ptrdiff_t pt = BUF_PT (b);
+ NSUInteger textLen = cachedText ? [cachedText length] : 0; + NSUInteger textLen = cachedText ? [cachedText length] : 0;
+ /* Cache is valid when neither characters nor fold-state have changed.
+ BUF_CHARS_MODIFF guards against character edits and is not bumped
+ by font-lock (text-property changes), preserving the O(1) hot path.
+ BUF_OVERLAY_MODIFF covers fold/unfold in modes that use overlays
+ (org-mode, hideshow); text-property-based invisibility such as
+ outline-minor-mode without overlays is a known limitation. */
+ if (cachedText && cachedTextModiff == chars_modiff + if (cachedText && cachedTextModiff == chars_modiff
+ && cachedOverlayModiffForText == overlay_modiff
&& cachedTextStart == BUF_BEGV (b) && cachedTextStart == BUF_BEGV (b)
&& pt >= cachedTextStart && pt >= cachedTextStart
&& (textLen == 0 && (textLen == 0
@@ -8184,7 +8299,7 @@ included in the cached AX text (it is handled separately via @@ -8184,7 +8308,8 @@ included in the cached AX text (it is handled separately via
{ {
[cachedText release]; [cachedText release];
cachedText = [text retain]; cachedText = [text retain];
- cachedTextModiff = modiff; - cachedTextModiff = modiff;
+ cachedTextModiff = chars_modiff; + cachedTextModiff = chars_modiff;
+ cachedOverlayModiffForText = overlay_modiff;
cachedTextStart = start; cachedTextStart = start;
if (visibleRuns) if (visibleRuns)
@@ -9175,6 +9290,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b @@ -9175,6 +9300,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
ptrdiff_t currentOverlayStart = 0; ptrdiff_t currentOverlayStart = 0;
ptrdiff_t currentOverlayEnd = 0; ptrdiff_t currentOverlayEnd = 0;
@@ -253,7 +281,7 @@ index 8d44b5f..8d88273 100644
specpdl_ref count2 = SPECPDL_INDEX (); specpdl_ref count2 = SPECPDL_INDEX ();
record_unwind_current_buffer (); record_unwind_current_buffer ();
if (b != current_buffer) if (b != current_buffer)
@@ -9931,6 +10047,10 @@ - (void)dealloc @@ -9931,6 +10057,10 @@ - (void)dealloc
#endif #endif
[accessibilityElements release]; [accessibilityElements release];
@@ -264,7 +292,7 @@ index 8d44b5f..8d88273 100644
[[self menu] release]; [[self menu] release];
[super dealloc]; [super dealloc];
} }
@@ -11380,6 +11500,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f @@ -11380,6 +11510,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
windowClosing = NO; windowClosing = NO;
processingCompose = NO; processingCompose = NO;
@@ -274,7 +302,7 @@ index 8d44b5f..8d88273 100644
scrollbarsNeedingUpdate = 0; scrollbarsNeedingUpdate = 0;
fs_state = FULLSCREEN_NONE; fs_state = FULLSCREEN_NONE;
fs_before_fs = next_maximized = -1; fs_before_fs = next_maximized = -1;
@@ -12688,6 +12811,80 @@ - (id)accessibilityFocusedUIElement @@ -12688,6 +12821,80 @@ - (id)accessibilityFocusedUIElement
The existing elements carry cached state (modiff, point) from the The existing elements carry cached state (modiff, point) from the
previous redisplay cycle. Rebuilding first would create fresh previous redisplay cycle. Rebuilding first would create fresh
elements with current values, making change detection impossible. */ elements with current values, making change detection impossible. */
@@ -355,7 +383,7 @@ index 8d44b5f..8d88273 100644
- (void)postAccessibilityUpdates - (void)postAccessibilityUpdates
{ {
NSTRACE ("[EmacsView postAccessibilityUpdates]"); NSTRACE ("[EmacsView postAccessibilityUpdates]");
@@ -12698,11 +12895,59 @@ - (void)postAccessibilityUpdates @@ -12698,11 +12905,59 @@ - (void)postAccessibilityUpdates
/* Re-entrance guard: VoiceOver callbacks during notification posting /* Re-entrance guard: VoiceOver callbacks during notification posting
can trigger redisplay, which calls ns_update_end, which calls us can trigger redisplay, which calls ns_update_end, which calls us