From 3093053131bce3a8886406e532e1e947b74750b4 Mon Sep 17 00:00:00 2001 From: Daneel Date: Mon, 2 Mar 2026 14:40:49 +0100 Subject: [PATCH] Fix VO cursor sync: post FocusedUIElementChanged on self not emacsView The notification was posted on self.emacsView (the NSView container). VoiceOver called accessibilityFocusedUIElement on the view, got back the same buffer element, and did not re-anchor its browse cursor. Fix: post on self (the buffer element itself). When VoiceOver receives NSAccessibilityFocusedUIElementChangedNotification from an element that is already focused, it silently re-queries accessibilitySelectedTextRange and re-anchors its browse cursor without re-announcing the element name. Covers all emacsMovedCursor granularities (arrow keys, M-f/M-b, C-n/C-p via the separate isCtrlNP path). --- ...hild-frame-completion-candidates-for-Vo.patch | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch b/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch index 0754f08..295eff0 100644 --- a/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch +++ b/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch @@ -518,7 +518,7 @@ index 8d44b5f..29b646d 100644 NSInteger direction = ns_ax_text_selection_direction_discontiguous; if (point > oldPoint) direction = ns_ax_text_selection_direction_next; -@@ -9492,6 +9674,36 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property +@@ -9492,6 +9674,38 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property granularity = ns_ax_text_selection_granularity_line; } @@ -542,14 +542,16 @@ index 8d44b5f..29b646d 100644 + if (emacsMovedCursor && !isCtrlNP) + direction = ns_ax_text_selection_direction_discontiguous; + -+ /* Post FocusedUIElementChanged on the containing NSView whenever -+ Emacs moves the cursor independently of VoiceOver. Posting on -+ the view causes VoiceOver to re-query accessibilityFocusedUIElement -+ and re-anchor its browse cursor at the new selection range, without -+ re-announcing the element name. Required for all granularities. */ ++ /* Post FocusedUIElementChangedNotification on the buffer element ++ itself (not the parent view) so VoiceOver re-queries ++ accessibilitySelectedTextRange and re-anchors its rotor browse ++ cursor to Emacs' current point. Posting on self (already ++ focused) causes VO to silently re-anchor without re-announcing ++ the element name. Required for all granularities (char, word, ++ line). */ + if (emacsMovedCursor && [self isAccessibilityFocused]) + ns_ax_post_notification ( -+ self.emacsView, ++ self, + NSAccessibilityFocusedUIElementChangedNotification); + /* Post notifications for focused and non-focused elements. */