diff --git a/patches/0000-ns-integrate-with-macOS-Zoom-for-cursor-tracking.patch b/patches/0000-ns-integrate-with-macOS-Zoom-for-cursor-tracking.patch index be5bfe9..d26a89d 100644 --- a/patches/0000-ns-integrate-with-macOS-Zoom-for-cursor-tracking.patch +++ b/patches/0000-ns-integrate-with-macOS-Zoom-for-cursor-tracking.patch @@ -1,4 +1,4 @@ -From e27ae42313eb5cb5cab14de348f83db216a17a53 Mon Sep 17 00:00:00 2001 +From 9b7352fee5782beb5dae88710bb66cf23ea242c3 Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 22:39:35 +0100 Subject: [PATCH 0/8] ns: integrate with macOS Zoom for cursor tracking diff --git a/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch b/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch index bf127a2..c65f23f 100644 --- a/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch +++ b/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch @@ -1,4 +1,4 @@ -From 9650910e7ac6e423ea9beaa75033d12693b93c89 Mon Sep 17 00:00:00 2001 +From ce2b1aff0e1834bbf9375bdbace7943f0ee83c89 Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 12:58:11 +0100 Subject: [PATCH 1/8] ns: add accessibility base classes and text extraction diff --git a/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch b/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch index 57200b2..e0fe665 100644 --- a/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch +++ b/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch @@ -1,4 +1,4 @@ -From 9ac52a3f3e57628bd06516bc439b8ec388207098 Mon Sep 17 00:00:00 2001 +From 2197610b35f37f20dcc7a01ffba7b1210bb72561 Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 12:58:11 +0100 Subject: [PATCH 2/8] ns: implement buffer accessibility element (core diff --git a/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch b/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch index e004b27..1a68e91 100644 --- a/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch +++ b/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch @@ -1,4 +1,4 @@ -From 361aecfc858d712943921435454d9a7235d145ed Mon Sep 17 00:00:00 2001 +From d3bd4a705068b2538cda29217eb6ea67c525f9d5 Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 12:58:11 +0100 Subject: [PATCH 3/8] ns: add buffer notification dispatch and mode-line diff --git a/patches/0004-ns-add-interactive-span-elements-for-Tab-navigation.patch b/patches/0004-ns-add-interactive-span-elements-for-Tab-navigation.patch index 5d3c78a..64a552c 100644 --- a/patches/0004-ns-add-interactive-span-elements-for-Tab-navigation.patch +++ b/patches/0004-ns-add-interactive-span-elements-for-Tab-navigation.patch @@ -1,4 +1,4 @@ -From a0ea23e5b05e7ab6048d6dd3e9e05aae00dc6939 Mon Sep 17 00:00:00 2001 +From 5d5aca0665a22d3bf3cce54e53ec58fa9defab6e Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 12:58:11 +0100 Subject: [PATCH 4/8] ns: add interactive span elements for Tab navigation diff --git a/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch b/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch index 307626f..b74d5b4 100644 --- a/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch +++ b/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch @@ -1,4 +1,4 @@ -From ca511140b95caf299ab1b24b7a22de03a2e5b543 Mon Sep 17 00:00:00 2001 +From 31d94ecffbfc42a48c6222a1794b823fd0db7b3c Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 12:58:11 +0100 Subject: [PATCH 5/8] ns: integrate accessibility with EmacsView and redisplay diff --git a/patches/0006-doc-add-VoiceOver-accessibility-section-to-macOS-app.patch b/patches/0006-doc-add-VoiceOver-accessibility-section-to-macOS-app.patch index 704314c..1276644 100644 --- a/patches/0006-doc-add-VoiceOver-accessibility-section-to-macOS-app.patch +++ b/patches/0006-doc-add-VoiceOver-accessibility-section-to-macOS-app.patch @@ -1,4 +1,4 @@ -From 2cfc623598b666515fe3cf05ee8c578601e0e587 Mon Sep 17 00:00:00 2001 +From b863369a4d33a3488c3fa9de0cf0eca687b40447 Mon Sep 17 00:00:00 2001 From: Martin Sukany Date: Sat, 28 Feb 2026 12:58:11 +0100 Subject: [PATCH 6/8] doc: add VoiceOver accessibility section to macOS diff --git a/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch b/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch index b199aed..24f721a 100644 --- a/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch +++ b/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch @@ -1,4 +1,4 @@ -From 239d804cf216a05a2b62aeeda7ab2cc5795c158b Mon Sep 17 00:00:00 2001 +From 6b9c326c56346bc55381d4d5c68cd34b59165417 Mon Sep 17 00:00:00 2001 From: Daneel Date: Mon, 2 Mar 2026 18:39:46 +0100 Subject: [PATCH 7/8] ns: announce overlay completion candidates for VoiceOver diff --git a/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch b/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch index 8a4144b..ecf31a1 100644 --- a/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch +++ b/patches/0008-ns-announce-child-frame-completion-candidates-for-Vo.patch @@ -1,4 +1,4 @@ -From 235fb607dfe06a242044218a2ed0ea82fed4f82f Mon Sep 17 00:00:00 2001 +From 0cd27cd398ebcbaadd526b404cf7d549bfe53a4a Mon Sep 17 00:00:00 2001 From: Daneel Date: Mon, 2 Mar 2026 18:49:13 +0100 Subject: [PATCH 8/8] ns: announce child frame completion candidates for @@ -33,8 +33,8 @@ area announcements. doc/emacs/macos.texi | 14 +- etc/NEWS | 18 +- src/nsterm.h | 20 ++ - src/nsterm.m | 504 +++++++++++++++++++++++++++++++++++++------ - 4 files changed, 482 insertions(+), 74 deletions(-) + src/nsterm.m | 511 +++++++++++++++++++++++++++++++++++++------ + 4 files changed, 489 insertions(+), 74 deletions(-) diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi index 8d4a7825d8..03a657f970 100644 @@ -149,7 +149,7 @@ index 21a93bc799..bdd40b8eb7 100644 @end diff --git a/src/nsterm.m b/src/nsterm.m -index 8f744d1bf3..1f3b2ad78a 100644 +index 8f744d1bf3..dc5b965468 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1126,24 +1126,19 @@ Uses CFAbsoluteTimeGetCurrent() (~5 ns, a VDSO read) for timing. */ @@ -339,7 +339,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 specpdl_ref count = SPECPDL_INDEX (); record_unwind_current_buffer (); /* Ensure block_input is always matched by unblock_input even if -@@ -9053,22 +9159,33 @@ - (void)postFocusedCursorNotification:(ptrdiff_t)point +@@ -9053,20 +9159,38 @@ - (void)postFocusedCursorNotification:(ptrdiff_t)point && granularity == ns_ax_text_selection_granularity_character); @@ -368,6 +368,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 - selection so VoiceOver reads the appropriate text. */ - if (!isCharMove) - moveInfo[@"AXTextSelectionGranularity"] = @(granularity); +- + BOOL isDiscontiguous + = (direction == ns_ax_text_selection_direction_discontiguous); + if (!isDiscontiguous && !isCharMove) @@ -375,15 +376,19 @@ index 8f744d1bf3..1f3b2ad78a 100644 + moveInfo[@"AXTextSelectionDirection"] = @(direction); + moveInfo[@"AXTextSelectionGranularity"] = @(granularity); + } - -+ moveInfo[NSAccessibilityUIElementsKey] = @[self]; ++ ++ /* Post on self (the EmacsAXBuffer element), not on the parent ++ EmacsView. When the notification originates from the element ++ whose selection changed, VoiceOver calls accessibilityLineForIndex: ++ on that element to determine the line to read. Posting from the ++ parent view with UIElementsKey causes VoiceOver to call ++ accessibilityLineForIndex: on the view instead, which returns an ++ incorrect range in specialised buffers (org-agenda, org-super-agenda) ++ where line geometry differs from plain text. */ ns_ax_post_notification_with_info ( -- self, -+ self.emacsView, + self, NSAccessibilitySelectedTextChangedNotification, - moveInfo); - -@@ -9166,12 +9283,17 @@ user expectation ("w" jumps to next word and reads it). */ +@@ -9166,12 +9290,17 @@ user expectation ("w" jumps to next word and reads it). */ } } @@ -406,7 +411,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 if (cachedText && granularity == ns_ax_text_selection_granularity_line) { -@@ -9236,6 +9358,11 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b +@@ -9236,6 +9365,11 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b block_input (); specpdl_ref count2 = SPECPDL_INDEX (); @@ -418,7 +423,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 record_unwind_protect_void (unblock_input); record_unwind_current_buffer (); if (b != current_buffer) -@@ -9412,12 +9539,29 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f +@@ -9412,12 +9546,29 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f if (!b) return; @@ -448,7 +453,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 if (modiff != self.cachedModiff) { self.cachedModiff = modiff; -@@ -9431,6 +9575,7 @@ Text property changes (e.g. face updates from +@@ -9431,6 +9582,7 @@ Text property changes (e.g. face updates from { self.cachedCharsModiff = chars_modiff; [self postTextChangedNotification:point]; @@ -456,7 +461,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 } } -@@ -9453,8 +9598,15 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property +@@ -9453,8 +9605,15 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property displayed in the minibuffer. In normal editing buffers, font-lock and other modes change BUF_OVERLAY_MODIFF on every redisplay, triggering O(overlays) work per keystroke. @@ -474,7 +479,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 goto skip_overlay_scan; int selected_line = -1; -@@ -9500,7 +9652,18 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property +@@ -9500,7 +9659,18 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property self.cachedPoint = point; self.cachedMarkActive = markActive; @@ -494,7 +499,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 NSInteger direction = ns_ax_text_selection_direction_discontiguous; if (point > oldPoint) direction = ns_ax_text_selection_direction_next; -@@ -9512,6 +9675,7 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property +@@ -9512,6 +9682,7 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property /* --- Granularity detection --- */ NSInteger granularity = ns_ax_text_selection_granularity_unknown; @@ -502,7 +507,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 [self ensureTextCache]; if (cachedText && oldPoint > 0) { -@@ -9526,7 +9690,18 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property +@@ -9526,7 +9697,18 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property NSRange newLine = [cachedText lineRangeForRange: NSMakeRange (newIdx, 0)]; if (oldLine.location != newLine.location) @@ -522,7 +527,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 else { NSUInteger dist = (newIdx > oldIdx -@@ -9548,34 +9723,23 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property +@@ -9548,34 +9730,23 @@ frameworks like Vertico bump BOTH BUF_MODIFF (via text property granularity = ns_ax_text_selection_granularity_line; } @@ -570,7 +575,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 { NSWindow *win = [self.emacsView window]; if (win) -@@ -9734,6 +9898,13 @@ - (NSRect)accessibilityFrame +@@ -9734,6 +9905,13 @@ - (NSRect)accessibilityFrame if (vis_start >= vis_end) return @[]; @@ -584,7 +589,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 block_input (); specpdl_ref blk_count = SPECPDL_INDEX (); record_unwind_protect_void (unblock_input); -@@ -9858,6 +10029,7 @@ than O(chars). Fall back to pos+1 as safety net. */ +@@ -9858,6 +10036,7 @@ than O(chars). Fall back to pos+1 as safety net. */ pos = span_end; } @@ -592,7 +597,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 return [[spans copy] autorelease]; } -@@ -10039,6 +10211,10 @@ - (void)dealloc +@@ -10039,6 +10218,10 @@ - (void)dealloc #endif [accessibilityElements release]; @@ -603,7 +608,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 [[self menu] release]; [super dealloc]; } -@@ -11488,6 +11664,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f +@@ -11488,6 +11671,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f windowClosing = NO; processingCompose = NO; @@ -613,7 +618,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 scrollbarsNeedingUpdate = 0; fs_state = FULLSCREEN_NONE; fs_before_fs = next_maximized = -1; -@@ -12796,6 +12975,154 @@ - (id)accessibilityFocusedUIElement +@@ -12796,6 +12982,154 @@ - (id)accessibilityFocusedUIElement The existing elements carry cached state (modiff, point) from the previous redisplay cycle. Rebuilding first would create fresh elements with current values, making change detection impossible. */ @@ -768,7 +773,7 @@ index 8f744d1bf3..1f3b2ad78a 100644 - (void)postAccessibilityUpdates { NSTRACE ("[EmacsView postAccessibilityUpdates]"); -@@ -12806,11 +13133,64 @@ - (void)postAccessibilityUpdates +@@ -12806,11 +13140,64 @@ - (void)postAccessibilityUpdates /* Re-entrance guard: VoiceOver callbacks during notification posting can trigger redisplay, which calls ns_update_end, which calls us