Performance issue: editing large files (>~10KB, >2000 lines) caused progressive slowdown regardless of VoiceOver status. Root causes: 1. ns_zoom_find_overlay_candidate_line: called Foverlays_in on the entire visible buffer range on every redisplay when UAZoomEnabled(). In files with many overlays (font-lock, hl-line, show-paren etc.) this was O(overlays) Lisp work per keystroke. 2. postAccessibilityNotificationsForFrame: when ns-accessibility-enabled is non-nil, checked BUF_OVERLAY_MODIFF every redisplay. font-lock bumps this on every redraw, triggering ns_ax_selected_overlay_text (another O(overlays) scan) for non-minibuffer windows. Fix: Both scans now guard with MINI_WINDOW_P check. Overlay completion frameworks (Vertico, Icomplete, Ivy) only display candidates in minibuffer windows --- no completion framework puts selected-face overlays in normal editing buffers. For non-minibuffer windows both functions return immediately with zero Lisp calls. Additionally: ns_zoom_find_child_frame_candidate is skipped when f->child_frame_list is nil (no child frames = no Corfu popup).
109 lines
4.0 KiB
Diff
109 lines
4.0 KiB
Diff
From 58616020bbd9e088428e7fd76cc28c19c60cbe05 Mon Sep 17 00:00:00 2001
|
|
From: Martin Sukany <martin@sukany.cz>
|
|
Date: Sat, 28 Feb 2026 12:58:11 +0100
|
|
Subject: [PATCH 7/9] doc: add VoiceOver accessibility section to macOS
|
|
appendix
|
|
|
|
* doc/emacs/macos.texi (VoiceOver Accessibility): New node. Document
|
|
screen reader usage, keyboard navigation, completion announcements,
|
|
---
|
|
doc/emacs/macos.texi | 75 ++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 75 insertions(+)
|
|
|
|
diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
|
|
index 6bd334f..4825cf9 100644
|
|
--- a/doc/emacs/macos.texi
|
|
+++ b/doc/emacs/macos.texi
|
|
@@ -36,6 +36,7 @@ Support}), but we hope to improve it in the future.
|
|
* Mac / GNUstep Basics:: Basic Emacs usage under GNUstep or macOS.
|
|
* Mac / GNUstep Customization:: Customizations under GNUstep or macOS.
|
|
* Mac / GNUstep Events:: How window system events are handled.
|
|
+* VoiceOver Accessibility:: Screen reader support on macOS.
|
|
* GNUstep Support:: Details on status of GNUstep support.
|
|
@end menu
|
|
|
|
@@ -272,6 +273,80 @@ and return the result as a string. You can also use the Lisp function
|
|
services and receive the results back. Note that you may need to
|
|
restart Emacs to access newly-available services.
|
|
|
|
+@node VoiceOver Accessibility
|
|
+@section VoiceOver Accessibility (macOS)
|
|
+@cindex VoiceOver
|
|
+@cindex accessibility (macOS)
|
|
+@cindex screen reader (macOS)
|
|
+@cindex Zoom, cursor tracking (macOS)
|
|
+
|
|
+ When built with the Cocoa interface on macOS, Emacs exposes buffer
|
|
+content, cursor position, mode lines, and interactive elements to the
|
|
+macOS accessibility subsystem. This enables use with VoiceOver,
|
|
+Apple's built-in screen reader, and with other assistive technology
|
|
+such as macOS Zoom.
|
|
+
|
|
+ Toggle VoiceOver with @kbd{Cmd-F5} (or via System Settings,
|
|
+Accessibility, VoiceOver). When Emacs is focused, VoiceOver announces
|
|
+the buffer name and current line. Standard Emacs navigation produces
|
|
+speech feedback:
|
|
+
|
|
+@itemize @bullet
|
|
+@item
|
|
+Arrow keys read individual characters (left/right) or full lines
|
|
+(up/down).
|
|
+@item
|
|
+@kbd{M-f} and @kbd{M-b} announce words.
|
|
+@item
|
|
+@kbd{C-n} and @kbd{C-p} read the destination line.
|
|
+@item
|
|
+Shift-modified movement announces selected or deselected text.
|
|
+@item
|
|
+@key{TAB} and @kbd{S-@key{TAB}} navigate interactive elements
|
|
+(buttons, links, completion candidates) within a buffer.
|
|
+@end itemize
|
|
+
|
|
+ The @file{*Completions*} buffer announces each completion candidate
|
|
+as you navigate, even while keyboard focus remains in the minibuffer.
|
|
+
|
|
+ macOS Zoom (System Settings, Accessibility, Zoom) tracks the Emacs
|
|
+cursor automatically when set to follow keyboard focus. The cursor
|
|
+position is communicated via @code{UAZoomChangeFocus} and the
|
|
+@code{AXBoundsForRange} accessibility attribute.
|
|
+
|
|
+@vindex ns-accessibility-enabled
|
|
+ To disable the accessibility interface entirely (for instance, to
|
|
+eliminate overhead on systems where assistive technology is not in
|
|
+use), set @code{ns-accessibility-enabled} to @code{nil}. The default
|
|
+is @code{t}.
|
|
+
|
|
+@subheading Known Limitations
|
|
+
|
|
+@itemize @bullet
|
|
+@item
|
|
+Very large buffers (tens of megabytes) may cause slow initial
|
|
+accessibility text extraction. Once cached, subsequent queries
|
|
+are fast.
|
|
+@item
|
|
+Mode-line text extraction handles only character glyphs. Mode lines
|
|
+using icon fonts (e.g., @code{doom-modeline} with nerd-font icons)
|
|
+produce incomplete accessibility text.
|
|
+@item
|
|
+The accessibility virtual element tree is rebuilt automatically on
|
|
+window configuration changes (splits, deletions, new buffers).
|
|
+@item
|
|
+Right-to-left (bidi) text is exposed correctly as buffer content,
|
|
+but @code{accessibilityRangeForPosition} hit-testing assumes
|
|
+left-to-right glyph layout.
|
|
+@end itemize
|
|
+
|
|
+ This support is available only on the Cocoa build; GNUstep has a
|
|
+different accessibility model and is not yet supported
|
|
+(@pxref{GNUstep Support}). Evil-mode block cursors are handled
|
|
+correctly: character navigation announces the character at the cursor
|
|
+position, not the character before it.
|
|
+
|
|
+
|
|
@node GNUstep Support
|
|
@section GNUstep Support
|
|
|
|
--
|
|
2.43.0
|
|
|