patches: fix Corfu Zoom tracking — replace rate-limit with parent-frame guard

Root cause: the 50ms rate limit broke child-frame (Corfu) tracking.
When the Corfu child frame redraws, its ns_update_end fires first and
resets the rate-limit timer.  When the parent frame's ns_update_end
fires immediately after, the timer has not expired, so
ns_zoom_track_completion returns early without scanning child frames.
Zoom focus stays on the first candidate.

Fix: remove the rate limit; add a FRAME_PARENT_FRAME(f) guard instead.
Child frames have no completion children to scan; their parent's
ns_update_end does the scan via FOR_EACH_FRAME.  Returning early on
child-frame calls avoids the redundant scan and leaves the timer
problem moot.  Overhead without the rate limit is ~40 Lisp evaluations
per redisplay (~5-20 µs), acceptable given ns_zoom_enabled_p() already
caches the UAZoomEnabled() IPC call.
This commit is contained in:
2026-03-01 07:11:00 +01:00
parent 19cc43dbbb
commit c4975c3fe4
9 changed files with 83 additions and 86 deletions

View File

@@ -1,4 +1,4 @@
From 61a0ae5344e6f52cb21ae299133b39b2ede010d0 Mon Sep 17 00:00:00 2001
From 4a81923ad68bc5866f7343b37429a882f7a388dd Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 6/9] ns: integrate accessibility with EmacsView and redisplay
@@ -51,7 +51,7 @@ index 80661a9..2b1f9e6 100644
** Re-introduced dictation, lost in Emacs v30 (macOS).
We lost macOS dictation in v30 when migrating to NSTextInputClient.
diff --git a/src/nsterm.m b/src/nsterm.m
index 5eaf480..4ad451f 100644
index 1a21f2e..f8b7a8d 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1258,7 +1258,7 @@ If a completion candidate is selected (overlay or child frame),
@@ -63,7 +63,7 @@ index 5eaf480..4ad451f 100644
return;
if (!WINDOWP (f->selected_window))
return;
@@ -1378,7 +1378,8 @@ so the visual offset is (ov_line + 1) * line_h from
@@ -1375,7 +1375,8 @@ so the visual offset is (ov_line + 1) * line_h from
(zoomCursorUpdated is NO). */
#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
&& MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
@@ -73,7 +73,7 @@ index 5eaf480..4ad451f 100644
&& !NSIsEmptyRect (view->lastCursorRect))
{
NSRect r = view->lastCursorRect;
@@ -1405,6 +1406,9 @@ so the visual offset is (ov_line + 1) * line_h from
@@ -1402,6 +1403,9 @@ so the visual offset is (ov_line + 1) * line_h from
if (view)
ns_zoom_track_completion (f, view);
#endif /* NS_IMPL_COCOA */
@@ -83,7 +83,7 @@ index 5eaf480..4ad451f 100644
}
static void
@@ -3552,7 +3556,7 @@ EmacsView pixels (AppKit, flipped, top-left origin)
@@ -3549,7 +3553,7 @@ EmacsView pixels (AppKit, flipped, top-left origin)
#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
&& MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
@@ -92,7 +92,7 @@ index 5eaf480..4ad451f 100644
{
NSRect windowRect = [view convertRect:r toView:nil];
NSRect screenRect
@@ -6717,9 +6721,56 @@ - (void)applicationDidFinishLaunching: (NSNotification *)notification
@@ -6714,9 +6718,56 @@ - (void)applicationDidFinishLaunching: (NSNotification *)notification
}
#endif
@@ -149,7 +149,7 @@ index 5eaf480..4ad451f 100644
- (void)antialiasThresholdDidChange:(NSNotification *)notification
{
#ifdef NS_IMPL_COCOA
@@ -7620,7 +7671,6 @@ - (id)accessibilityTopLevelUIElement
@@ -7617,7 +7668,6 @@ - (id)accessibilityTopLevelUIElement
@@ -157,7 +157,7 @@ index 5eaf480..4ad451f 100644
static BOOL
ns_ax_find_completion_overlay_range (struct buffer *b, ptrdiff_t point,
ptrdiff_t *out_start,
@@ -8722,7 +8772,6 @@ - (NSRect)accessibilityFrame
@@ -8719,7 +8769,6 @@ - (NSRect)accessibilityFrame
@end
@@ -165,7 +165,7 @@ index 5eaf480..4ad451f 100644
/* ===================================================================
EmacsAccessibilityBuffer (Notifications) — AX event dispatch
@@ -9267,7 +9316,6 @@ - (NSRect)accessibilityFrame
@@ -9264,7 +9313,6 @@ - (NSRect)accessibilityFrame
@end
@@ -173,7 +173,7 @@ index 5eaf480..4ad451f 100644
/* ===================================================================
EmacsAccessibilityInteractiveSpan — helpers and implementation
=================================================================== */
@@ -9597,6 +9645,7 @@ - (void)dealloc
@@ -9594,6 +9642,7 @@ - (void)dealloc
[layer release];
#endif
@@ -181,7 +181,7 @@ index 5eaf480..4ad451f 100644
[[self menu] release];
[super dealloc];
}
@@ -10945,6 +10994,32 @@ - (void)windowDidBecomeKey /* for direct calls */
@@ -10942,6 +10991,32 @@ - (void)windowDidBecomeKey /* for direct calls */
XSETFRAME (event.frame_or_window, emacsframe);
kbd_buffer_store_event (&event);
ns_send_appdefined (-1); // Kick main loop
@@ -214,7 +214,7 @@ index 5eaf480..4ad451f 100644
}
@@ -12182,6 +12257,332 @@ - (int) fullscreenState
@@ -12179,6 +12254,332 @@ - (int) fullscreenState
return fs_state;
}
@@ -547,7 +547,7 @@ index 5eaf480..4ad451f 100644
@end /* EmacsView */
@@ -14182,12 +14583,17 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
@@ -14179,12 +14580,17 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
ns_use_srgb_colorspace = YES;
DEFVAR_BOOL ("ns-accessibility-enabled", ns_accessibility_enabled,