patches: fix char nav — announce char AT point, not before it (evil block cursor)
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
From 26208baf6a7d44d471d0c99bd99e288cd23472bc Mon Sep 17 00:00:00 2001
|
From 36073f1ad322a2ca478189fca89bc2b220fce621 Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Fri, 27 Feb 2026 11:36:03 +0100
|
Date: Fri, 27 Feb 2026 11:48:36 +0100
|
||||||
Subject: [PATCH] ns: implement VoiceOver accessibility (AXBoundsForRange, line
|
Subject: [PATCH] ns: implement VoiceOver accessibility (AXBoundsForRange, line
|
||||||
nav, completions, interactive spans)
|
nav, completions, interactive spans)
|
||||||
|
|
||||||
---
|
---
|
||||||
src/nsterm.h | 109 ++
|
src/nsterm.h | 109 ++
|
||||||
src/nsterm.m | 2674 +++++++++++++++++++++++++++++++++++++++++++++++---
|
src/nsterm.m | 2715 +++++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
2 files changed, 2634 insertions(+), 149 deletions(-)
|
2 files changed, 2675 insertions(+), 149 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/nsterm.h b/src/nsterm.h
|
diff --git a/src/nsterm.h b/src/nsterm.h
|
||||||
index 7c1ee4c..6c95673 100644
|
index 7c1ee4c..6c95673 100644
|
||||||
@@ -144,7 +144,7 @@ index 7c1ee4c..6c95673 100644
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/src/nsterm.m b/src/nsterm.m
|
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||||
index 932d209..e81798a 100644
|
index 932d209..7e53bb3 100644
|
||||||
--- a/src/nsterm.m
|
--- a/src/nsterm.m
|
||||||
+++ b/src/nsterm.m
|
+++ b/src/nsterm.m
|
||||||
@@ -46,6 +46,7 @@ Updated by Christian Limpach (chris@nice.ch)
|
@@ -46,6 +46,7 @@ Updated by Christian Limpach (chris@nice.ch)
|
||||||
@@ -205,7 +205,7 @@ index 932d209..e81798a 100644
|
|||||||
ns_focus (f, NULL, 0);
|
ns_focus (f, NULL, 0);
|
||||||
|
|
||||||
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||||
@@ -6849,219 +6886,2235 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg
|
@@ -6849,219 +6886,2276 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
|
|
||||||
@@ -1981,6 +1981,47 @@ index 932d209..e81798a 100644
|
|||||||
+ NSAccessibilitySelectedTextChangedNotification,
|
+ NSAccessibilitySelectedTextChangedNotification,
|
||||||
+ moveInfo);
|
+ moveInfo);
|
||||||
+
|
+
|
||||||
|
+ /* Character navigation: announce the character AT point.
|
||||||
|
+ VoiceOver's default for SelectedTextChanged with direction=next/char
|
||||||
|
+ reads the character BEFORE the new cursor position (the one "just
|
||||||
|
+ passed"). This is correct for insert-mode (cursor BETWEEN chars)
|
||||||
|
+ but wrong for block-cursor modes like evil-normal where the cursor
|
||||||
|
+ is visually ON the character at point. Post an explicit
|
||||||
|
+ announcement with the character at point to override this. */
|
||||||
|
+ if ([self isAccessibilityFocused]
|
||||||
|
+ && cachedText
|
||||||
|
+ && granularity == ns_ax_text_selection_granularity_character
|
||||||
|
+ && (direction == ns_ax_text_selection_direction_next
|
||||||
|
+ || direction == ns_ax_text_selection_direction_previous))
|
||||||
|
+ {
|
||||||
|
+ NSUInteger point_idx = [self accessibilityIndexForCharpos:point];
|
||||||
|
+ NSUInteger tlen = [cachedText length];
|
||||||
|
+ if (point_idx < tlen)
|
||||||
|
+ {
|
||||||
|
+ NSRange charRange = [cachedText
|
||||||
|
+ rangeOfComposedCharacterSequenceAtIndex: point_idx];
|
||||||
|
+ if (charRange.location != NSNotFound && charRange.length > 0
|
||||||
|
+ && charRange.location + charRange.length <= tlen)
|
||||||
|
+ {
|
||||||
|
+ NSString *ch = [cachedText substringWithRange: charRange];
|
||||||
|
+ /* Skip bare newlines — VoiceOver already says "new line". */
|
||||||
|
+ if (![ch isEqualToString: @"
|
||||||
|
+"])
|
||||||
|
+ {
|
||||||
|
+ NSDictionary *annInfo = @{
|
||||||
|
+ NSAccessibilityAnnouncementKey: ch,
|
||||||
|
+ NSAccessibilityPriorityKey:
|
||||||
|
+ @(NSAccessibilityPriorityHigh)
|
||||||
|
+ };
|
||||||
|
+ NSAccessibilityPostNotificationWithUserInfo (
|
||||||
|
+ NSApp,
|
||||||
|
+ NSAccessibilityAnnouncementRequestedNotification,
|
||||||
|
+ annInfo);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ /* Emit an explicit announcement whenever point lands on a new line.
|
+ /* Emit an explicit announcement whenever point lands on a new line.
|
||||||
+ Triggering on granularity=line covers ALL line-motion commands
|
+ Triggering on granularity=line covers ALL line-motion commands
|
||||||
+ in ALL modes (next-line, dired-next-line, next-completion, …)
|
+ in ALL modes (next-line, dired-next-line, next-completion, …)
|
||||||
@@ -2590,7 +2631,7 @@ index 932d209..e81798a 100644
|
|||||||
unsigned fnKeysym = 0;
|
unsigned fnKeysym = 0;
|
||||||
static NSMutableArray *nsEvArray;
|
static NSMutableArray *nsEvArray;
|
||||||
unsigned int flags = [theEvent modifierFlags];
|
unsigned int flags = [theEvent modifierFlags];
|
||||||
@@ -8237,6 +10290,28 @@ - (void)windowDidBecomeKey /* for direct calls */
|
@@ -8237,6 +10331,28 @@ - (void)windowDidBecomeKey /* for direct calls */
|
||||||
XSETFRAME (event.frame_or_window, emacsframe);
|
XSETFRAME (event.frame_or_window, emacsframe);
|
||||||
kbd_buffer_store_event (&event);
|
kbd_buffer_store_event (&event);
|
||||||
ns_send_appdefined (-1); // Kick main loop
|
ns_send_appdefined (-1); // Kick main loop
|
||||||
@@ -2619,7 +2660,7 @@ index 932d209..e81798a 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9474,6 +11549,307 @@ - (int) fullscreenState
|
@@ -9474,6 +11590,307 @@ - (int) fullscreenState
|
||||||
return fs_state;
|
return fs_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user