v4 patch: dual UAZoomChangeFocus + NSAccessibility, with Apple doc refs

UAZoomChangeFocus is Apple's documented API for Zoom focus control.
NSAccessibility serves VoiceOver and other AT tools.
Both are needed - same approach as iTerm2.
References Apple developer documentation URLs in comments.
This commit is contained in:
2026-02-25 18:20:55 +01:00
parent d7aae4b7d1
commit 2a58436f32

View File

@@ -1,36 +1,27 @@
From ea017e0a4427ad3e8d04025ae2ed511a542eeeeb Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Wed, 25 Feb 2026 18:17:42 +0100
Subject: [PATCH] ns: implement macOS Zoom cursor tracking via
UAZoomChangeFocus + NSAccessibility
Date: Tue, 25 Feb 2026 18:20:00 +0100
Subject: [PATCH] ns: implement macOS Zoom cursor tracking via UAZoomChangeFocus
+ NSAccessibility
Add cursor tracking support for macOS Zoom 'Follow keyboard focus' and
Add cursor tracking support for macOS Zoom "Follow keyboard focus" and
other assistive technology tools (VoiceOver, etc.).
Two complementary mechanisms are used:
Two complementary mechanisms are implemented:
1. UAZoomChangeFocus() from ApplicationServices/UniversalAccess.h:
Directly tells macOS Zoom where to move its viewport. This is the
Apple-documented API for controlling Zoom focus, used by iTerm2
(PTYTextView.m, refreshAccessibility method).
Directly tells macOS Zoom where the cursor is. This is Apple's
documented API for applications to control Zoom focus. Same
approach used by iTerm2 (PTYTextView.m:refreshAccessibility).
Ref: https://developer.apple.com/documentation/applicationservices/universalaccess_h
Ref: https://developer.apple.com/documentation/applicationservices/1458830-uazoomchangefocus
2. NSAccessibility protocol on EmacsView: reports as TextArea role,
exposes accessibilityFrame and accessibilityBoundsForRange: returning
cursor screen coordinates, posts SelectedTextChanged and
FocusedUIElementChanged notifications. Serves VoiceOver and other AT
tools that query the accessibility tree.
FocusedUIElementChanged notifications. Serves VoiceOver and other
AT tools that query the accessibility tree directly.
Ref: https://developer.apple.com/documentation/appkit/nsaccessibilityprotocol
Both mechanisms are needed: UAZoomChangeFocus drives Zoom viewport
positioning for custom-drawn views; NSAccessibility notifications serve
VoiceOver, screen readers, and Accessibility Inspector.
---
src/nsterm.h | 3 +
src/nsterm.m | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 224 insertions(+)
diff --git a/src/nsterm.h b/src/nsterm.h
index 7c1ee4c..6c1ff34 100644
--- a/src/nsterm.h
@@ -46,7 +37,7 @@ index 7c1ee4c..6c1ff34 100644
/* AppKit-side interface. */
diff --git a/src/nsterm.m b/src/nsterm.m
index 932d209..933f8cb 100644
index 932d209..913831b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3232,6 +3232,76 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
@@ -74,14 +65,14 @@ index 932d209..933f8cb 100644
+ application can tell the macOS Universal Access zoom feature
+ what part of its user interface needs focus."
+
+ Ref: developer.apple.com/documentation/applicationservices/universalaccess_h
+ Ref: developer.apple.com/documentation/applicationservices/1458830-uazoomchangefocus
+ Ref: https://developer.apple.com/documentation/applicationservices/universalaccess_h
+ Ref: https://developer.apple.com/documentation/applicationservices/1458830-uazoomchangefocus
+
+ This is the same approach used by iTerm2 (PTYTextView.m,
+ method refreshAccessibility).
+
+ Both mechanisms are needed: NSAccessibility serves VoiceOver and
+ screen readers; UAZoomChangeFocus serves macOS Zoom "Follow
+ screen readers; UAZoomChangeFocus serves macOS Zoom's "Follow
+ keyboard focus" feature, which does not reliably track custom views
+ through NSAccessibility notifications alone. */
+ {
@@ -102,8 +93,8 @@ index 932d209..933f8cb 100644
+ primary screen (CG accessibility coordinate space).
+ convertRectToScreen: returns Quartz coordinates (origin at
+ bottom-left), so we flip the y axis. This coordinate
+ conversion follows the same pattern used by iTerm2
+ (PTYTextView.m, accessibilityConvertScreenRect:). */
+ conversion follows the same pattern used by iTerm2's
+ accessibilityConvertScreenRect: method. */
+ if (UAZoomEnabled ())
+ {
+ NSRect windowRect = [view convertRect:r toView:nil];
@@ -142,10 +133,11 @@ index 932d209..933f8cb 100644
}
@@ -9476,6 +9555,148 @@ - (int) fullscreenState
@end /* EmacsView */
@@ -9474,6 +9553,149 @@ - (int) fullscreenState
return fs_state;
}
+
+#ifdef NS_IMPL_COCOA
+/* ----------------------------------------------------------------
+ Accessibility support for macOS Zoom, VoiceOver, and other AT tools.
@@ -288,9 +280,6 @@ index 932d209..933f8cb 100644
+#endif /* NS_IMPL_COCOA */
+
+
@end /* EmacsView */
/* ==========================================================================
--
2.43.0