13 #include "flutter/third_party/accessibility/ax/ax_action_data.h"
14 #include "flutter/third_party/accessibility/ax/ax_node_position.h"
15 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node.h"
16 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_base.h"
17 #include "flutter/third_party/accessibility/base/string_utils.h"
18 #include "flutter/third_party/accessibility/gfx/geometry/rect_conversions.h"
19 #include "flutter/third_party/accessibility/gfx/mac/coordinate_conversion.h"
24 std::weak_ptr<AccessibilityBridge> bridge,
26 : bridge_(std::move(bridge)), view_controller_(view_controller) {}
33 ax_platform_node_ = ui::AXPlatformNode::Create(
this);
35 NSCAssert(ax_platform_node_,
@"Failed to create platform node.");
39 const ui::AXNodeData& new_node_data) {
40 if (old_node_data.IsTextField() && !new_node_data.IsTextField()) {
41 ax_platform_node_->Destroy();
42 ax_platform_node_ = ui::AXPlatformNode::Create(
this);
43 }
else if (!old_node_data.IsTextField() && new_node_data.IsTextField()) {
44 ax_platform_node_->Destroy();
51 ax_platform_node_->Destroy();
55 NSCAssert(ax_platform_node_,
@"Platform node does not exist.");
56 return ax_platform_node_->GetNativeViewAccessible();
62 NSCAssert(view_controller_.viewLoaded,
@"Flutter view must be loaded");
63 return view_controller_.flutterView;
69 const ui::AXCoordinateSystem coordinate_system,
70 const ui::AXClippingBehavior clipping_behavior,
71 ui::AXOffscreenResult* offscreen_result)
const {
73 coordinate_system, clipping_behavior, offscreen_result);
74 gfx::RectF local_bounds_f(local_bounds);
75 gfx::RectF screen_bounds = ConvertBoundsFromLocalToScreen(local_bounds_f);
76 return gfx::ToEnclosingRect(ConvertBoundsFromScreenToGlobal(screen_bounds));
89 std::string text =
GetData().GetStringAttribute(ax::mojom::StringAttribute::kName);
93 auto bridge_ptr = bridge_.lock();
94 NSCAssert(bridge_ptr,
@"Accessibility bridge in flutter engine must not be null.");
95 for (int32_t child :
GetData().child_ids) {
96 auto delegate_child = bridge_ptr->GetFlutterPlatformNodeDelegateFromID(child).lock();
97 if (!delegate_child) {
100 text += std::static_pointer_cast<FlutterPlatformNodeDelegateMac>(delegate_child)
101 ->GetLiveRegionText();
106 gfx::RectF FlutterPlatformNodeDelegateMac::ConvertBoundsFromLocalToScreen(
107 const gfx::RectF& local_bounds)
const {
109 NSRect ns_local_bounds =
110 NSMakeRect(local_bounds.x(), local_bounds.y(), local_bounds.width(), local_bounds.height());
115 ns_local_bounds.origin.y = -ns_local_bounds.origin.y - ns_local_bounds.size.height;
117 NSCAssert(view_controller_.viewLoaded,
@"Flutter view must be loaded.");
118 NSRect ns_view_bounds = [view_controller_.flutterView convertRectFromBacking:ns_local_bounds];
119 NSRect ns_window_bounds = [view_controller_.flutterView convertRect:ns_view_bounds toView:nil];
120 NSRect ns_screen_bounds =
121 [[view_controller_.flutterView window] convertRectToScreen:ns_window_bounds];
122 gfx::RectF screen_bounds(ns_screen_bounds.origin.x, ns_screen_bounds.origin.y,
123 ns_screen_bounds.size.width, ns_screen_bounds.size.height);
124 return screen_bounds;
127 gfx::RectF FlutterPlatformNodeDelegateMac::ConvertBoundsFromScreenToGlobal(
128 const gfx::RectF& screen_bounds)
const {
131 NSScreen* screen = [[NSScreen screens] firstObject];
132 NSRect primary_screen_bounds = [screen frame];
134 float flipped_y = primary_screen_bounds.size.height - screen_bounds.y() - screen_bounds.height();
135 return {screen_bounds.x(), flipped_y, screen_bounds.width(), screen_bounds.height()};