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).
Zoom patch 0000 now tracks completion candidates:
- Overlay: Vertico, Icomplete, Ivy (face heuristic on before-string)
- Child frame: Corfu, Company-box (scan buffer text for selected face)
Also fixes duplicate lastCursorRect ivar when applied with VoiceOver.
Zoom (0000) declares lastCursorRect @public in EmacsView.
VoiceOver (0005) was re-declaring it, causing 'duplicate member'
compiler error when both applied together. Removed the duplicate.
VoiceOver patches 0001-0008 now apply cleanly on top of Zoom patch
0000. The full set (git am patches/000*.patch) works without
conflicts. Patch 0005 (integration) merges Zoom fallback and
VoiceOver postAccessibilityUpdates in ns_update_end.
Fixes from Opus maintainer review:
1. [BLOCKER] Zoom code completely removed from ALL intermediate patches
(0005-0007 no longer have UAZoom/overlayZoom at any commit point)
2. [BLOCKER] Unified cursor rect ivar: lastCursorRect (was split
between lastZoomCursorRect and lastAccessibilityCursorRect)
3. [HIGH] Child frame static vars moved to EmacsView ivars
(childFrameLastCandidate/Buffer/Modiff — no cross-frame interference)
4. [HIGH] intern_c_string replaced with Qbefore_string/Qafter_string
5. [MEDIUM] Zoom fallback gated by zoomCursorUpdated flag (no double call)
Major changes:
1. Zoom separated into standalone patch 0000
- UAZoomChangeFocus in ns_draw_window_cursor
- Fallback in ns_update_end for window-switch tracking
- No overlayZoomActive (source of split/switch/move bug)
2. VoiceOver patches 0001-0008 are now Zoom-free
- All UAZoom*, overlayZoom*, kUAZoomFocus references removed
- lastAccessibilityCursorRect kept for VoiceOver bounds queries
- Commit messages cleaned of Zoom references
3. README.txt and TESTING.txt rewritten for new structure
Addresses reviewer (Stéphane Marks) feedback:
- Keep Zoom patch separate from VoiceOver work
- Design discussion needed for non-Zoom patches
- Performance: ns-accessibility-enabled=nil for zero overhead