patches: fix VoiceOver cursor sync + echo area (base f8d9ecb restored)

This commit is contained in:
2026-03-01 14:51:58 +01:00
parent 7ddebc2579
commit b7d0188cbb
9 changed files with 43 additions and 49 deletions

View File

@@ -1,4 +1,4 @@
From dd5326f6549efdcd6a238a2d552dba72bf31e33c Mon Sep 17 00:00:00 2001 From edb3a37f853fc9b98dfc96a7ba0434e87e1fdc3e Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 22:39:35 +0100 Date: Sat, 28 Feb 2026 22:39:35 +0100
Subject: [PATCH 0/8] ns: integrate with macOS Zoom for cursor tracking Subject: [PATCH 0/8] ns: integrate with macOS Zoom for cursor tracking
@@ -32,7 +32,7 @@ to the selected completion candidate after normal cursor tracking.
3 files changed, 370 insertions(+) 3 files changed, 370 insertions(+)
diff --git a/etc/NEWS b/etc/NEWS diff --git a/etc/NEWS b/etc/NEWS
index 4b24237..77570d7 100644 index ef36df5..80661a9 100644
--- a/etc/NEWS --- a/etc/NEWS
+++ b/etc/NEWS +++ b/etc/NEWS
@@ -82,6 +82,17 @@ other directory on your system. You can also invoke the @@ -82,6 +82,17 @@ other directory on your system. You can also invoke the

View File

@@ -1,4 +1,4 @@
From 3a3b3205b24e6b4298039db05dd38819d985599d Mon Sep 17 00:00:00 2001 From 1ecb71555d3419523d8ccebc03ace9bffac4f99e Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100 Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 1/8] ns: add accessibility base classes and text extraction Subject: [PATCH 1/8] ns: add accessibility base classes and text extraction

View File

@@ -1,4 +1,4 @@
From c2eec09aae64e2ce37fb19cf0716116313f647e8 Mon Sep 17 00:00:00 2001 From f29ed7e4e305a5f8857e72d3762d43c0901be718 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100 Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 2/8] ns: implement buffer accessibility element (core Subject: [PATCH 2/8] ns: implement buffer accessibility element (core

View File

@@ -1,4 +1,4 @@
From 6fe743f05facbfa0f2bcfff82102a334c6a027e7 Mon Sep 17 00:00:00 2001 From b4b09f69a8a4742e9f1431242d58e2c52400112c Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100 Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 3/8] ns: add buffer notification dispatch and mode-line Subject: [PATCH 3/8] ns: add buffer notification dispatch and mode-line

View File

@@ -1,4 +1,4 @@
From ae623f79696deb5bb99610c2cf27d8f932305ba6 Mon Sep 17 00:00:00 2001 From 1ce902a7a0b0d4d63e9d9f8718145d183a3c5d1a Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100 Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 4/8] ns: add interactive span elements for Tab navigation Subject: [PATCH 4/8] ns: add interactive span elements for Tab navigation

View File

@@ -1,4 +1,4 @@
From 859627d473c5c5926aed29b2a6f885b69c1f5d62 Mon Sep 17 00:00:00 2001 From 6e6c5f4cf33d302e23141ce241c1747cdc0304be Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100 Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 5/8] ns: integrate accessibility with EmacsView and redisplay Subject: [PATCH 5/8] ns: integrate accessibility with EmacsView and redisplay
@@ -27,7 +27,7 @@ com.apple.accessibility.api distributed notification.
2 files changed, 431 insertions(+), 12 deletions(-) 2 files changed, 431 insertions(+), 12 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS diff --git a/etc/NEWS b/etc/NEWS
index 77570d7..a4a525f 100644 index 80661a9..2b1f9e6 100644
--- a/etc/NEWS --- a/etc/NEWS
+++ b/etc/NEWS +++ b/etc/NEWS
@@ -4400,6 +4400,19 @@ allowing Emacs users access to speech recognition utilities. @@ -4400,6 +4400,19 @@ allowing Emacs users access to speech recognition utilities.

View File

@@ -1,4 +1,4 @@
From e8804e0e5d3284e1ab6b6db4cd3848f882e29cab Mon Sep 17 00:00:00 2001 From cd2037fc2078f3db365fa3f222413d9022c882f5 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100 Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 6/8] doc: add VoiceOver accessibility section to macOS Subject: [PATCH 6/8] doc: add VoiceOver accessibility section to macOS

View File

