Commit Graph

199 Commits

Author SHA1 Message Date
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
419762bde0 patches: add 0009 line index perf fix, update README.txt
New patch 0009 fixes O(L) line scanning in accessibilityLineForIndex:
and accessibilityRangeForLine: by adding a precomputed lineStartOffsets
array built once per cache rebuild.  Queries go from O(L) linear scan
to O(log L) binary search.

README.txt: updated patch listing, text cache section, known limitations
(O(L) issue now resolved), stress test threshold raised to 50,000 lines.
2026-02-28 21:16:16 +01:00
c82ef86eaf patches: fix 0008 — forward reference + blank lines (maintainer review)
Move file-scope statics (lastChildFrameBuffer/Modiff/Candidate) and
ns_ax_reset_accessibility_updating before announceChildFrameCompletion.
Using them before their declaration was a forward reference (UB in C).

Remove two spurious blank lines at start of announceChildFrameCompletion
method body.
2026-02-28 19:26:55 +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
4f37a8660e patches: update TESTING.txt + README.txt for 0007/0008
TESTING: sections 14 (overlay completion) + 15 (child frame completion)
README: patch series listing, overlay/child frame architecture,
  textDidChange flag, focus restoration, new limitations
2026-02-28 18:01:38 +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
2d053f5a92 patches: 0008 fix EmacsAccessibilityBuffer class name 2026-02-28 17:24:44 +01:00
4c7ce352cd patches: 0008 focus restore after child frame close + corfu delay 2s
- childFrameCompletionActive flag: set by child frame handler,
  cleared when no child frame visible on parent's next cycle
- Posts FocusedUIElementChanged on parent buffer element to
  restore VoiceOver character echo after corfu closes
- corfu-auto-delay: 1.0 → 2.0 (reduce popup noise)
2026-02-28 17:21:44 +01:00
afa65a8201 patches: 0008 restored to confirmed working version (3e5fe81)
Pure version: direct UAZoomChangeFocus, specpdl_ref, re-entrance
guard, buffer switch + unbind_to. No window announcement suppression
(all attempts broke VoiceOver focus tracking or Zoom).
2026-02-28 17:08:49 +01:00
e09b8c61f0 patches: 0008 - setTitle:empty instead of setAccessibilityElement:NO 2026-02-28 17:04:06 +01:00
306cde4f79 patches: restore 0008 + setAccessibilityElement:NO (no Zoom changes)
Restore working 0008 (direct UAZoomChangeFocus, specpdl_ref fix,
re-entrance guard, buffer switch). Only addition: suppress child
frame window announcement via setAccessibilityElement:NO.
No overlayZoomRect/overlayZoomActive changes — 0007 untouched.
2026-02-28 16:59: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
1455542227 patches: 0008 - GroupRole + focus restore + overlayZoom reset
- NSAccessibilityGroupRole (no window announcement, focus tracking OK)
- FocusedUIElementChanged on parent when corfu closes
- overlayZoomActive = NO reset each parent cycle (handles C-g + frame delete)
2026-02-28 16:43:26 +01:00
5a58e3b925 patches: 0008 - setAccessibilityElement:NO (suppress window announcement) 2026-02-28 16:34:41 +01:00
2dc4182856 patches: 0008 - Zoom via parent overlayZoomRect + suppress window announcement 2026-02-28 16:29:26 +01:00
3e5fe814b8 patches: 0008 fix specpdl_ref type (not ptrdiff_t) 2026-02-28 16:19:08 +01:00
5aa0f05a33 patches: 0008 fix current_buffer bug + unbind_to on all return paths
Fbuffer_substring_no_properties operates on current_buffer, not the
passed buffer. Added set_buffer_internal_1 + record_unwind_current_buffer
with unbind_to on every return path.
2026-02-28 16:15:41 +01:00
31fcc1a711 patches: remove stale 0007 (merged overlay+child-frame variant) 2026-02-28 16:11:52 +01:00
659b9e2a1e patches: 0008 fix - re-entrance guard + modiff gate + safety checks
Root cause: child frame path bypassed accessibilityUpdating guard.
Lisp calls in announceChildFrameCompletion triggered redisplay →
ns_update_end → postAccessibilityUpdates → infinite recursion.
2026-02-28 16:11:23 +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
6c502c7af5 patches: squash 0007+0008+0009 into single clean 0007
All overlay fixes in one patch: Fequal face detection,
NSApp announcement target, SelectedTextChanged interrupt.
2026-02-28 14:46:43 +01:00
8a48e72493 patches: add 0009 fix Fequal face comparison in overlay detection 2026-02-28 14:44:37 +01:00
99ed8b4ae4 patches: add 0008 fix overlay announcement bugs
- AnnouncementRequested to NSApp (not self)
- Compare line faces via Fequal (find selected candidate)
- SelectedTextChanged before announcement (interrupt speech)
2026-02-28 14:41:45 +01:00
24fd61f1f6 patches: add 0007 overlay display string support
- Appends overlay before-string/after-string to AX text
- Detects BUF_OVERLAY_MODIFF changes
- Finds highlighted candidate via face text property
- Announces selected candidate via AnnouncementRequested
  (fixes 'new line' instead of reading candidate)
