diff --git a/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch b/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch index e161666..e43ca46 100644 --- a/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch +++ b/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch @@ -1,13 +1,13 @@ -From 3dedb68c7f8656ecdbae18533d092a4a91f3ddb7 Mon Sep 17 00:00:00 2001 +From b8ca9a5b66f8fd6f60e4f0263c620ae21be9d776 Mon Sep 17 00:00:00 2001 From: Martin Sukany -Date: Fri, 27 Feb 2026 11:06:06 +0100 +Date: Fri, 27 Feb 2026 11:14:26 +0100 Subject: [PATCH] ns: implement VoiceOver accessibility (AXBoundsForRange, line nav, completions, interactive spans) --- src/nsterm.h | 109 ++ - src/nsterm.m | 2681 +++++++++++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 2641 insertions(+), 149 deletions(-) + src/nsterm.m | 2679 +++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 2639 insertions(+), 149 deletions(-) diff --git a/src/nsterm.h b/src/nsterm.h index 7c1ee4c..6c95673 100644 @@ -144,7 +144,7 @@ index 7c1ee4c..6c95673 100644 diff --git a/src/nsterm.m b/src/nsterm.m -index 932d209..bedbe01 100644 +index 932d209..367ee50 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -46,6 +46,7 @@ Updated by Christian Limpach (chris@nice.ch) @@ -205,7 +205,7 @@ index 932d209..bedbe01 100644 ns_focus (f, NULL, 0); NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; -@@ -6849,219 +6886,2242 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg +@@ -6849,219 +6886,2240 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg /* ========================================================================== @@ -1986,31 +1986,31 @@ index 932d209..bedbe01 100644 + NSAccessibilitySelectedTextChangedNotification, + moveInfo); + -+ /* C-n/C-p (`next-line' / `previous-line') can diverge from -+ arrow-down/up command paths in some major modes (completion list, -+ Dired, etc.). Emit an explicit line announcement for this basic -+ line-motion path so VoiceOver tracks the Emacs point reliably. */ ++ /* Emit an explicit announcement whenever point lands on a new line. ++ Triggering on granularity=line covers ALL line-motion commands ++ in ALL modes (next-line, dired-next-line, next-completion, …) ++ without enumerating command names. Character and word moves ++ (granularity ≠ line) are left to VoiceOver's default behaviour. ++ ++ For buffers using horizontal multi-column completion layout ++ (completion-list-mode) we read the completion--string text ++ property at point rather than the whole line, which would ++ otherwise announce two candidates at once. */ + if ([self isAccessibilityFocused] + && cachedText -+ && (isCtrlNP || ns_ax_command_is_basic_line_move ()) -+ && (direction == ns_ax_text_selection_direction_next -+ || direction == ns_ax_text_selection_direction_previous)) ++ && granularity == ns_ax_text_selection_granularity_line) + { -+ /* In completion-list-mode, prefer the completion--string -+ text property over the raw line text. The horizontal -+ layout places two candidates per line; reading the whole -+ line would announce both at once. */ + NSString *announceText = nil; + -+ struct buffer *cb = XBUFFER (w->contents); -+ Lisp_Object cs_sym = intern ("completion--string"); ++ /* 1. completion--string at point (completion-list-mode). */ + Lisp_Object cstr = Fget_char_property (make_fixnum (point), -+ cs_sym, Qnil); ++ intern ("completion--string"), ++ Qnil); + announceText = ns_ax_completion_string_from_prop (cstr); + ++ /* 2. Fallback: full line text. */ + if (!announceText) + { -+ /* Fallback: read full line (non-completion buffers). */ + NSUInteger point_idx = [self accessibilityIndexForCharpos:point]; + if (point_idx <= [cachedText length]) + { @@ -2018,10 +2018,9 @@ index 932d209..bedbe01 100644 + NSRange lineRange = [self accessibilityRangeForLine:lineNum]; + if (lineRange.location != NSNotFound + && lineRange.length > 0 -+ && lineRange.location + lineRange.length <= [cachedText length]) -+ { -+ announceText = [cachedText substringWithRange:lineRange]; -+ } ++ && lineRange.location + lineRange.length ++ <= [cachedText length]) ++ announceText = [cachedText substringWithRange:lineRange]; + } + } + @@ -2041,7 +2040,6 @@ index 932d209..bedbe01 100644 + annInfo); + } + } -+ (void) cb; + } + + /* --- Completions announcement --- @@ -2597,7 +2595,7 @@ index 932d209..bedbe01 100644 unsigned fnKeysym = 0; static NSMutableArray *nsEvArray; unsigned int flags = [theEvent modifierFlags]; -@@ -8237,6 +10297,28 @@ - (void)windowDidBecomeKey /* for direct calls */ +@@ -8237,6 +10295,28 @@ - (void)windowDidBecomeKey /* for direct calls */ XSETFRAME (event.frame_or_window, emacsframe); kbd_buffer_store_event (&event); ns_send_appdefined (-1); // Kick main loop @@ -2626,7 +2624,7 @@ index 932d209..bedbe01 100644 } -@@ -9474,6 +11556,307 @@ - (int) fullscreenState +@@ -9474,6 +11554,307 @@ - (int) fullscreenState return fs_state; }