patches: address all maintainer review issues

- Issue 1: Add explicit ApplicationServices import for UAZoomEnabled/
  UAZoomChangeFocus (was implicit via Carbon.h, now explicit)
- Issue 2: Rename FOR_EACH_FRAME variable 'frames' -> 'frame' (plural
  was misleading; matches Emacs convention)
- Issue 3: Move unblock_input before ObjC calls in
  postCompletionAnnouncementForBuffer: to avoid holding block_input
  during @synchronized operations
- Issue 4: Fix DEFVAR_BOOL doc and Texinfo: initial value is nil,
  not t; auto-detection sets it at startup
- Issue 5: Replace magic 10000 with NS_AX_MAX_COMPLETION_BUFFER_CHARS
  constant with explanatory comment
- Issue 6: Add comment to lineStartOffsets loop explaining it is gated
  on BUF_CHARS_MODIFF and never runs on the hot path
- Issue 8: Rewrite all 9 commit messages to GNU ChangeLog format with
  '* file (symbol): description' entries
- Issue 9: Break 81-char @interface line in nsterm.h
- Issue 10: Add WINDOWP/BUFFERP guards before dereferencing
  cf->selected_window and cw->contents in ns_zoom_find_child_frame_candidate
- Issue 11: Fix @pxref -> @xref at sentence start in macos.texi
This commit is contained in:
2026-03-01 09:44:47 +01:00
parent e0343db56c
commit 71c81abcae
9 changed files with 275 additions and 279 deletions

View File

