From bc7eb02db7bb8b2ad312eaf49b29b85616674956 Mon Sep 17 00:00:00 2001 From: Adam Demasi Date: Fri, 10 Apr 2026 01:19:18 +1000 Subject: [PATCH] Announce changes to live regions on macOS (#21045) * Announce changes to live regions on macOS It is necessary to manually request announcement of the new name of a live region, alongside posting the general kAXLiveRegionChangedNotification. * Refactor -raisePropertyChanged: to use switch statement * Fix warning about switch not covering all cases --------- Co-authored-by: Julien Lebosquain --- native/Avalonia.Native/src/OSX/automation.mm | 32 +++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/native/Avalonia.Native/src/OSX/automation.mm b/native/Avalonia.Native/src/OSX/automation.mm index 412e7ddc5f..78552f716e 100644 --- a/native/Avalonia.Native/src/OSX/automation.mm +++ b/native/Avalonia.Native/src/OSX/automation.mm @@ -130,7 +130,7 @@ case AutomationExpander: return NSAccessibilityDisclosureTriangleRole; // Treat unknown roles as generic group container items. Returning // NSAccessibilityUnknownRole is also possible but makes the screen - // reader focus on the item instead of passing focus to child items. + // reader focus on the item instead of passing focus to child items. default: return NSAccessibilityGroupRole; } } @@ -191,6 +191,7 @@ { switch (_peer->GetLiveSetting()) { + case LiveSettingOff: return nil; case LiveSettingPolite: return @"polite"; case LiveSettingAssertive: return @"assertive"; } @@ -519,6 +520,35 @@ - (void)raiseLiveRegionChanged { NSAccessibilityPostNotification(self, @"AXLiveRegionChanged" /* kAXLiveRegionChangedNotification */); + + // Announce the new string + auto name = _peer->GetName(); + if (name != nullptr) + { + NSAccessibilityPriorityLevel priority = NSAccessibilityPriorityLow; + switch (_peer->GetLiveSetting()) + { + case LiveSettingOff: + return; + case LiveSettingPolite: + priority = NSAccessibilityPriorityMedium; + break; + case LiveSettingAssertive: + priority = NSAccessibilityPriorityHigh; + break; + } + + NSDictionary *userInfo = @{ + NSAccessibilityAnnouncementKey: GetNSStringAndRelease(name), + NSAccessibilityPriorityKey: @(priority) + }; + + id topLevel = [self accessibilityTopLevelUIElement]; + if ([topLevel isKindOfClass:[AvnWindow class]]) + { + NSAccessibilityPostNotificationWithUserInfo(topLevel, NSAccessibilityAnnouncementRequestedNotification, userInfo); + } + } } - (void)setAccessibilityFocused:(BOOL)accessibilityFocused