patches: maintainer review fixes — thread safety, performance, safety
BLOCKER fixes: - @synchronized on visibleRuns/cachedText (AX thread data race) - Foverlays_in bulk query replaces O(n) per-char Foverlays_at loop WARNING fixes: - record_unwind_current_buffer in ns_ax_buffer_text - ns_ax_frame_for_range simplified (charpos params, no NSRange indirection) - NSTRACE added to 4 key accessibility functions - MAC_OS_X_VERSION_MIN_REQUIRED guard for UAZoom APIs - BUF_OVERLAY_MODIFF TODO in ensureTextCache
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
From a194f7d30770478d476720f86f39c9878aa63e79 Mon Sep 17 00:00:00 2001
|
From 900c20da8271f503ed3c224795a001dfca8b92f1 Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Sukany <martin@sukany.cz>
|
From: Martin Sukany <martin@sukany.cz>
|
||||||
Date: Fri, 27 Feb 2026 13:38:25 +0100
|
Date: Fri, 27 Feb 2026 14:29:32 +0100
|
||||||
Subject: [PATCH] ns: implement VoiceOver accessibility (AXBoundsForRange, line
|
Subject: [PATCH] ns: implement VoiceOver accessibility (AXBoundsForRange, line
|
||||||
nav, completions, interactive spans)
|
nav, completions, interactive spans)
|
||||||
|
|
||||||
@@ -14,25 +14,25 @@ links, completion candidates, and keymap overlays.
|
|||||||
(ns_ax_visible_run): Maps contiguous visible buffer ranges to AX string
|
(ns_ax_visible_run): Maps contiguous visible buffer ranges to AX string
|
||||||
indices, skipping invisible text.
|
indices, skipping invisible text.
|
||||||
|
|
||||||
* src/nsterm.m (ns_ax_buffer_text): Build accessibility string from
|
* src/nsterm.m (ns_ax_buffer_text): Build accessibility string with
|
||||||
buffer content, skipping text hidden via TEXT_PROP_MEANS_INVISIBLE.
|
record_unwind_current_buffer for exception safety.
|
||||||
(ns_ax_event_is_line_nav_key): Detect C-n/C-p/Tab/backtab for line
|
(ns_ax_event_is_line_nav_key): Detect C-n/C-p/Tab/backtab.
|
||||||
granularity forcing.
|
(ns_ax_scan_interactive_spans): Forward scan for interactive properties.
|
||||||
(ns_ax_scan_interactive_spans): Forward scan for interactive text
|
(ns_ax_find_completion_overlay_range): Fast 3-probe + Foverlays_in bulk
|
||||||
properties (widget, button, follow-link, org-link, completion, keymap).
|
fallback (no per-character scan).
|
||||||
(ns_ax_completion_string_from_prop): Handle completion--string as plain
|
(postAccessibilityUpdates): Re-entrance-guarded dispatcher with NSTRACE.
|
||||||
string or annotated cons list.
|
(postAccessibilityNotificationsForFrame:): Hybrid notification strategy.
|
||||||
(postAccessibilityUpdates): Re-entrance-guarded dispatcher called from
|
(invalidateTextCache, ensureTextCache): @synchronized for thread safety
|
||||||
ns_update_end; rebuilds AX tree on window layout changes.
|
of visibleRuns/cachedText accessed from AX server thread.
|
||||||
(postAccessibilityNotificationsForFrame:): Hybrid notification strategy:
|
(accessibilityIndexForCharpos:, charposForAccessibilityIndex:):
|
||||||
SelectedTextChanged for word/line/selection (VoiceOver reads correctly);
|
Thread-safe index mapping with @synchronized.
|
||||||
AnnouncementRequested for character moves (char AT point, correct for
|
(ns_draw_phys_cursor): UAZoomChangeFocus with MAC_OS_X_VERSION guard.
|
||||||
evil block-cursor mode). Non-focused buffer completion announcements
|
|
||||||
via 4-step fallback chain.
|
* etc/NEWS: New feature: VoiceOver accessibility on macOS.
|
||||||
---
|
---
|
||||||
src/nsterm.h | 108 ++
|
src/nsterm.h | 108 ++
|
||||||
src/nsterm.m | 2700 +++++++++++++++++++++++++++++++++++++++++++++++---
|
src/nsterm.m | 2727 +++++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
2 files changed, 2668 insertions(+), 140 deletions(-)
|
2 files changed, 2693 insertions(+), 142 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/nsterm.h b/src/nsterm.h
|
diff --git a/src/nsterm.h b/src/nsterm.h
|
||||||
index 7c1ee4c..6455547 100644
|
index 7c1ee4c..6455547 100644
|
||||||
@@ -168,7 +168,7 @@ index 7c1ee4c..6455547 100644
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/src/nsterm.m b/src/nsterm.m
|
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||||
index 932d209..5cd6ade 100644
|
index 932d209..248511b 100644
|
||||||
--- a/src/nsterm.m
|
--- a/src/nsterm.m
|
||||||
+++ b/src/nsterm.m
|
+++ b/src/nsterm.m
|
||||||
@@ -46,6 +46,7 @@ Updated by Christian Limpach (chris@nice.ch)
|
@@ -46,6 +46,7 @@ Updated by Christian Limpach (chris@nice.ch)
|
||||||
@@ -191,7 +191,7 @@ index 932d209..5cd6ade 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3232,6 +3238,37 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
@@ -3232,6 +3238,42 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
||||||
/* Prevent the cursor from being drawn outside the text area. */
|
/* Prevent the cursor from being drawn outside the text area. */
|
||||||
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
|
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
|
||||||
|
|
||||||
@@ -207,7 +207,11 @@ index 932d209..5cd6ade 100644
|
|||||||
+ view->lastAccessibilityCursorRect = r;
|
+ view->lastAccessibilityCursorRect = r;
|
||||||
+
|
+
|
||||||
+ /* Tell macOS Zoom where the cursor is. UAZoomChangeFocus()
|
+ /* Tell macOS Zoom where the cursor is. UAZoomChangeFocus()
|
||||||
+ expects top-left origin (CG coordinate space). */
|
+ expects top-left origin (CG coordinate space).
|
||||||
|
+ These APIs are available since macOS 10.4 (Universal Access
|
||||||
|
+ framework, linked via ApplicationServices umbrella). */
|
||||||
|
+#if defined (MAC_OS_X_VERSION_MIN_REQUIRED) \
|
||||||
|
+ && MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
|
||||||
+ if (UAZoomEnabled ())
|
+ if (UAZoomEnabled ())
|
||||||
+ {
|
+ {
|
||||||
+ NSRect windowRect = [view convertRect:r toView:nil];
|
+ NSRect windowRect = [view convertRect:r toView:nil];
|
||||||
@@ -222,6 +226,7 @@ index 932d209..5cd6ade 100644
|
|||||||
+ UAZoomChangeFocus (&cgRect, &cgRect,
|
+ UAZoomChangeFocus (&cgRect, &cgRect,
|
||||||
+ kUAZoomFocusTypeInsertionPoint);
|
+ kUAZoomFocusTypeInsertionPoint);
|
||||||
+ }
|
+ }
|
||||||
|
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 */
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+#endif
|
+#endif
|
||||||
@@ -229,7 +234,7 @@ index 932d209..5cd6ade 100644
|
|||||||
ns_focus (f, NULL, 0);
|
ns_focus (f, NULL, 0);
|
||||||
|
|
||||||
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||||
@@ -6849,207 +6886,2239 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg
|
@@ -6849,213 +6891,2263 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
|
|
||||||
@@ -306,7 +311,8 @@ index 932d209..5cd6ade 100644
|
|||||||
- EmacsLayer *layer = (EmacsLayer *)[self layer];
|
- EmacsLayer *layer = (EmacsLayer *)[self layer];
|
||||||
- [layer release];
|
- [layer release];
|
||||||
-#endif
|
-#endif
|
||||||
+ struct buffer *oldb = current_buffer;
|
+ specpdl_ref count = SPECPDL_INDEX ();
|
||||||
|
+ record_unwind_current_buffer ();
|
||||||
+ if (b != current_buffer)
|
+ if (b != current_buffer)
|
||||||
+ set_buffer_internal_1 (b);
|
+ set_buffer_internal_1 (b);
|
||||||
|
|
||||||
@@ -396,8 +402,7 @@ index 932d209..5cd6ade 100644
|
|||||||
+ }
|
+ }
|
||||||
|
|
||||||
- font_panel_result = (NSFont *) [sender convertFont: nsfont];
|
- font_panel_result = (NSFont *) [sender convertFont: nsfont];
|
||||||
+ if (b != oldb)
|
+ unbind_to (count, Qnil);
|
||||||
+ set_buffer_internal_1 (oldb);
|
|
||||||
|
|
||||||
- if (font_panel_result)
|
- if (font_panel_result)
|
||||||
- [font_panel_result retain];
|
- [font_panel_result retain];
|
||||||
@@ -450,7 +455,8 @@ index 932d209..5cd6ade 100644
|
|||||||
+
|
+
|
||||||
+static NSRect
|
+static NSRect
|
||||||
+ns_ax_frame_for_range (struct window *w, EmacsView *view,
|
+ns_ax_frame_for_range (struct window *w, EmacsView *view,
|
||||||
+ ptrdiff_t text_start, NSRange range)
|
+ ptrdiff_t charpos_start,
|
||||||
|
+ ptrdiff_t charpos_len)
|
||||||
{
|
{
|
||||||
- font_panel_active = NO;
|
- font_panel_active = NO;
|
||||||
+ if (!w || !w->current_matrix || !view)
|
+ if (!w || !w->current_matrix || !view)
|
||||||
@@ -458,9 +464,11 @@ index 932d209..5cd6ade 100644
|
|||||||
|
|
||||||
- /* If no font was previously selected, use the currently selected
|
- /* If no font was previously selected, use the currently selected
|
||||||
- font. */
|
- font. */
|
||||||
+ /* Convert range indices back to buffer charpos. */
|
+ /* charpos_start and charpos_len are already in buffer charpos
|
||||||
+ ptrdiff_t cp_start = text_start + (ptrdiff_t) range.location;
|
+ space — the caller maps AX string indices through
|
||||||
+ ptrdiff_t cp_end = cp_start + (ptrdiff_t) range.length;
|
+ charposForAccessibilityIndex which handles invisible text. */
|
||||||
|
+ ptrdiff_t cp_start = charpos_start;
|
||||||
|
+ ptrdiff_t cp_end = cp_start + charpos_len;
|
||||||
|
|
||||||
- if (!font_panel_result && FRAME_FONT (emacsframe))
|
- if (!font_panel_result && FRAME_FONT (emacsframe))
|
||||||
+ struct glyph_matrix *matrix = w->current_matrix;
|
+ struct glyph_matrix *matrix = w->current_matrix;
|
||||||
@@ -652,16 +660,18 @@ index 932d209..5cd6ade 100644
|
|||||||
- [fm orderFrontFontPanel: NSApp];
|
- [fm orderFrontFontPanel: NSApp];
|
||||||
+ if (!found)
|
+ if (!found)
|
||||||
+ {
|
+ {
|
||||||
+ for (ptrdiff_t scan = begv; scan < zv; scan++)
|
+ /* Bulk query: get all overlays in the buffer at once.
|
||||||
+ {
|
+ Avoids the previous O(n) per-character Foverlays_at loop. */
|
||||||
+ Lisp_Object overlays = Foverlays_at (make_fixnum (scan), Qnil);
|
+ Lisp_Object all = Foverlays_in (make_fixnum (begv),
|
||||||
|
+ make_fixnum (zv));
|
||||||
+ Lisp_Object tail;
|
+ Lisp_Object tail;
|
||||||
+ for (tail = overlays; CONSP (tail); tail = XCDR (tail))
|
+ for (tail = all; CONSP (tail); tail = XCDR (tail))
|
||||||
+ {
|
+ {
|
||||||
+ Lisp_Object ov = XCAR (tail);
|
+ Lisp_Object ov = XCAR (tail);
|
||||||
+ Lisp_Object face = Foverlay_get (ov, Qface);
|
+ Lisp_Object face = Foverlay_get (ov, Qface);
|
||||||
+ if (!(EQ (face, faceSym)
|
+ if (!(EQ (face, faceSym)
|
||||||
+ || (CONSP (face) && !NILP (Fmemq (faceSym, face)))))
|
+ || (CONSP (face)
|
||||||
|
+ && !NILP (Fmemq (faceSym, face)))))
|
||||||
+ continue;
|
+ continue;
|
||||||
+
|
+
|
||||||
+ ptrdiff_t ov_start = OVERLAY_START (ov);
|
+ ptrdiff_t ov_start = OVERLAY_START (ov);
|
||||||
@@ -675,9 +685,7 @@ index 932d209..5cd6ade 100644
|
|||||||
+ else if (point > ov_end)
|
+ else if (point > ov_end)
|
||||||
+ dist = point - ov_end;
|
+ dist = point - ov_end;
|
||||||
+
|
+
|
||||||
+ if (!found || dist < best_dist
|
+ if (!found || dist < best_dist)
|
||||||
+ || (dist == best_dist
|
|
||||||
+ && (ov_start < point && best_start >= point)))
|
|
||||||
+ {
|
+ {
|
||||||
+ best_start = ov_start;
|
+ best_start = ov_start;
|
||||||
+ best_end = ov_end;
|
+ best_end = ov_end;
|
||||||
@@ -686,7 +694,6 @@ index 932d209..5cd6ade 100644
|
|||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
|
||||||
|
|
||||||
- font_panel_active = YES;
|
- font_panel_active = YES;
|
||||||
- timeout = make_timespec (0, 100000000);
|
- timeout = make_timespec (0, 100000000);
|
||||||
@@ -874,11 +881,11 @@ index 932d209..5cd6ade 100644
|
|||||||
+ return [NSString stringWithLispString: he];
|
+ return [NSString stringWithLispString: he];
|
||||||
+
|
+
|
||||||
+ return @"";
|
+ return @"";
|
||||||
+}
|
}
|
||||||
+
|
|
||||||
+/* Scan visible range of window W for interactive spans.
|
+/* Scan visible range of window W for interactive spans.
|
||||||
+ Returns NSArray<EmacsAccessibilityInteractiveSpan *>.
|
+ Returns NSArray<EmacsAccessibilityInteractiveSpan *>.
|
||||||
+
|
|
||||||
+ Priority when properties overlap:
|
+ Priority when properties overlap:
|
||||||
+ widget > button > follow-link > org-link >
|
+ widget > button > follow-link > org-link >
|
||||||
+ completion-candidate > keymap-overlay. */
|
+ completion-candidate > keymap-overlay. */
|
||||||
@@ -888,7 +895,9 @@ index 932d209..5cd6ade 100644
|
|||||||
+{
|
+{
|
||||||
+ if (!w)
|
+ if (!w)
|
||||||
+ return @[];
|
+ return @[];
|
||||||
+
|
|
||||||
|
-/*****************************************************************************/
|
||||||
|
-/* Keyboard handling. */
|
||||||
+ Lisp_Object buf_obj = ns_ax_window_buffer_object (w);
|
+ Lisp_Object buf_obj = ns_ax_window_buffer_object (w);
|
||||||
+ if (NILP (buf_obj))
|
+ if (NILP (buf_obj))
|
||||||
+ return @[];
|
+ return @[];
|
||||||
@@ -1250,6 +1259,8 @@ index 932d209..5cd6ade 100644
|
|||||||
+
|
+
|
||||||
+- (void)invalidateTextCache
|
+- (void)invalidateTextCache
|
||||||
+{
|
+{
|
||||||
|
+ @synchronized (self)
|
||||||
|
+ {
|
||||||
+ [cachedText release];
|
+ [cachedText release];
|
||||||
+ cachedText = nil;
|
+ cachedText = nil;
|
||||||
+ if (visibleRuns)
|
+ if (visibleRuns)
|
||||||
@@ -1258,11 +1269,13 @@ index 932d209..5cd6ade 100644
|
|||||||
+ visibleRuns = NULL;
|
+ visibleRuns = NULL;
|
||||||
+ }
|
+ }
|
||||||
+ visibleRunCount = 0;
|
+ visibleRunCount = 0;
|
||||||
|
+ }
|
||||||
+ [self invalidateInteractiveSpans];
|
+ [self invalidateInteractiveSpans];
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+- (void)ensureTextCache
|
+- (void)ensureTextCache
|
||||||
+{
|
+{
|
||||||
|
+ NSTRACE ("EmacsAccessibilityBuffer ensureTextCache");
|
||||||
+ struct window *w = [self validWindow];
|
+ struct window *w = [self validWindow];
|
||||||
+ if (!w || !WINDOW_LEAF_P (w))
|
+ if (!w || !WINDOW_LEAF_P (w))
|
||||||
+ return;
|
+ return;
|
||||||
@@ -1274,6 +1287,10 @@ index 932d209..5cd6ade 100644
|
|||||||
+ ptrdiff_t modiff = BUF_MODIFF (b);
|
+ ptrdiff_t modiff = BUF_MODIFF (b);
|
||||||
+ ptrdiff_t pt = BUF_PT (b);
|
+ ptrdiff_t pt = BUF_PT (b);
|
||||||
+ NSUInteger textLen = cachedText ? [cachedText length] : 0;
|
+ NSUInteger textLen = cachedText ? [cachedText length] : 0;
|
||||||
|
+ /* TODO: Also track BUF_OVERLAY_MODIFF to catch overlay-only
|
||||||
|
+ changes (e.g., timer-based completion highlight move without
|
||||||
|
+ point change). Currently, overlay changes without text edits
|
||||||
|
+ are detected only when point also moves. */
|
||||||
+ if (cachedText && cachedTextModiff == modiff
|
+ if (cachedText && cachedTextModiff == modiff
|
||||||
+ && pt >= cachedTextStart
|
+ && pt >= cachedTextStart
|
||||||
+ && (textLen == 0
|
+ && (textLen == 0
|
||||||
@@ -1285,6 +1302,8 @@ index 932d209..5cd6ade 100644
|
|||||||
+ NSUInteger nruns = 0;
|
+ NSUInteger nruns = 0;
|
||||||
+ NSString *text = ns_ax_buffer_text (w, &start, &runs, &nruns);
|
+ NSString *text = ns_ax_buffer_text (w, &start, &runs, &nruns);
|
||||||
+
|
+
|
||||||
|
+ @synchronized (self)
|
||||||
|
+ {
|
||||||
+ [cachedText release];
|
+ [cachedText release];
|
||||||
+ cachedText = [text retain];
|
+ cachedText = [text retain];
|
||||||
+ cachedTextModiff = modiff;
|
+ cachedTextModiff = modiff;
|
||||||
@@ -1294,6 +1313,7 @@ index 932d209..5cd6ade 100644
|
|||||||
+ xfree (visibleRuns);
|
+ xfree (visibleRuns);
|
||||||
+ visibleRuns = runs;
|
+ visibleRuns = runs;
|
||||||
+ visibleRunCount = nruns;
|
+ visibleRunCount = nruns;
|
||||||
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* ---- Index mapping ---- */
|
+/* ---- Index mapping ---- */
|
||||||
@@ -1301,11 +1321,11 @@ index 932d209..5cd6ade 100644
|
|||||||
+/* Convert buffer charpos to accessibility string index. */
|
+/* Convert buffer charpos to accessibility string index. */
|
||||||
+- (NSUInteger)accessibilityIndexForCharpos:(ptrdiff_t)charpos
|
+- (NSUInteger)accessibilityIndexForCharpos:(ptrdiff_t)charpos
|
||||||
+{
|
+{
|
||||||
+ /* This method may be called from the AX server thread. All data
|
+ /* This method may be called from the AX server thread.
|
||||||
+ read here (visibleRuns, cachedText) is built on the main thread
|
+ Synchronize on self to prevent use-after-free if the main
|
||||||
+ inside ensureTextCache / ns_ax_buffer_text and is only invalidated
|
+ thread invalidates the text cache concurrently. */
|
||||||
+ on the main thread. No Lisp calls are made here. */
|
+ @synchronized (self)
|
||||||
+
|
+ {
|
||||||
+ for (NSUInteger i = 0; i < visibleRunCount; i++)
|
+ for (NSUInteger i = 0; i < visibleRunCount; i++)
|
||||||
+ {
|
+ {
|
||||||
+ ns_ax_visible_run *r = &visibleRuns[i];
|
+ ns_ax_visible_run *r = &visibleRuns[i];
|
||||||
@@ -1342,6 +1362,7 @@ index 932d209..5cd6ade 100644
|
|||||||
+ return last->ax_start + last->ax_length;
|
+ return last->ax_start + last->ax_length;
|
||||||
+ }
|
+ }
|
||||||
+ return 0;
|
+ return 0;
|
||||||
|
+ } /* @synchronized */
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* Convert accessibility string index to buffer charpos.
|
+/* Convert accessibility string index to buffer charpos.
|
||||||
@@ -1349,6 +1370,9 @@ index 932d209..5cd6ade 100644
|
|||||||
+ visibleRuns — no Lisp calls. */
|
+ visibleRuns — no Lisp calls. */
|
||||||
+- (ptrdiff_t)charposForAccessibilityIndex:(NSUInteger)ax_idx
|
+- (ptrdiff_t)charposForAccessibilityIndex:(NSUInteger)ax_idx
|
||||||
+{
|
+{
|
||||||
|
+ /* May be called from AX server thread — synchronize. */
|
||||||
|
+ @synchronized (self)
|
||||||
|
+ {
|
||||||
+ for (NSUInteger i = 0; i < visibleRunCount; i++)
|
+ for (NSUInteger i = 0; i < visibleRunCount; i++)
|
||||||
+ {
|
+ {
|
||||||
+ ns_ax_visible_run *r = &visibleRuns[i];
|
+ ns_ax_visible_run *r = &visibleRuns[i];
|
||||||
@@ -1379,6 +1403,7 @@ index 932d209..5cd6ade 100644
|
|||||||
+ return last->charpos + last->length;
|
+ return last->charpos + last->length;
|
||||||
+ }
|
+ }
|
||||||
+ return cachedTextStart;
|
+ return cachedTextStart;
|
||||||
|
+ } /* @synchronized */
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* ---- NSAccessibility protocol ---- */
|
+/* ---- NSAccessibility protocol ---- */
|
||||||
@@ -1746,8 +1771,8 @@ index 932d209..5cd6ade 100644
|
|||||||
+ ptrdiff_t cp_start = [self charposForAccessibilityIndex:range.location];
|
+ ptrdiff_t cp_start = [self charposForAccessibilityIndex:range.location];
|
||||||
+ ptrdiff_t cp_end = [self charposForAccessibilityIndex:
|
+ ptrdiff_t cp_end = [self charposForAccessibilityIndex:
|
||||||
+ range.location + range.length];
|
+ range.location + range.length];
|
||||||
+ NSRange charRange = NSMakeRange (0, (NSUInteger) (cp_end - cp_start));
|
+ return ns_ax_frame_for_range (w, view, cp_start,
|
||||||
+ return ns_ax_frame_for_range (w, view, cp_start, charRange);
|
+ cp_end - cp_start);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+- (NSRange)accessibilityRangeForPosition:(NSPoint)screenPoint
|
+- (NSRange)accessibilityRangeForPosition:(NSPoint)screenPoint
|
||||||
@@ -2606,10 +2631,16 @@ index 932d209..5cd6ade 100644
|
|||||||
+#endif
|
+#endif
|
||||||
+ [currentCursor setOnMouseEntered: YES];
|
+ [currentCursor setOnMouseEntered: YES];
|
||||||
+#endif
|
+#endif
|
||||||
}
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************/
|
||||||
|
+/* Keyboard handling. */
|
||||||
|
#define NS_KEYLOG 0
|
||||||
|
|
||||||
|
- (void)keyDown: (NSEvent *)theEvent
|
||||||
@@ -8237,6 +10306,31 @@ - (void)windowDidBecomeKey /* for direct calls */
|
@@ -8237,6 +10329,31 @@ - (void)windowDidBecomeKey /* for direct calls */
|
||||||
XSETFRAME (event.frame_or_window, emacsframe);
|
XSETFRAME (event.frame_or_window, emacsframe);
|
||||||
kbd_buffer_store_event (&event);
|
kbd_buffer_store_event (&event);
|
||||||
ns_send_appdefined (-1); // Kick main loop
|
ns_send_appdefined (-1); // Kick main loop
|
||||||
@@ -2641,7 +2672,7 @@ index 932d209..5cd6ade 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9474,6 +11568,320 @@ - (int) fullscreenState
|
@@ -9474,6 +11591,320 @@ - (int) fullscreenState
|
||||||
return fs_state;
|
return fs_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2962,7 +2993,7 @@ index 932d209..5cd6ade 100644
|
|||||||
@end /* EmacsView */
|
@end /* EmacsView */
|
||||||
|
|
||||||
|
|
||||||
@@ -11303,6 +13711,18 @@ Convert an X font name (XLFD) to an NS font name.
|
@@ -11303,6 +13734,18 @@ Convert an X font name (XLFD) to an NS font name.
|
||||||
DEFSYM (Qns_drag_operation_generic, "ns-drag-operation-generic");
|
DEFSYM (Qns_drag_operation_generic, "ns-drag-operation-generic");
|
||||||
DEFSYM (Qns_handle_drag_motion, "ns-handle-drag-motion");
|
DEFSYM (Qns_handle_drag_motion, "ns-handle-drag-motion");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user