patches: fix all safe pre-submission issues

- Blocker #1: add BOOL emacsMovedCursor = YES in patch 0005 so series
  compiles standalone; patch 0008 replaces it with !voiceoverSetPoint
- Blocker #3: change all Daneel authorship to Martin Sukany
- Zoom gate: remove ns_accessibility_enabled guards from Zoom code
  paths (0005 no longer adds them; 0008 retains the clarifying comment)
- eassert: remove redundant BUFFER_LIVE_P eassert with contradictory
  comment in patch 0008
- macos.texi: integrate orphan 'Block-style cursors' paragraph as
  @item in the Known Limitations list
- cindex: restore @cindex Zoom, cursor tracking (macOS) removed in 0008
- ChangeLog 0002: list only functions actually added in that patch
- ChangeLog 0008: accurate description (remove wrong BUF_CHARS_MODIFF
  claim for ensureTextCache; ns_ax_buffer_text block_input was in 0001)
- git apply --check: all 9 patches apply cleanly on fresh base

Remaining open issue: BUF_MODIFF regression in patch 0007 (ensureTextCache
O(N) rebuild per font-lock pass) requires design decision before
submission.
This commit is contained in:
2026-03-03 17:50:18 +01:00
parent 3a3fbbac19
commit 70f0cb9a86
9 changed files with 270 additions and 247 deletions

View File

