patches: review fixes — memory leak, dead code, unwind-protect, protocol conformance

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.
This commit is contained in:
2026-02-27 15:12:40 +01:00
parent 6994403014
commit 0b43fd25e3
2 changed files with 216 additions and 134 deletions

View File

@@ -131,7 +131,9 @@ THREADING MODEL
- postAccessibilityNotificationsForFrame: (full notify logic)
- setAccessibilitySelectedTextRange: (SET_PT_BOTH, marker moves)
- setAccessibilityFocused: on EmacsAccessibilityInteractiveSpan
(dispatches to main queue via dispatch_async)
(dispatches to main queue via dispatch_async; uses specpdl
unwind protection so block_input is always matched by
unblock_input even if Fselect_window signals an error)
- ns_draw_phys_cursor partial update (lastAccessibilityCursorRect,
UAZoomChangeFocus)
@@ -343,8 +345,9 @@ INTERACTIVE SPANS
and referenced directly -- no repeated intern() calls.
Each span is allocated, configured, added to the spans array, then
released (the array retains it). Label priority: completion--string
> buffer substring > help-echo.
released (the array retains it). The function returns an autoreleased
immutable copy of the spans array. Label priority:
completion--string > buffer substring > help-echo.
Tab navigation: -accessibilityChildrenInNavigationOrder returns the
cached span array, rebuilt lazily when interactiveSpansDirty is set.
@@ -381,9 +384,13 @@ ZOOM INTEGRATION
2. EmacsView -accessibilityBoundsForRange: /
-accessibilityFrameForRange:
AT tools (including Zoom) call these with the selectedTextRange
to locate the insertion point. The implementation returns the
screen rect stored in lastAccessibilityCursorRect, with a minimum
size of 1x8 pixels. The legacy parameterized-attribute API
to locate the insertion point. The implementation first delegates
to the focused EmacsAccessibilityBuffer element for accurate
per-range geometry via its accessibilityFrameForRange: method.
If the buffer element returns an empty rect (no valid window or
glyph data), the fallback uses the cached cursor rect stored in
lastAccessibilityCursorRect (minimum size 1x8 pixels). The legacy
parameterized-attribute API
(NSAccessibilityBoundsForRangeParameterizedAttribute) is supported
via -accessibilityAttributeValue:forParameter: for older AT
clients.
@@ -479,6 +486,13 @@ KNOWN LIMITATIONS
- GNUstep is explicitly excluded (#ifdef NS_IMPL_COCOA). GNUstep
has a different accessibility model and requires separate work.
- Line navigation detection (ns_ax_event_is_line_nav_key) checks
raw key codes (C-n = 14, C-p = 16, Tab = 9, backtab symbol).
Users who remap keys to navigation commands (e.g. C-j -> next-line)
will not get forced line-granularity announcements for those
bindings. A future improvement would inspect Vthis_command
against known navigation command symbols instead.
- UAZoomChangeFocus always uses kUAZoomFocusTypeInsertionPoint
regardless of cursor style (box, bar, hbar). This is cosmetically
imprecise but functionally correct.