Commit Graph

33 Commits

Author SHA1 Message Date
07826b61a0 patches: squash perf fixes into respective patches, clean 9-patch series
Performance fixes folded back:
- BUF_CHARS_MODIFF → patch 0002 (implement buffer accessibility element)
- UAZoomEnabled cache + rate-limit → patch 0000 (Zoom integration)

Also in patch 0000: ns_zoom_face_is_selected (standalone compilation).
Also in patch 0001: ns_accessibility_enabled defaults to nil.
2026-03-01 05:58:42 +01:00
256263343d patches: fix standalone compilation + accessibility default + perf
Three fixes:
1. Patch 0000 now compiles standalone: replaced forward declaration
   of ns_ax_face_is_selected (defined in VoiceOver patches) with
   self-contained ns_zoom_face_is_selected in the Zoom patch.

2. ns_accessibility_enabled defaults to nil: eliminates ALL VoiceOver
   overhead (text cache rebuild, AX notifications, Mach IPC to AX
   server) when VoiceOver is not in use. Zero per-redisplay cost.
   Enable with (setq ns-accessibility-enabled t).

3. UAZoomEnabled() cached for 1s + ns_zoom_track_completion rate-
   limited to 2Hz: eliminates 150-600µs/frame of IPC overhead.
2026-03-01 05:51:03 +01:00
6b3843e0c6 patches: fix O(position) performance via UAZoomEnabled caching
Root cause (per Opus analysis): UAZoomEnabled() is a synchronous
Mach IPC roundtrip to macOS Accessibility server, called 3x per
redisplay cycle. At 60fps = 180 IPC roundtrips/second blocking the
main thread. Combined with Emacs's inherent O(position) redisplay
cost, this compounded into progressive choppy behavior.

Fix 1: ns_zoom_enabled_p() caches UAZoomEnabled() for 1 second.
Fix 2: ns_zoom_track_completion() rate-limited to 2 Hz.

Also includes BUF_CHARS_MODIFF fix (patch 0009) for VoiceOver cache.
2026-03-01 05:23:59 +01:00
cd16d45584 patches: fix O(buffer) cache invalidation caused by font-lock
BUF_CHARS_MODIFF fix — the core performance regression:
ensureTextCache checked BUF_MODIFF which font-lock bumps on every
redisplay. Each cursor movement in a large file triggered full buffer
rebuild. Now uses BUF_CHARS_MODIFF (changes only on char insert/delete).
2026-03-01 04:56:37 +01:00
bc71e58123 patches: fix two more compile errors
- Remove f->child_frame_list (field does not exist in struct frame)
- Fix dangling else-if after goto label (skip_overlay_scan)
2026-03-01 04:33:35 +01:00
3d2fa7a54e patches: fix O(overlays) performance regression
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).
2026-03-01 04:26:12 +01:00
84eb777065 patches: fix all compile errors and review issues
- ZV_S -> BUF_ZV (undefined macro)
- cf->current_buffer -> XWINDOW(cf->selected_window)->contents
  (current_buffer is a thread macro, can't use as field name)
- find_newline: add record_unwind_current_buffer + set_buffer_internal_1
- ns_zoom_track_completion: add specpdl unwind protection
- ns_zoom_face_is_selected: replace with forward decl of ns_ax_face_is_selected
  (eliminates duplicate)
- childFrameLastBuffer: struct buffer * -> Lisp_Object (safe vs kill-buffer)
- EmacsView dealloc: xfree childFrameLastCandidate (memory leak)
- postCompletionAnnouncementForBuffer: add block_input/unblock_input
2026-03-01 03:58:04 +01:00
b283068f82 patches: add Zoom completion tracking (overlay + child frame)
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.
2026-03-01 03:38:58 +01:00
9110eee881 patches: fix duplicate lastCursorRect ivar (build error)
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.
2026-03-01 03:20:23 +01:00
74fcee0820 patches: regenerate for combined application (Zoom + VoiceOver)
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.
2026-03-01 03:02:46 +01:00
132e32795f patches: review iteration 1 fixes
Shortened ivar comments (line length), broke long ObjC method call,
changed '---' to em-dash in overlay patch comment.
2026-03-01 02:42:49 +01:00
98ca6a378d patches: move lastCursorRect ivar from patch 1 to patch 5
The ivar was declared in patch 0001 but first used in patch 0005,
creating dead code in intermediate commits 0001-0004.  Now each
commit only introduces declarations that are immediately used.
2026-02-28 22:55:31 +01:00
61b5b5daf1 patches: fix windowWillResize em-dash regression (iteration 3)
Patch 0007 bulk em-dash→triple-dash replacement accidentally changed
windowWillResize title format string and strstr search, introducing
a user-visible regression. Reverted those two lines to em-dash.
2026-02-28 22:45:05 +01:00
9d2b1da729 patches: fix all review blockers (iteration 2)
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)
2026-02-28 22:39:57 +01:00
d9b4cbb87a patches: restructure per reviewer feedback
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
2026-02-28 22:28:35 +01:00
bbe683e752 patches: fix 3 blockers — duplicate functions, idx typo, doc cap
BLOCKER fixes:
1. Remove duplicate ns_ax_face_is_selected, ns_ax_selected_overlay_text,
   ns_ax_selected_child_frame_text definitions from patch 0002
   (now defined only in 0007/0008 where they belong)