@@ -1,53 +1,30 @@
From fb4d1411fcc4a18cefae80dbed856fda8fe8c85e Mon Sep 17 00:00:00 2001
From 2f655a0fa3071046169011ecdc97f0a3f7c1105c Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 16:01:29 +0100
Subject: [PATCH 8/8] ns: announce child frame completion candidates for
VoiceOver
Completion frameworks such as Corfu, Company-box, and similar
render candidates in a child frame rather than as overlay strings
in the minibuffer. This patch extends the overlay announcement
support (patch 7/8) to handle child frame popups.
Completion frameworks such as Corfu and Company-box render candidates
in a child frame. This extends the overlay announcement support to
handle child frame popups.
Detect child frames via FRAME_PARENT_FRAME in postAccessibilityUpdates.
Scan the child frame buffer text line by line using Fget_char_property
(which checks both text properties and overlay face properties) to
find the selected candidate. Reuse ns_ax_face_is_selected from
the overlay patch to identify "current", "selected", and
"selection" faces.
Safety:
- record_unwind_current_buffer / set_buffer_internal_1 to switch to
the child frame buffer for Fbuffer_substring_no_properties.
- Re-entrance guard (accessibilityUpdating) before child frame dispatch.
- BUF_MODIFF gating prevents redundant scans.
- WINDOWP, BUFFERP validation for partially initialized frames.
- Buffer size limit (10000 chars) skips non-completion child frames.
When the child frame closes, post FocusedUIElementChangedNotification
on the parent buffer element to restore VoiceOver's character echo
and cursor tracking. The flag childFrameCompletionActive is set by
the child frame handler and cleared on the parent's next accessibility
cycle when no child frame is visible (via FOR_EACH_FRAME).
Announce via AnnouncementRequested to NSApp with High priority.
independently --- its ns_update_end runs after the parent's
* src/nsterm.h (EmacsView): Add announceChildFrameCompletion,
childFrameCompletionActive flag.
* src/nsterm.m (ns_ax_selected_child_frame_text): New function.
(EmacsView announceChildFrameCompletion): New method, set parent flag.
(EmacsView postAccessibilityUpdates): Dispatch to child frame handler,
refocus parent buffer element when child frame closes.
* src/nsterm.m (ns_ax_selected_child_frame_text): New function; scan
a child frame buffer line by line using Fget_char_property to find the
selected candidate; uses record_unwind_current_buffer for safety.
(EmacsView announceChildFrameCompletion): New method.
(EmacsView postAccessibilityUpdates): Detect child frames via
FRAME_PARENT_FRAME; call announceChildFrameCompletion. Post
NSAccessibilityFocusedUIElementChangedNotification on the parent buffer
element when a child frame completion closes.
---
doc/emacs/macos.texi | 6 -
etc/NEWS | 4 +-
src/nsterm.h | 5 +
src/nsterm.m | 266 +++++++++++++++++++++++++++++++++++++++++--
4 files changed, 263 insertions(+), 18 deletions(-)
src/nsterm.m | 265 +++++++++++++++++++++++++++++++++++++++++--
4 files changed, 262 insertions(+), 18 deletions(-)
diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index 4825cf9..97777e2 100644
index 6514dfc..f47929e 100644
--- a/doc/emacs/macos.texi
+++ b/doc/emacs/macos.texi
@@ -278,7 +278,6 @@ restart Emacs to access newly-available services.
@@ -86,10 +63,10 @@ index 2b1f9e6..8a40850 100644
for the *Completions* buffer. The implementation uses a virtual
accessibility tree with per-window elements, hybrid SelectedTextChanged
diff --git a/src/nsterm.h b/src/nsterm.h
index 2102fb9..dd98d56 100644
index 483fed3..8bf867a 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -594,6 +594,10 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType)
@@ -595,6 +595,10 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType)
Lisp_Object lastRootWindow;
BOOL accessibilityTreeValid;
BOOL accessibilityUpdating;
@@ -100,7 +77,7 @@ index 2102fb9..dd98d56 100644
#endif
BOOL font_panel_active;
NSFont *font_panel_result;
@@ -663,6 +667,7 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType)
@@ -664,6 +668,7 @@ typedef NS_ENUM (NSInteger, EmacsAXSpanType)
- (void)rebuildAccessibilityTree;
- (void)invalidateAccessibilityTree;
- (void)postAccessibilityUpdates;
@@ -109,10 +86,10 @@ index 2102fb9..dd98d56 100644
@end
diff --git a/src/nsterm.m b/src/nsterm.m
index a3104d0..6e8a226 100644
index 20ba0b9..f911d93 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7398,6 +7398,112 @@ visual line index for Zoom (skip whitespace-only lines
@@ -7415,6 +7415,112 @@ visual line index for Zoom (skip whitespace-only lines
return nil;
}
@@ -225,7 +202,7 @@ index a3104d0..6e8a226 100644
/* Build accessibility text for window W, skipping invisible text.
Populates *OUT_START with the buffer start charpos.
Populates *OUT_RUNS with an array of visible runs and *OUT_NRUNS
@@ -8142,16 +8248,25 @@ - (void)ensureTextCache
@@ -8159,16 +8265,25 @@ - (void)ensureTextCache
if (!b)
return;
@@ -259,7 +236,7 @@ index a3104d0..6e8a226 100644
&& cachedTextStart == BUF_BEGV (b)
&& pt >= cachedTextStart
&& (textLen == 0
@@ -8167,7 +8282,7 @@ included in the cached AX text (it is handled separately via
@@ -8184,7 +8299,7 @@ included in the cached AX text (it is handled separately via
{
[cachedText release];
cachedText = [text retain];
@@ -268,7 +245,7 @@ index a3104d0..6e8a226 100644
cachedTextStart = start;
if (visibleRuns)
@@ -9154,6 +9269,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
@@ -9175,6 +9290,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
ptrdiff_t currentOverlayStart = 0;
ptrdiff_t currentOverlayEnd = 0;
@@ -276,15 +253,7 @@ index a3104d0..6e8a226 100644
specpdl_ref count2 = SPECPDL_INDEX ();
record_unwind_current_buffer ();
if (b != current_buffer)
@@ -9312,6 +9428,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
self.cachedCompletionOverlayEnd = 0;
self.cachedCompletionPoint = 0;
}
+ unblock_input ();
}
/* ---- Notification dispatch (main entry point) ---- */
@@ -9908,6 +10025,10 @@ - (void)dealloc
@@ -9930,6 +10046,10 @@ - (void)dealloc
#endif
[accessibilityElements release];
@@ -295,7 +264,7 @@ index a3104d0..6e8a226 100644
[[self menu] release];
[super dealloc];
}
@@ -11357,6 +11478,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
@@ -11379,6 +11499,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
windowClosing = NO;
processingCompose = NO;
@@ -305,7 +274,7 @@ index a3104d0..6e8a226 100644
scrollbarsNeedingUpdate = 0;
fs_state = FULLSCREEN_NONE;
fs_before_fs = next_maximized = -1;
@@ -12665,6 +12789,80 @@ - (id)accessibilityFocusedUIElement
@@ -12687,6 +12810,80 @@ - (id)accessibilityFocusedUIElement
The existing elements carry cached state (modiff, point) from the
previous redisplay cycle. Rebuilding first would create fresh
elements with current values, making change detection impossible. */
@@ -386,7 +355,7 @@ index a3104d0..6e8a226 100644
- (void)postAccessibilityUpdates
{
NSTRACE ("[EmacsView postAccessibilityUpdates]");
@@ -12675,11 +12873,59 @@ - (void)postAccessibilityUpdates
@@ -12697,11 +12894,59 @@ - (void)postAccessibilityUpdates
/* Re-entrance guard: VoiceOver callbacks during notification posting
can trigger redisplay, which calls ns_update_end, which calls us