v7 patch: fix Zoom snapping to old window on C-x o
Guard accessibility notifications with on_p && active_p so they only fire when drawing the cursor in the selected window. Without this, ns_draw_window_cursor is called for both old and new windows during redisplay, and UAZoomChangeFocus fires for the old window last.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
From: Martin Sukany <martin@sukany.cz>
|
||||
Date: Tue, 25 Feb 2026 19:20:00 +0100
|
||||
Date: Tue, 25 Feb 2026 20:10:00 +0100
|
||||
Subject: [PATCH] ns: implement macOS Zoom cursor tracking and VoiceOver
|
||||
support via UAZoomChangeFocus + NSAccessibility
|
||||
|
||||
@@ -19,12 +19,10 @@ Add cursor tracking and screen reader support for macOS accessibility:
|
||||
movement), FocusedUIElementChanged (window focus).
|
||||
Ref: https://developer.apple.com/documentation/appkit/nsaccessibilityprotocol
|
||||
|
||||
accessibilityFrame returns the view's frame (standard behavior) so
|
||||
VoiceOver draws its focus ring around the text area. Cursor position
|
||||
is exposed via accessibilityBoundsForRange: only.
|
||||
|
||||
Both mechanisms are needed: UAZoomChangeFocus serves Zoom; NSAccessibility
|
||||
serves VoiceOver. Same dual pattern used by iTerm2.
|
||||
Accessibility notifications are only posted when drawing the cursor in
|
||||
the active (selected) window (on_p && active_p guard). Without this,
|
||||
C-x o (other-window) triggers UAZoomChangeFocus for the old window
|
||||
last, snapping Zoom back to it.
|
||||
---
|
||||
diff --git a/src/nsterm.h b/src/nsterm.h
|
||||
index 7c1ee4c..6c1ff34 100644
|
||||
@@ -41,10 +39,10 @@ index 7c1ee4c..6c1ff34 100644
|
||||
|
||||
/* AppKit-side interface. */
|
||||
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||
index 932d209..2576c96 100644
|
||||
index 932d209..e6b1699 100644
|
||||
--- a/src/nsterm.m
|
||||
+++ b/src/nsterm.m
|
||||
@@ -3232,6 +3232,72 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
||||
@@ -3232,6 +3232,77 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
||||
/* Prevent the cursor from being drawn outside the text area. */
|
||||
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
|
||||
|
||||
@@ -75,7 +73,12 @@ index 932d209..2576c96 100644
|
||||
+ serves macOS Zoom's "Follow keyboard focus" feature. */
|
||||
+ {
|
||||
+ EmacsView *view = FRAME_NS_VIEW (f);
|
||||
+ if (view)
|
||||
+ /* Only notify AT when drawing the cursor in the active
|
||||
+ (selected) window. ns_draw_window_cursor is called for
|
||||
+ all windows during redisplay (to draw or erase cursors);
|
||||
+ without this guard, C-x o triggers UAZoomChangeFocus for
|
||||
+ the old window last, snapping Zoom back to it. */
|
||||
+ if (view && on_p && active_p)
|
||||
+ {
|
||||
+ /* Store cursor rect for accessibilityBoundsForRange: queries. */
|
||||
+ view->lastAccessibilityCursorRect = r;
|
||||
@@ -117,7 +120,7 @@ index 932d209..2576c96 100644
|
||||
ns_focus (f, NULL, 0);
|
||||
|
||||
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||
@@ -8237,6 +8303,15 @@ - (void)windowDidBecomeKey /* for direct calls */
|
||||
@@ -8237,6 +8308,15 @@ - (void)windowDidBecomeKey /* for direct calls */
|
||||
XSETFRAME (event.frame_or_window, emacsframe);
|
||||
kbd_buffer_store_event (&event);
|
||||
ns_send_appdefined (-1); // Kick main loop
|
||||
@@ -133,7 +136,7 @@ index 932d209..2576c96 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -9474,6 +9549,310 @@ - (int) fullscreenState
|
||||
@@ -9474,6 +9554,310 @@ - (int) fullscreenState
|
||||
return fs_state;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user