@@ -1,7 +1,7 @@
From f2e97ea6ba4ffc1c73e625f9d61636b7261cbecf Mon Sep 17 00:00:00 2001
From 3f894218b771f2aa098f19dfb4bdc8b13408c8c8 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 5/8] ns: integrate accessibility with EmacsView and redisplay
Subject: [PATCH 6/9] ns: integrate accessibility with EmacsView and redisplay
Wire the accessibility element tree into EmacsView and hook it into
the redisplay cycle.
@@ -24,7 +24,7 @@ com.apple.accessibility.api distributed notification.
---
etc/NEWS | 13 ++
src/nsterm.m | 474 +++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 475 insertions(+), 12 deletions(-)
2 files changed, 477 insertions(+), 10 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 4c149e41d6..7f917f93b2 100644
@@ -51,24 +51,15 @@ index 4c149e41d6..7f917f93b2 100644
** Re-introduced dictation, lost in Emacs v30 (macOS).
We lost macOS dictation in v30 when migrating to NSTextInputClient.
diff --git a/src/nsterm.m b/src/nsterm.m
index 8aa5b6ac1b..32eb04acef 100644
index d65609cc79..4ba9b41b3b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1275,7 +1275,7 @@ If a completion candidate is selected (overlay or child frame),
static void
ns_zoom_track_completion (struct frame *f, EmacsView *view)
{
- if (!ns_zoom_enabled_p ())
+ if (!ns_accessibility_enabled || !ns_zoom_enabled_p ())
return;
if (!WINDOWP (f->selected_window))
return;
@@ -1393,7 +1393,8 @@ so the visual offset is (ov_line + 1) * line_h from
(zoomCursorUpdated is NO). */
#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
&& MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
- if (view && !view->zoomCursorUpdated && ns_zoom_enabled_p ()
+ if (ns_accessibility_enabled && view && !view->zoomCursorUpdated
+ if (view && !view->zoomCursorUpdated
+ && ns_zoom_enabled_p ()
&& !NSIsEmptyRect (view->lastCursorRect))
{
@@ -83,15 +74,6 @@ index 8aa5b6ac1b..32eb04acef 100644
}
static void
@@ -3567,7 +3571,7 @@ EmacsView pixels (AppKit, flipped, top-left origin)
#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
&& MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
- if (ns_zoom_enabled_p ())
+ if (ns_accessibility_enabled && ns_zoom_enabled_p ())
{
NSRect windowRect = [view convertRect:r toView:nil];
NSRect screenRect
@@ -6723,9 +6727,56 @@ - (void)applicationDidFinishLaunching: (NSNotification *)notification
}
#endif
@@ -163,14 +145,18 @@ index 8aa5b6ac1b..32eb04acef 100644
-
/* ===================================================================
EmacsAccessibilityBuffer (Notifications) --- AX event dispatch
EmacsAccessibilityBuffer (Notifications) AX event dispatch
@@ -9235,6 +9284,50 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f
@@ -9235,6 +9284,54 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f
granularity = ns_ax_text_selection_granularity_line;
}
+ /* Treat all moves as Emacs-initiated until voiceoverSetPoint
+ tracking is introduced (subsequent patch). */
+ BOOL emacsMovedCursor = YES;
+
+ /* Programmatic jumps that cross a line boundary (]], [[, M-<,
+ xref, imenu, ...) are discontiguous: the cursor teleported to an
+ xref, imenu, ) are discontiguous: the cursor teleported to an
+ arbitrary position, not one sequential step forward/backward.
+ Reporting AXTextSelectionDirectionDiscontiguous causes VoiceOver
+ to re-anchor its rotor browse cursor at the new
@@ -216,7 +202,7 @@ index 8aa5b6ac1b..32eb04acef 100644
/* Post notifications for focused and non-focused elements. */
if ([self isAccessibilityFocused])
[self postFocusedCursorNotification:point
@@ -9347,7 +9440,6 @@ - (NSRect)accessibilityFrame
@@ -9347,7 +9444,6 @@ - (NSRect)accessibilityFrame
@end
@@ -224,7 +210,7 @@ index 8aa5b6ac1b..32eb04acef 100644
/* ===================================================================
EmacsAccessibilityInteractiveSpan --- helpers and implementation
=================================================================== */
@@ -9683,6 +9775,7 @@ - (void)dealloc
@@ -9684,6 +9780,7 @@ - (void)dealloc
[layer release];
#endif
@@ -232,7 +218,7 @@ index 8aa5b6ac1b..32eb04acef 100644
[[self menu] release];
[super dealloc];
}
@@ -11031,6 +11124,32 @@ - (void)windowDidBecomeKey /* for direct calls */
@@ -11032,6 +11129,32 @@ - (void)windowDidBecomeKey /* for direct calls */
XSETFRAME (event.frame_or_window, emacsframe);
kbd_buffer_store_event (&event);
ns_send_appdefined (-1); // Kick main loop
@@ -265,7 +251,7 @@ index 8aa5b6ac1b..32eb04acef 100644
}
@@ -12268,6 +12387,332 @@ - (int) fullscreenState
@@ -12269,6 +12392,332 @@ - (int) fullscreenState
return fs_state;
}
@@ -285,7 +271,7 @@ index 8aa5b6ac1b..32eb04acef 100644
+
+ if (WINDOW_LEAF_P (w))
+ {
+ /* Buffer element --- reuse existing if available. */
+ /* Buffer element reuse existing if available. */
+ EmacsAccessibilityBuffer *elem
+ = [existing objectForKey:[NSValue valueWithPointer:w]];
+ if (!elem)
@@ -319,7 +305,7 @@ index 8aa5b6ac1b..32eb04acef 100644
+ }
+ else
+ {
+ /* Internal (combination) window --- recurse into children. */
+ /* Internal (combination) window recurse into children. */
+ Lisp_Object child = w->contents;
+ while (!NILP (child))
+ {
@@ -431,7 +417,7 @@ index 8aa5b6ac1b..32eb04acef 100644
+ accessibilityUpdating = YES;
+
+ /* Detect window tree change (split, delete, new buffer). Compare
+ FRAME_ROOT_WINDOW --- if it changed, the tree structure changed. */
+ FRAME_ROOT_WINDOW if it changed, the tree structure changed. */
+ Lisp_Object curRoot = FRAME_ROOT_WINDOW (emacsframe);
+ if (!EQ (curRoot, lastRootWindow))
+ {
@@ -440,12 +426,12 @@ index 8aa5b6ac1b..32eb04acef 100644
+ }
+
+ /* If tree is stale, rebuild FIRST so we don't iterate freed
+ window pointers. Skip notifications for this cycle --- the
+ window pointers. Skip notifications for this cycle the
+ freshly-built elements have no previous state to diff against. */
+ if (!accessibilityTreeValid)
+ {
+ [self rebuildAccessibilityTree];
+ /* Invalidate span cache --- window layout changed. */
+ /* Invalidate span cache window layout changed. */
+ for (EmacsAccessibilityElement *elem in accessibilityElements)
+ if ([elem isKindOfClass: [EmacsAccessibilityBuffer class]])
+ [(EmacsAccessibilityBuffer *) elem invalidateInteractiveSpans];
@@ -598,7 +584,7 @@ index 8aa5b6ac1b..32eb04acef 100644
@end /* EmacsView */
@@ -14264,12 +14709,17 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
@@ -14265,12 +14714,17 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
ns_use_srgb_colorspace = YES;
DEFVAR_BOOL ("ns-accessibility-enabled", ns_accessibility_enabled,