Merge remote-tracking branch 'refs/remotes/origin/master'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
diff --git a/src/nsterm.h b/src/nsterm.h
|
||||
index 7c1ee4c..8bf21f6 100644
|
||||
index 7c1ee4c..4abeafe 100644
|
||||
--- a/src/nsterm.h
|
||||
+++ b/src/nsterm.h
|
||||
@@ -453,6 +453,40 @@ enum ns_return_frame_mode
|
||||
@@ -43,20 +43,22 @@ index 7c1ee4c..8bf21f6 100644
|
||||
/* ==========================================================================
|
||||
|
||||
The main Emacs view
|
||||
@@ -471,6 +505,12 @@ enum ns_return_frame_mode
|
||||
@@ -471,6 +505,14 @@ enum ns_return_frame_mode
|
||||
#ifdef NS_IMPL_COCOA
|
||||
char *old_title;
|
||||
BOOL maximizing_resize;
|
||||
+ NSMutableArray *accessibilityElements;
|
||||
+ Lisp_Object lastSelectedWindow;
|
||||
+ Lisp_Object lastRootWindow;
|
||||
+ BOOL accessibilityTreeValid;
|
||||
+ BOOL accessibilityUpdating;
|
||||
+ @public
|
||||
+ NSRect lastAccessibilityCursorRect;
|
||||
+ @protected
|
||||
#endif
|
||||
BOOL font_panel_active;
|
||||
NSFont *font_panel_result;
|
||||
@@ -528,6 +568,13 @@ enum ns_return_frame_mode
|
||||
@@ -528,6 +570,13 @@ enum ns_return_frame_mode
|
||||
- (void)windowWillExitFullScreen;
|
||||
- (void)windowDidExitFullScreen;
|
||||
- (void)windowDidBecomeKey;
|
||||
@@ -71,7 +73,7 @@ index 7c1ee4c..8bf21f6 100644
|
||||
|
||||
|
||||
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||
index 932d209..6543e3b 100644
|
||||
index 932d209..e830f54 100644
|
||||
--- a/src/nsterm.m
|
||||
+++ b/src/nsterm.m
|
||||
@@ -1104,6 +1104,11 @@ ns_update_end (struct frame *f)
|
||||
@@ -124,7 +126,7 @@ index 932d209..6543e3b 100644
|
||||
ns_focus (f, NULL, 0);
|
||||
|
||||
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||
@@ -6847,6 +6883,717 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
|
||||
@@ -6847,6 +6883,756 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -759,13 +761,52 @@ index 932d209..6543e3b 100644
|
||||
+ kAXTextStateChangeTypeSelectionMove = 1. */
|
||||
+ if (point != self.cachedPoint || markActive != self.cachedMarkActive)
|
||||
+ {
|
||||
+ ptrdiff_t oldPoint = self.cachedPoint;
|
||||
+ self.cachedPoint = point;
|
||||
+ self.cachedMarkActive = markActive;
|
||||
+
|
||||
+ /* Compute direction: 2=Previous, 3=Next, 4=Discontiguous. */
|
||||
+ NSInteger direction = 4;
|
||||
+ if (point > oldPoint)
|
||||
+ direction = 3;
|
||||
+ else if (point < oldPoint)
|
||||
+ direction = 2;
|
||||
+
|
||||
+ /* Compute granularity from movement distance.
|
||||
+ Check if we crossed a newline → line movement (2).
|
||||
+ Otherwise single char (0) or discontiguous (5=unknown). */
|
||||
+ NSInteger granularity = 5;
|
||||
+ [self ensureTextCache];
|
||||
+ if (cachedText && oldPoint > 0)
|
||||
+ {
|
||||
+ ptrdiff_t delta = point - oldPoint;
|
||||
+ if (delta == 1 || delta == -1)
|
||||
+ granularity = 0; /* Character. */
|
||||
+ else
|
||||
+ {
|
||||
+ /* Check for line crossing by looking for newlines
|
||||
+ between old and new position. */
|
||||
+ NSUInteger lo = (NSUInteger)
|
||||
+ (MIN (oldPoint, point) - cachedTextStart);
|
||||
+ NSUInteger hi = (NSUInteger)
|
||||
+ (MAX (oldPoint, point) - cachedTextStart);
|
||||
+ NSUInteger tlen = [cachedText length];
|
||||
+ if (lo < tlen && hi <= tlen)
|
||||
+ {
|
||||
+ NSRange searchRange = NSMakeRange (lo, hi - lo);
|
||||
+ NSRange nl = [cachedText rangeOfString:@"\n"
|
||||
+ options:0
|
||||
+ range:searchRange];
|
||||
+ if (nl.location != NSNotFound)
|
||||
+ granularity = 2; /* Line. */
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ NSDictionary *moveInfo = @{
|
||||
+ @"AXTextStateChangeType": @1,
|
||||
+ @"AXTextSelectionDirection": @4,
|
||||
+ @"AXTextSelectionGranularity": @3
|
||||
+ @"AXTextSelectionDirection": @(direction),
|
||||
+ @"AXTextSelectionGranularity": @(granularity)
|
||||
+ };
|
||||
+ NSAccessibilityPostNotificationWithUserInfo (
|
||||
+ self,
|
||||
@@ -842,7 +883,7 @@ index 932d209..6543e3b 100644
|
||||
/* ==========================================================================
|
||||
|
||||
EmacsView implementation
|
||||
@@ -6889,6 +7636,7 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
|
||||
@@ -6889,6 +7675,7 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
|
||||
[layer release];
|
||||
#endif
|
||||
|
||||
@@ -850,7 +891,7 @@ index 932d209..6543e3b 100644
|
||||
[[self menu] release];
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -8237,6 +8985,18 @@ ns_in_echo_area (void)
|
||||
@@ -8237,6 +9024,18 @@ ns_in_echo_area (void)
|
||||
XSETFRAME (event.frame_or_window, emacsframe);
|
||||
kbd_buffer_store_event (&event);
|
||||
ns_send_appdefined (-1); // Kick main loop
|
||||
@@ -869,7 +910,7 @@ index 932d209..6543e3b 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -9474,6 +10234,259 @@ ns_in_echo_area (void)
|
||||
@@ -9474,6 +10273,290 @@ ns_in_echo_area (void)
|
||||
return fs_state;
|
||||
}
|
||||
|
||||
@@ -1028,37 +1069,68 @@ index 932d209..6543e3b 100644
|
||||
+ if (!emacsframe)
|
||||
+ return;
|
||||
+
|
||||
+ /* Re-entrance guard: VoiceOver callbacks during notification posting
|
||||
+ can trigger redisplay, which calls ns_update_end, which calls us
|
||||
+ again. Prevent infinite recursion. */
|
||||
+ if (accessibilityUpdating)
|
||||
+ return;
|
||||
+ accessibilityUpdating = YES;
|
||||
+
|
||||
+ /* Detect window tree change (split, delete, new buffer). Compare
|
||||
+ FRAME_ROOT_WINDOW — if it changed, the tree structure changed. */
|
||||
+ Lisp_Object curRoot = FRAME_ROOT_WINDOW (emacsframe);
|
||||
+ if (!EQ (curRoot, lastRootWindow))
|
||||
+ {
|
||||
+ lastRootWindow = curRoot;
|
||||
+ accessibilityTreeValid = NO;
|
||||
+ }
|
||||
+
|
||||
+ /* If tree is stale, rebuild FIRST so we don't iterate freed
|
||||
+ window pointers. Skip notifications for this cycle — the
|
||||
+ freshly-built elements have no previous state to diff against. */
|
||||
+ if (!accessibilityTreeValid)
|
||||
+ {
|
||||
+ [self rebuildAccessibilityTree];
|
||||
+
|
||||
+ /* Post focus change so VoiceOver picks up the new tree. */
|
||||
+ id focused = [self accessibilityFocusedUIElement];
|
||||
+ if (focused && focused != self)
|
||||
+ NSAccessibilityPostNotification (focused,
|
||||
+ NSAccessibilityFocusedUIElementChangedNotification);
|
||||
+
|
||||
+ lastSelectedWindow = emacsframe->selected_window;
|
||||
+ accessibilityUpdating = NO;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Post per-buffer notifications using EXISTING elements that have
|
||||
+ cached state from the previous cycle. */
|
||||
+ cached state from the previous cycle. Validate each window
|
||||
+ pointer before use. */
|
||||
+ for (EmacsAccessibilityElement *elem in accessibilityElements)
|
||||
+ {
|
||||
+ if ([elem isKindOfClass:[EmacsAccessibilityBuffer class]])
|
||||
+ {
|
||||
+ struct window *w = elem.emacsWindow;
|
||||
+ if (w && WINDOW_LEAF_P (w))
|
||||
+ if (w && WINDOW_LEAF_P (w)
|
||||
+ && BUFFERP (w->contents) && XBUFFER (w->contents))
|
||||
+ [(EmacsAccessibilityBuffer *) elem
|
||||
+ postAccessibilityNotificationsForFrame:emacsframe];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Check for window switch (C-x o) before rebuild. */
|
||||
+ /* Check for window switch (C-x o). */
|
||||
+ Lisp_Object curSel = emacsframe->selected_window;
|
||||
+ BOOL windowSwitched = !EQ (curSel, lastSelectedWindow);
|
||||
+ if (windowSwitched)
|
||||
+ lastSelectedWindow = curSel;
|
||||
+
|
||||
+ /* Rebuild tree only if window configuration changed. */
|
||||
+ if (!accessibilityTreeValid)
|
||||
+ [self rebuildAccessibilityTree];
|
||||
+
|
||||
+ /* Post focus change AFTER rebuild so the new element exists. */
|
||||
+ if (windowSwitched)
|
||||
+ {
|
||||
+ lastSelectedWindow = curSel;
|
||||
+ id focused = [self accessibilityFocusedUIElement];
|
||||
+ if (focused && focused != self)
|
||||
+ NSAccessibilityPostNotification (focused,
|
||||
+ NSAccessibilityFocusedUIElementChangedNotification);
|
||||
+ }
|
||||
+
|
||||
+ accessibilityUpdating = NO;
|
||||
+}
|
||||
+
|
||||
+/* ---- Cursor position for Zoom (via accessibilityBoundsForRange:) ----
|
||||
@@ -1129,7 +1201,7 @@ index 932d209..6543e3b 100644
|
||||
@end /* EmacsView */
|
||||
|
||||
|
||||
@@ -9941,6 +10954,14 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
|
||||
@@ -9941,6 +11024,14 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user