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.
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).
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.
B1: setAccessibilityFocused: on EmacsAccessibilityBuffer now checks
![NSThread isMainThread] and dispatches to main via dispatch_async.
Prevents data race + AppKit thread violation from AX server thread.
W1: accessibilityInsertionPointLineNumber and accessibilityLineForIndex:
now use lineRangeForRange iteration — O(lines) instead of O(chars).
W2: ns_ax_scan_interactive_spans skips non-interactive regions using
Fnext_single_property_change for each scannable property and
Fnext_single_char_property_change for keymap overlays.
W3: ns_ax_event_is_line_nav_key inspects Vthis_command against known
navigation command symbols (next-line, previous-line, evil variants,
dired variants) instead of raw key codes. Tab/backtab fallback
retained via last_command_event.
W4: DEFSYM symbols renamed with ns_ax_ prefix (Qns_ax_button, etc.)
to avoid linker collisions with other Emacs source files.
Lisp symbol strings unchanged.
M3: Removed dead enum values (CheckBox, TextField, PopUpButton) and
corresponding dead switch cases.
M4: Improved accessibilityStyleRangeForIndex: comment documenting the
line-granularity simplification.
README: Updated stats, KNOWN LIMITATIONS, DEFSYM docs, test numbering.
Add deadlock prevention section to THREADING MODEL, note async
posting in NOTIFICATION STRATEGY, add design decision 6a, and
add deadlock regression test case (#24) to testing checklist.
The function definition lacked a return type, causing:
nsterm.m:7149:1: error: a type specifier is required for all declarations
Added 'static BOOL' — the function returns YES/NO and is file-scoped.
Updated patch line counts in header and README accordingly.
B1: Fix memory leak in ns_ax_scan_interactive_spans — [spans copy]
returned +1 retained object never released by caller.
Now returns [[spans copy] autorelease].
B2: Remove dead function ns_ax_utf16_length_for_buffer_range —
defined but never called anywhere in the patch.
B3: Add specpdl unwind protection in
EmacsAccessibilityInteractiveSpan setAccessibilityFocused: —
if Fselect_window signals, block_input is now always matched
by unblock_input via record_unwind_protect_void.
W2: Document ns_ax_event_is_line_nav_key fragility in README
Known Limitations (raw keycodes vs command symbols).
W4: Add comment for #include intervals.h (TEXT_PROP_MEANS_INVISIBLE).
M3: accessibilityBoundsForRange: on EmacsView now delegates to the
focused EmacsAccessibilityBuffer for accurate per-range geometry,
with cursor-rect fallback for Zoom.
M4: Add <NSAccessibility> protocol conformance to
EmacsAccessibilityBuffer @interface declaration.
W1: Expanded commit message listing all new types, functions, DEFSYM
additions, and threading model.