2026-02-28 14:31:02 +01:00
9130268ff0 patches: fix ObjC category declaration warnings
Move postAccessibilityNotificationsForFrame: declaration from
primary @interface to (Notifications) category.
Add invalidateInteractiveSpans to (InteractiveSpans) category.
Fixes 3 compiler warnings (-Wobjc-method-access,
-Wincomplete-implementation, -Wobjc-protocol-method-implementation).
2026-02-28 12:58:18 +01:00
ca77cc8e3d patches: add TESTING.txt with macOS build and VoiceOver evidence 2026-02-28 11:46:53 +01:00
edab71038a patches: 6-patch series (split Buffer into core + notifications)
0001: Base classes + helpers (+587)
  0002: Buffer core protocol (+1089)
  0003: Buffer notifications + ModeLine (+545)
  0004: Interactive spans (+286)
  0005: EmacsView integration + NEWS (+408)
  0006: Documentation (+75)

Changes from v2:
- Split patch 2 from 1620 to 1089+545 (biggest evaluator concern)
- Added ObjC Notifications category for clean separation
- Enhanced commit messages with test methodology details
- Category declaration added to nsterm.h
2026-02-28 10:35:53 +01:00
fa28bb52e1 patches: fix forward dependency (helpers moved to patch 1) 2026-02-28 10:24:39 +01:00
5016155c8a patches: 5-patch VoiceOver series (improved split + safety docs)
Split into 5 logical patches:
  0001: Base classes + text extraction (+474)
  0002: Buffer + ModeLine protocol (+1620)
  0003: Interactive spans (+403)
  0004: EmacsView integration + etc/NEWS (+408)
  0005: Documentation (+75)

Improvements over previous version:
- 5 patches (was 3): finer granularity
- Helpers placed in correct patches (find_completion_overlay_range,
  event_is_line_nav_key moved to patch with their users)
- etc/NEWS moved to last functional patch (0004)
- ChangeLog-format commit messages
- Longjmp safety analysis comment in code
- Code reorganized for clean sequential patches
2026-02-28 10:11:16 +01:00
67b1d25c34 patches: 4-patch VoiceOver series (split + improved docs)
Split VoiceOver accessibility into 4 logical patches:
  0001: Base classes + text extraction (+753)
  0002: Buffer/ModeLine/InteractiveSpan implementations (+1716)
  0003: EmacsView integration + cursor tracking (+395)
  0004: Documentation with known limitations (+75)

Each patch is self-contained: 0001 adds infrastructure that compiles
but doesn't change behavior.  0002 adds protocol implementations.
0003 wires everything into EmacsView.  0004 documents for users.

All patches verified: apply cleanly to current Emacs master,
final state identical to original monolithic patch.
2026-02-28 09:54:51 +01:00
2c8515a0a1 patches: split VoiceOver into 3-patch series, improve docs
Split the monolithic 3011-line patch into logical pieces:
  0001: All new accessibility code (infrastructure, no existing code modified)
  0002: EmacsView integration + cursor tracking (wiring only)
  0003: Documentation (expanded with known limitations)

Improvements:
- Comprehensive commit messages with testing methodology
- Known limitations documented (text cap, bidi, mode-line icons)
- Documentation expanded with Known Limitations section
- Each patch is self-contained and reviewable
2026-02-28 09:34:00 +01:00
bbd328dc81 fix: patch hunk 8 old_count 7→6 (trailer miscount) 2026-02-28 09:10:53 +01:00
b002d3004a patches: fix MRC build — add @synthesize for spanLabel/spanValue 2026-02-27 22:25:36 +01:00
d408a542e5 patches: review fixes — defvar, method extraction, GC safety, window_end_valid
Review-based improvements:
- ns-accessibility-enabled DEFVAR_BOOL (disable AX overhead)
- window_end_valid guard in ns_ax_window_end_charpos
- GC safety comments on Lisp_Object ObjC ivars
- postAccessibilityNotificationsForFrame split into 4 methods
- block_input in ns_ax_completion_text_for_span
- Fplist_get predicate comment
- macos.texi VoiceOver section with defvar docs
- README updated with USER OPTION + REVIEW CHANGES sections
2026-02-27 17:51:39 +01:00
b83a061322 patches: review fixes — eassert, blank lines, Texinfo doc
- nsterm.m: Remove 2 stray blank lines at start of
  ns_ax_event_is_line_nav_key body
- nsterm.m: Add eassert([NSThread isMainThread]) to ensureTextCache
  for explicit main-thread contract enforcement
- New 0002 patch: Texinfo section in doc/emacs/macos.texi documenting
  VoiceOver accessibility, Zoom tracking, completion announcements
- README.txt: Updated file listing and patch index
2026-02-27 17:15:18 +01:00
65c799dc3f patches: review fixes — specpdl protection, overlay_modiff tracking, binary search, enum cleanup
M1: accessibilityRangeForPosition uses specpdl unwind protection for
    block_input/unblock_input (consistent with all other methods).
M2: Track BUF_OVERLAY_MODIFF in ensureTextCache — overlay-only changes
    (timer-based completion highlight) now invalidate the text cache.
M3: Detect narrowing/widening by comparing cachedTextStart vs BUF_BEGV.
m1: Binary search (O(log n)) for visible runs in both
    accessibilityIndexForCharpos and charposForAccessibilityIndex.
m3: Add EmacsAXSpanTypeNone = -1 to enum instead of (EmacsAXSpanType)-1 cast.
m5: Add TODO comment in ns_ax_mode_line_text about non-CHAR_GLYPH limitation.
README: Remove resolved overlay_modiff limitation, document binary search
    and narrowing detection, update architecture section.
2026-02-27 16:56:05 +01:00