5#import "flutter/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMac.h"
7#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
8#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h"
9#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObject.h"
10#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
11#include "flutter/shell/platform/embedder/embedder.h"
25 : flutter_engine_(flutter_engine), view_controller_(view_controller) {}
29 if (!view_controller_.viewLoaded || !view_controller_.
view.window) {
34 std::vector<AccessibilityBridgeMac::NSAccessibilityEvent> events =
36 for (
const AccessibilityBridgeMac::NSAccessibilityEvent&
event : events) {
37 if (
event.user_info != nil) {
38 DispatchMacOSNotificationWithUserInfo(
event.target,
event.name,
event.user_info);
45std::vector<AccessibilityBridgeMac::NSAccessibilityEvent>
49 NSCAssert(flutter_engine_,
@"Flutter engine should not be deallocated");
51 NSCAssert(platform_node_delegate,
@"Event target must exist in accessibility bridge.");
52 auto mac_platform_node_delegate =
53 std::static_pointer_cast<FlutterPlatformNodeDelegateMac>(platform_node_delegate);
56 std::vector<AccessibilityBridgeMac::NSAccessibilityEvent> events;
61 .name = NSAccessibilitySelectedRowsChangedNotification,
62 .target = native_node,
70 .name = NSAccessibilitySelectedChildrenChangedNotification,
71 .target = native_node,
82 .target = native_node,
89 .target = native_node,
96 .name = NSAccessibilitySelectedRowsChangedNotification,
97 .target = native_node,
104 NSAccessibilityElement* native_accessibility_node = (NSAccessibilityElement*)native_node;
105 if (native_accessibility_node.accessibilityFocusedUIElement &&
114 .name = NSAccessibilitySelectedChildrenChangedNotification,
115 .target = native_node,
121 id focused = mac_platform_node_delegate->GetFocus();
127 if (native_text_field == mac_platform_node_delegate->GetFocus()) {
128 [native_text_field startEditing];
134 .name = NSAccessibilitySelectedTextChangedNotification,
135 .target = native_node,
150 .name = NSAccessibilitySelectedTextChangedNotification,
151 .target = focus_node->GetNativeViewAccessible(),
158 .name = NSAccessibilityValueChangedNotification,
159 .target = native_node,
170 id focused = mac_platform_node_delegate->GetFocus();
171 if (!focused || native_text_field == focused) {
172 [native_text_field startEditing];
177 .name = NSAccessibilityValueChangedNotification,
178 .target = native_node,
183 .name = NSAccessibilityValueChangedNotification,
193 .target = native_node,
200 .target = native_node,
205 auto live_region_events =
207 events.insert(events.end(), live_region_events.begin(), live_region_events.end());
214 .target = native_node,
221 .name = NSAccessibilityRowCountChangedNotification,
222 .target = native_node,
227 NSAccessibilityNotificationName mac_notification;
230 mac_notification = NSAccessibilityRowExpandedNotification;
235 .name = mac_notification,
236 .target = native_node,
242 NSAccessibilityNotificationName mac_notification;
245 mac_notification = NSAccessibilityRowCollapsedNotification;
250 .name = mac_notification,
251 .target = native_node,
259 .target = native_node,
267 .name = NSAccessibilityCreatedNotification,
268 .target = view_controller_.
view.window,
335 NSCAssert(flutter_engine_,
@"Flutter engine should not be deallocated");
336 NSCAssert(view_controller_.viewLoaded && view_controller_.
view.window,
337 @"The accessibility bridge should not receive accessibility actions if the flutter view"
338 @"is not loaded or attached to a NSWindow.");
339 [flutter_engine_ dispatchSemanticsAction:
action toTarget:
target withData:std::move(
data)];
342std::shared_ptr<FlutterPlatformNodeDelegate>
344 return std::make_shared<FlutterPlatformNodeDelegateMac>(weak_from_this(), view_controller_);
350 NSAccessibilityNotificationName mac_notification) {
351 NSCAssert(mac_notification,
@"The notification must not be null.");
352 NSCAssert(native_node,
@"The notification target must not be null.");
353 NSAccessibilityPostNotification(native_node, mac_notification);
356void AccessibilityBridgeMac::DispatchMacOSNotificationWithUserInfo(
358 NSAccessibilityNotificationName mac_notification,
359 NSDictionary* user_info) {
360 NSCAssert(mac_notification,
@"The notification must not be null.");
361 NSCAssert(native_node,
@"The notification target must not be null.");
362 NSCAssert(user_info,
@"The notification data must not be null.");
363 NSAccessibilityPostNotificationWithUserInfo(native_node, mac_notification, user_info);
367 NSCAssert(flutter_engine_,
@"Flutter engine should not be deallocated");
368 std::vector<ui::AXEventGenerator::TargetedEvent> pending_events =
GetPendingEvents();
370 if (pending_event.event_params.event ==
event) {
ax::mojom::Event event_type
AccessibilityBridgeMac(__weak FlutterEngine *flutter_engine, __weak FlutterViewController *view_controller)
Creates an AccessibilityBridgeMacDelegate.
void OnAccessibilityEvent(ui::AXEventGenerator::TargetedEvent targeted_event) override
Handle accessibility events generated due to accessibility tree changes. These events are needed to b...
std::shared_ptr< FlutterPlatformNodeDelegate > CreateFlutterPlatformNodeDelegate() override
Creates a platform specific FlutterPlatformNodeDelegate. Ownership passes to the caller....
virtual void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, NSAccessibilityNotificationName mac_notification)
Posts the given event against the given node to the macOS accessibility notification system.
void DispatchAccessibilityAction(AccessibilityNodeId target, FlutterSemanticsAction action, fml::MallocMapping data) override
Dispatch accessibility action back to the Flutter framework. These actions are generated in the nativ...
ui::AXPlatformNodeDelegate * RootDelegate() const override
std::weak_ptr< FlutterPlatformNodeDelegate > GetFlutterPlatformNodeDelegateFromID(AccessibilityNodeId id) const
Get the flutter platform node delegate with the given id from this accessibility bridge....
const ui::AXTreeData & GetAXTreeData() const
Get the ax tree data from this accessibility bridge. The tree data contains information such as the i...
const std::vector< ui::AXEventGenerator::TargetedEvent > GetPendingEvents() const
Gets all pending accessibility events generated during semantics updates. This is useful when decidin...
FlutterView * view() const
A Mapping like NonOwnedMapping, but uses Free as its release proc.
@ LIVE_REGION_NODE_CHANGED
@ ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED
@ DOCUMENT_SELECTION_CHANGED
@ OBJECT_ATTRIBUTE_CHANGED
@ SCROLL_HORIZONTAL_POSITION_CHANGED
@ POSITION_IN_SET_CHANGED
@ IMAGE_ANNOTATION_CHANGED
@ WIN_IACCESSIBLE_STATE_CHANGED
@ MULTILINE_STATE_CHANGED
@ OTHER_ATTRIBUTE_CHANGED
@ MULTISELECTABLE_STATE_CHANGED
@ SCROLL_VERTICAL_POSITION_CHANGED
@ HIERARCHICAL_LEVEL_CHANGED
@ ACTIVE_DESCENDANT_CHANGED
@ SELECTED_CHILDREN_CHANGED
static constexpr AXID kInvalidAXID
const AXNodeData & data() const
static NSString *const kAccessibilityLoadCompleteNotification
static NSString *const kAccessibilityExpandedChanged
static NSString *const kAccessibilityMenuItemSelectedNotification
static NSString *const kAccessibilityLiveRegionChangedNotification
static NSString *const kAccessibilityInvalidStatusChangedNotification
static NSString *const kAccessibilityLiveRegionCreatedNotification
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
UnimplementedNativeViewAccessible * NativeViewAccessible
bool IsTableLike(const ax::mojom::Role role)
const EventParams & event_params
bool HasState(ax::mojom::State state) const
AXNode::AXID sel_anchor_object_id