fix: add accessibilityBoundsForRange: (new NSAccessibilityProtocol) + isAccessibilityElement

Old parameterized attribute API alone insufficient — macOS Zoom prefers
the new NSAccessibilityProtocol method accessibilityBoundsForRange:.
Also adds isAccessibilityElement returning YES.

Both APIs now implemented for compatibility across macOS versions.
This commit is contained in:
2026-02-23 09:19:51 +01:00
parent 78ee89512e
commit ce46e5b7eb

View File

@@ -7,23 +7,26 @@ Add NSAccessibilityBoundsForRangeParameterizedAttribute support to
EmacsView so that macOS Zoom and other accessibility tools can track EmacsView so that macOS Zoom and other accessibility tools can track
the text cursor position. the text cursor position.
This implements accessibilityAttributeValue:forParameter: on EmacsView, Implements both the old parameterized attribute API
storing the cursor rect in ns_draw_window_cursor and converting it to (accessibilityAttributeValue:forParameter:) and the new
screen coordinates on demand. NSAccessibilityProtocol (accessibilityBoundsForRange:) so that Zoom
works on both older and newer macOS versions.
Changes: Changes:
- Add lastAccessibilityCursorRect ivar to EmacsView (nsterm.h) - Add lastAccessibilityCursorRect ivar to EmacsView (nsterm.h)
- Store cursor rect in ns_draw_window_cursor (nsterm.m) - Store cursor rect in ns_draw_window_cursor (nsterm.m)
- Implement accessibilityParameterizedAttributeNames - Implement accessibilityIsIgnored, accessibilityFocusedUIElement
- Implement accessibilityAttributeValue:forParameter: for BoundsForRange - Implement accessibilityRole (NSAccessibilityTextAreaRole)
- Implement accessibilityIsIgnored, accessibilityFocusedUIElement, accessibilityRole - Implement isAccessibilityElement (new API, returns YES)
- EmacsView reports as NSAccessibilityTextAreaRole - Implement accessibilityParameterizedAttributeNames (old API)
- Implement accessibilityAttributeValue:forParameter: for BoundsForRange (old API)
- Implement accessibilityBoundsForRange: (new NSAccessibilityProtocol)
See also: https://github.com/nicowillis/Ghostty/issues/4053 See also: https://github.com/nicowillis/Ghostty/issues/4053
--- ---
src/nsterm.h | 3 +++ src/nsterm.h | 3 +++
src/nsterm.m | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nsterm.m | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+) 2 files changed, 89 insertions(+)
diff --git a/src/nsterm.h b/src/nsterm.h diff --git a/src/nsterm.h b/src/nsterm.h
index 7c1ee4c..6c1ff34 100644 index 7c1ee4c..6c1ff34 100644
@@ -59,19 +62,26 @@ index 932d209..c900d71 100644
ns_focus (f, NULL, 0); ns_focus (f, NULL, 0);
NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
@@ -9474,6 +9483,65 @@ - (int) fullscreenState @@ -9474,6 +9483,83 @@ - (int) fullscreenState
return fs_state; return fs_state;
} }
+#ifdef NS_IMPL_COCOA +#ifdef NS_IMPL_COCOA
+/* Accessibility support for macOS Zoom and other assistive tools. +/* Accessibility support for macOS Zoom and other assistive tools.
+ Implements AXBoundsForRange so that cursor tracking works. */ + Implements both old (AXBoundsForRange parameterized attribute) and
+ new (accessibilityBoundsForRange:) APIs so cursor tracking works
+ on all macOS versions. */
+ +
+- (BOOL)accessibilityIsIgnored +- (BOOL)accessibilityIsIgnored
+{ +{
+ return NO; + return NO;
+} +}
+ +
+- (BOOL)isAccessibilityElement
+{
+ return YES;
+}
+
+- (id)accessibilityFocusedUIElement +- (id)accessibilityFocusedUIElement
+{ +{
+ return self; + return self;
@@ -82,6 +92,25 @@ index 932d209..c900d71 100644
+ return NSAccessibilityTextAreaRole; + return NSAccessibilityTextAreaRole;
+} +}
+ +
+/* New NSAccessibilityProtocol (macOS 10.10+) — preferred by Zoom. */
+- (NSRect)accessibilityBoundsForRange:(NSRange)range
+{
+ NSRect viewRect = lastAccessibilityCursorRect;
+
+ if (viewRect.size.width < 1)
+ viewRect.size.width = 1;
+ if (viewRect.size.height < 1)
+ viewRect.size.height = 8;
+
+ NSWindow *win = [self window];
+ if (win == nil)
+ return NSZeroRect;
+
+ NSRect windowRect = [self convertRect:viewRect toView:nil];
+ return [win convertRectToScreen:windowRect];
+}
+
+/* Old parameterized attribute API — fallback for older tools. */
+- (NSArray *)accessibilityParameterizedAttributeNames +- (NSArray *)accessibilityParameterizedAttributeNames
+{ +{
+ NSArray *superAttrs = [super accessibilityParameterizedAttributeNames]; + NSArray *superAttrs = [super accessibilityParameterizedAttributeNames];
@@ -127,4 +156,3 @@ index 932d209..c900d71 100644
-- --
2.43.0 2.43.0