2. Fix idx → point_idx in accessibilityInsertionPointLineNumber (0002)
3. Remove stale 100K cap reference from documentation (0006)

Architecture fix:
- ns_ax_selected_child_frame_text moved from 0007 to 0008
  (where it logically belongs)

Verified: all 8 patches apply cleanly on fresh emacs HEAD.
2026-02-28 22:00:10 +01:00
30089e9413 patches: fold line index + remove NS_AX_TEXT_CAP into 0001-0002
- 0001: remove NS_AX_TEXT_CAP (100K char cap), add lineStartOffsets/
  lineCount ivars and method declarations to nsterm.h
- 0002: add lineForAXIndex:/rangeForLine: O(log L) helpers, build line
  index in ensureTextCache, replace O(L) line scanning in
  accessibilityInsertionPointLineNumber/accessibilityLineForIndex/
  accessibilityRangeForLine, free index in invalidateTextCache/dealloc
- 0009 deleted (folded into 0001+0002)
- README.txt: remove NS_AX_TEXT_CAP references, update known
  limitations, stress test threshold 50K lines
2026-02-28 21:39:30 +01:00
Martin Sukany
98b3d04597 Revert "patches: add 0009 resource safety hardening + update 0007/0008"
This reverts commit acc2a2985e.
2026-02-28 19:05:02 +01:00
acc2a2985e patches: add 0009 resource safety hardening + update 0007/0008
New patch 0009 fixes HIGH severity issues from Opus review:
- Announcement coalescing (50ms debounce)
- cachedText retain+autorelease in accessibilityValue
- EmacsView dealloc: nil out emacsView on all AX elements
- Nil guards on protocol methods + overlayZoomActive

0007 updated: revert accidental em-dash→triple-dash, add overlayZoomActive nil guards
0008 updated: specpdl exception safety for accessibilityUpdating, lastChildFrameBuffer staticpro

Series now 9 patches total (0001-0006 unchanged, 0007-0009 new/updated).
2026-02-28 18:45:30 +01:00
0f7608326c patches: fix 2 blockers from Opus review
BLOCKER #1: accessibilityUpdating flag exception safety.
A Lisp signal (longjmp) during postAccessibilityUpdates left
the re-entrance flag permanently YES, suppressing all future
AX notifications → VoiceOver goes silent randomly.
Fix: specpdl unwind protection (record_unwind_protect_ptr)
resets the flag on any longjmp. All 3 exit points use unbind_to.

BLOCKER #2: static struct buffer *lastBuffer dangling pointer.
Raw C pointer to buffer struct has no GC protection. After
kill-buffer, the pointer dangles.
Fix: file-scope Lisp_Object lastChildFrameBuffer with staticpro.
EQ comparison instead of pointer equality.