@@ -1,4 +1,4 @@
From f2ceeb452a8264f0ae85046ed2fc1c49598f9b7b Mon Sep 17 00:00:00 2001 From c777281b5f05b463ec4bb8bdcb71bdcf400a10c6 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz> From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 14:46:25 +0100 Date: Sat, 28 Feb 2026 14:46:25 +0100
Subject: [PATCH 7/8] ns: announce overlay completion candidates for VoiceOver Subject: [PATCH 7/8] ns: announce overlay completion candidates for VoiceOver

View File

@@ -1,4 +1,4 @@
From 0fc45d4df14bdc39d6c005cc2c02c745fd59ea22 Mon Sep 17 00:00:00 2001 From a238db02b1d26210a61106c804c8dd012e93fc52 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
@@ -20,8 +20,8 @@ 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 | 9 ++ src/nsterm.h | 9 ++
src/nsterm.m | 337 +++++++++++++++++++++++++++++++++++++++++-- src/nsterm.m | 338 +++++++++++++++++++++++++++++++++++++++++--
4 files changed, 333 insertions(+), 23 deletions(-) 4 files changed, 334 insertions(+), 23 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
@@ -48,7 +48,7 @@ index 6514dfc..f47929e 100644
To disable the accessibility interface entirely (for instance, to To disable the accessibility interface entirely (for instance, to
eliminate overhead on systems where assistive technology is not in eliminate overhead on systems where assistive technology is not in
diff --git a/etc/NEWS b/etc/NEWS diff --git a/etc/NEWS b/etc/NEWS
index a4a525f..d26c926 100644 index 2b1f9e6..8a40850 100644
--- a/etc/NEWS --- a/etc/NEWS
+++ b/etc/NEWS +++ b/etc/NEWS
@@ -4404,8 +4404,8 @@ send user data to Apple's speech recognition servers. @@ -4404,8 +4404,8 @@ send user data to Apple's speech recognition servers.
@@ -97,7 +97,7 @@ index 21a93bc..bbce9fe 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..251a03e 100644 index 8d44b5f..e05608f 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
@@ -274,7 +274,7 @@ index 8d44b5f..251a03e 100644
cachedTextStart = start; cachedTextStart = start;
if (visibleRuns) if (visibleRuns)
@@ -9060,11 +9186,14 @@ - (void)postFocusedCursorNotification:(ptrdiff_t)point @@ -9060,11 +9186,13 @@ - (void)postFocusedCursorNotification:(ptrdiff_t)point
= @(ns_ax_text_state_change_selection_move); = @(ns_ax_text_state_change_selection_move);
moveInfo[@"AXTextSelectionDirection"] = @(direction); moveInfo[@"AXTextSelectionDirection"] = @(direction);
moveInfo[@"AXTextChangeElement"] = self; moveInfo[@"AXTextChangeElement"] = self;
@@ -283,26 +283,17 @@ index 8d44b5f..251a03e 100644
- for evil block-cursor mode). Include it for word/line/ - for evil block-cursor mode). Include it for word/line/
- selection so VoiceOver reads the appropriate text. */ - selection so VoiceOver reads the appropriate text. */
- if (!isCharMove) - if (!isCharMove)
+ /* Include granularity for sequential moves so VoiceOver reads + /* Include granularity for sequential moves so VoiceOver reads the
+ the appropriate unit of text. Omit for character moves (we + appropriate unit. Omit for character moves (announced explicitly
+ announce the character explicitly below) and for discontiguous + below) and for discontiguous jumps (destination line announced
+ jumps (the destination line is announced explicitly; omitting + explicitly; omitting granularity lets VoiceOver use its default
+ granularity lets VoiceOver use default behaviour and re-anchor + behaviour and re-anchor its browse cursor). */
+ its browse cursor to accessibilitySelectedTextRange). */
+ if (!isCharMove + if (!isCharMove
+ && direction != ns_ax_text_selection_direction_discontiguous) + && direction != ns_ax_text_selection_direction_discontiguous)
moveInfo[@"AXTextSelectionGranularity"] = @(granularity); moveInfo[@"AXTextSelectionGranularity"] = @(granularity);
ns_ax_post_notification_with_info ( ns_ax_post_notification_with_info (
@@ -9072,6 +9201,7 @@ derive its own speech (it would read the wrong character @@ -9175,6 +9303,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
NSAccessibilitySelectedTextChangedNotification,
moveInfo);
+
/* For character moves: explicit announcement of char AT point.
This is the ONLY speech source for character navigation.
Correct for evil block-cursor (cursor ON the character)
@@ -9175,6 +9305,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
ptrdiff_t currentOverlayStart = 0; ptrdiff_t currentOverlayStart = 0;
ptrdiff_t currentOverlayEnd = 0; ptrdiff_t currentOverlayEnd = 0;
@@ -310,18 +301,20 @@ index 8d44b5f..251a03e 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)
@@ -9352,6 +9483,44 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f @@ -9352,6 +9481,46 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f
if (!b) if (!b)
return; return;
+ /* --- Echo area announcements --- + /* --- Echo area announcements ---
+ When the minibuffer is not active for user input (minibuf_level == 0) + When the minibuffer is not active for user input (minibuf_level == 0)
+ and its character content changes, announce the new text to VoiceOver. + and its character content changes, announce the new message to
+ This surfaces error messages, informational echoes, and git/process + VoiceOver. This surfaces error messages, completion notices, and
+ status updates. We skip the rest of the notification cycle (cursor + process status updates (e.g. "Wrote file", "Git finished").
+ tracking etc.) because an inactive minibuffer has no meaningful cursor. +
+ When minibuf_level > 0 the user is composing a command; fall through + Priority High interrupts ongoing speech, which matches the urgency
+ to normal processing so prompt and completion announcements work. */ + of a status change. While minibuf_level > 0 the user is composing
+ a command; we fall through to normal cursor and completion tracking
+ in that case. */
+ if (MINI_WINDOW_P (w) && minibuf_level == 0) + if (MINI_WINDOW_P (w) && minibuf_level == 0)
+ { + {
+ ptrdiff_t echo_chars = BUF_CHARS_MODIFF (b); + ptrdiff_t echo_chars = BUF_CHARS_MODIFF (b);
@@ -355,23 +348,24 @@ index 8d44b5f..251a03e 100644
ptrdiff_t modiff = BUF_MODIFF (b); ptrdiff_t modiff = BUF_MODIFF (b);
ptrdiff_t point = BUF_PT (b); ptrdiff_t point = BUF_PT (b);
BOOL markActive = !NILP (BVAR (b, mark_active)); BOOL markActive = !NILP (BVAR (b, mark_active));
@@ -9488,6 +9657,15 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property @@ -9488,6 +9657,16 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property
granularity = ns_ax_text_selection_granularity_line; granularity = ns_ax_text_selection_granularity_line;
} }
+ /* Non-sequential jumps that cross a line boundary (e.g. ]], [[, + /* Programmatic jumps that cross a line boundary (]], [[, M-<,
+ M-<, xref, imenu) are discontiguous: the cursor moved to an + xref, imenu, …) are discontiguous: the cursor teleported to an
+ arbitrary location, not one sequential step. Reporting direction + arbitrary position, not one sequential step forward/backward.
+ discontiguous causes VoiceOver to re-anchor its rotor browse + Reporting AXTextSelectionDirectionDiscontiguous causes VoiceOver
+ cursor to the new accessibilitySelectedTextRange instead of + to re-anchor its rotor browse cursor at the new
+ advancing linearly from its previous position. */ + accessibilitySelectedTextRange rather than advancing linearly
+ from its previous internal position. */
+ if (!isCtrlNP && granularity == ns_ax_text_selection_granularity_line) + if (!isCtrlNP && granularity == ns_ax_text_selection_granularity_line)
+ direction = ns_ax_text_selection_direction_discontiguous; + direction = ns_ax_text_selection_direction_discontiguous;
+ +
/* Post notifications for focused and non-focused elements. */ /* Post notifications for focused and non-focused elements. */
if ([self isAccessibilityFocused]) if ([self isAccessibilityFocused])
[self postFocusedCursorNotification:point [self postFocusedCursorNotification:point
@@ -9931,6 +10109,10 @@ - (void)dealloc @@ -9931,6 +10110,10 @@ - (void)dealloc
#endif #endif
[accessibilityElements release]; [accessibilityElements release];
@@ -382,7 +376,7 @@ index 8d44b5f..251a03e 100644
[[self menu] release]; [[self menu] release];
[super dealloc]; [super dealloc];
} }
@@ -11380,6 +11562,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f @@ -11380,6 +11563,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
windowClosing = NO; windowClosing = NO;
processingCompose = NO; processingCompose = NO;
@@ -392,7 +386,7 @@ index 8d44b5f..251a03e 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 +12873,80 @@ - (id)accessibilityFocusedUIElement @@ -12688,6 +12874,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. */
@@ -473,7 +467,7 @@ index 8d44b5f..251a03e 100644
- (void)postAccessibilityUpdates - (void)postAccessibilityUpdates
{ {
NSTRACE ("[EmacsView postAccessibilityUpdates]"); NSTRACE ("[EmacsView postAccessibilityUpdates]");
@@ -12698,11 +12957,59 @@ - (void)postAccessibilityUpdates @@ -12698,11 +12958,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