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>
|
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
|
Subject: [PATCH] ns: implement macOS Zoom cursor tracking and VoiceOver
|
||||||
support via UAZoomChangeFocus + NSAccessibility
|
support via UAZoomChangeFocus + NSAccessibility
|
||||||
|
|
||||||
@@ -19,12 +19,10 @@ Add cursor tracking and screen reader support for macOS accessibility:
|
|||||||
movement), FocusedUIElementChanged (window focus).
|
movement), FocusedUIElementChanged (window focus).
|
||||||
Ref: https://developer.apple.com/documentation/appkit/nsaccessibilityprotocol
|
Ref: https://developer.apple.com/documentation/appkit/nsaccessibilityprotocol
|
||||||
|
|
||||||
accessibilityFrame returns the view's frame (standard behavior) so
|
Accessibility notifications are only posted when drawing the cursor in
|
||||||
VoiceOver draws its focus ring around the text area. Cursor position
|
the active (selected) window (on_p && active_p guard). Without this,
|
||||||
is exposed via accessibilityBoundsForRange: only.
|
C-x o (other-window) triggers UAZoomChangeFocus for the old window
|
||||||
|
last, snapping Zoom back to it.
|
||||||
Both mechanisms are needed: UAZoomChangeFocus serves Zoom; NSAccessibility
|
|
||||||
serves VoiceOver. Same dual pattern used by iTerm2.
|
|
||||||
---
|
---
|
||||||
diff --git a/src/nsterm.h b/src/nsterm.h
|
diff --git a/src/nsterm.h b/src/nsterm.h
|
||||||
index 7c1ee4c..6c1ff34 100644
|
index 7c1ee4c..6c1ff34 100644
|
||||||
@@ -41,10 +39,10 @@ index 7c1ee4c..6c1ff34 100644
|
|||||||
|
|
||||||
/* AppKit-side interface. */
|
/* AppKit-side interface. */
|
||||||
diff --git a/src/nsterm.m b/src/nsterm.m
|
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||||
index 932d209..2576c96 100644
|
index 932d209..e6b1699 100644
|
||||||
--- a/src/nsterm.m
|
--- a/src/nsterm.m
|
||||||
+++ b/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. */
|
/* 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));
|
||||||
|
|
||||||
@@ -75,7 +73,12 @@ index 932d209..2576c96 100644
|
|||||||
+ serves macOS Zoom's "Follow keyboard focus" feature. */
|
+ serves macOS Zoom's "Follow keyboard focus" feature. */
|
||||||
+ {
|
+ {
|
||||||
+ EmacsView *view = FRAME_NS_VIEW (f);
|
+ 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. */
|
+ /* Store cursor rect for accessibilityBoundsForRange: queries. */
|
||||||
+ view->lastAccessibilityCursorRect = r;
|
+ view->lastAccessibilityCursorRect = r;
|
||||||
@@ -117,7 +120,7 @@ index 932d209..2576c96 100644
|
|||||||
ns_focus (f, NULL, 0);
|
ns_focus (f, NULL, 0);
|
||||||
|
|
||||||
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
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);
|
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
|
||||||
@@ -133,7 +136,7 @@ index 932d209..2576c96 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9474,6 +9549,310 @@ - (int) fullscreenState
|
@@ -9474,6 +9554,310 @@ - (int) fullscreenState
|
||||||
return fs_state;
|
return fs_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user