Also: revert accidental em-dash → triple-dash in title bar (0007),
fix README factual error (BUF_OVERLAY_MODIFF cache key).
2026-02-28 18:29:19 +01:00
c05b46b058 patches: 0007 textDidChange fix (hl-line-mode), remove config workaround 2026-02-28 17:42:00 +01:00
beb5e14adf patches: revert textDidChange from 0007, config workarounds
- 0007 reverted to original else-if (no textDidChange flag)
- config: disable hl-line-mode (BUF_MODIFF blocking VoiceOver)
- config: org-startup-folded 'content (all headings, body hidden)
- config: corfu-auto-prefix 3 + delay re-set hook after Doom init
2026-02-28 17:39:51 +01:00
edbed0a116 patches: 0007 fix hl-line-mode blocking SelectedTextChanged
hl-line-mode (and similar) bumps BUF_MODIFF via text property
changes on every cursor movement. The else-if structure caused
the modiff branch to fire (skipping ValueChanged correctly) but
also blocked the cursor-move branch (SelectedTextChanged).

Fix: use textDidChange flag to decouple the two branches.
ValueChanged and SelectedTextChanged remain mutually exclusive
for real edits, but SelectedTextChanged now fires when only
text properties changed.
2026-02-28 17:38:05 +01:00
9772b7e33e patches: drop 0008 (child frame), revert 0007 to clean state
Child frame completion (Corfu) will be handled via config:
corfu-terminal-mode renders as overlays → patch 0007 handles it.
2026-02-28 16:48:53 +01:00
a8af58cff1 patches: split 0007 (overlay) + 0008 (child frame)
0007: Vertico/Icomplete/Ivy overlay completion, Zoom at text left edge
0008: Corfu/Company-box child frame completion, direct UAZoomChangeFocus
2026-02-28 16:02:13 +01:00
92188ab008 patches: v8 0007 - child frame completion (Corfu) + Zoom fix
Added: child frame buffer scanning for Corfu/Company-box.
Fixed: Zoom rect at text area left edge (not window center).
Added: 'selection' face match for company-tooltip-selection.
2026-02-28 15:59:11 +01:00
be4e0bb5be patches: v7 0007 - Zoom left edge + selection face match
Zoom rect now at text area left edge (WINDOW_TEXT_TO_FRAME_PIXEL_X)
with cursor-width (FRAME_COLUMN_WIDTH) instead of full window width.
Face matching adds 'selection' (company-tooltip-selection).
2026-02-28 15:51:06 +01:00
4e5596d9de patches: v6 0007 - fix Zoom Y offset (line_height arithmetic) 2026-02-28 15:39:44 +01:00
9129f032cf patches: v5 0007 - review fixes (em dash, comments, safety docs) 2026-02-28 15:36:50 +01:00
99609f0437 patches: v4 0007 - Zoom follows overlay candidate
Zoom now tracks the selected candidate row via overlayZoomRect
instead of always pointing at the text cursor. Returns to cursor
on typing (chars_modiff change).
2026-02-28 15:33:45 +01:00
9359277143 patches: v3 0007 - face name heuristic for candidate detection
Previous two-reference algorithm failed because:
- Vertico's cursor-space line (face=nil) confused the reference
- Count overlay processed before candidates overlay
- Group titles have distinct faces too

New approach: ns_ax_face_is_selected checks if face symbol name
contains 'current' or 'selected'. Works for all major frameworks
(Vertico, Icomplete, Ivy) without framework-specific code.
2026-02-28 15:25:52 +01:00
fcff3429b1 patches: rewrite 0007 - fix root cause of 'new line' announcement
Root cause: Vertico bumps BOTH BUF_MODIFF (text property face change
from vertico--prompt-selection) and BUF_OVERLAY_MODIFF (overlay-put)
in same cycle. Previous else-if chain meant overlay branch never fired.

Fixes:
1. Overlay check independent (if, not else-if)
2. BUF_CHARS_MODIFF gates ValueChanged (suppress property-only changes)
3. ensureTextCache no longer tracks overlay_modiff (prevents race)
4. Only AnnouncementRequested (no SelectedTextChanged - wrong line)
5. Two-reference face detection + single-candidate
6. Zoom tracking via UAZoomChangeFocus
2026-02-28 15:12:11 +01:00
9408e37a90 patches: rewrite 0007 overlay support
Key changes from previous version:
- Remove overlay text from ns_ax_buffer_text (was causing spurious
  'new line' announcements via VoiceOver text diff)
- Do NOT invalidate text cache on overlay change
- Two-reference face detection (handles selected at any position)
- SDATA scan instead of per-char Faref for newline detection
- Zoom tracking via UAZoomChangeFocus for selected candidate row
- Deduplication via cachedCompletionAnnouncement
2026-02-28 14:57:00 +01:00