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.");
40 ax_platform_node_->Destroy();
44 NSCAssert(ax_platform_node_,
@"Platform node does not exist.");
45 return ax_platform_node_->GetNativeViewAccessible();
51 NSCAssert(view_controller_.viewLoaded,
@"Flutter view must be loaded");
52 return view_controller_.flutterView;
58 const ui::AXCoordinateSystem coordinate_system,
59 const ui::AXClippingBehavior clipping_behavior,
60 ui::AXOffscreenResult* offscreen_result)
const {
62 coordinate_system, clipping_behavior, offscreen_result);
63 gfx::RectF local_bounds_f(local_bounds);
64 gfx::RectF screen_bounds = ConvertBoundsFromLocalToScreen(local_bounds_f);
65 return gfx::ToEnclosingRect(ConvertBoundsFromScreenToGlobal(screen_bounds));
78 std::string text =
GetData().GetStringAttribute(ax::mojom::StringAttribute::kName);
82 auto bridge_ptr = bridge_.lock();
83 NSCAssert(bridge_ptr,
@"Accessibility bridge in flutter engine must not be null.");
84 for (int32_t child :
GetData().child_ids) {
85 auto delegate_child = bridge_ptr->GetFlutterPlatformNodeDelegateFromID(child).lock();
86 if (!delegate_child) {
89 text += std::static_pointer_cast<FlutterPlatformNodeDelegateMac>(delegate_child)
90 ->GetLiveRegionText();
95 gfx::RectF FlutterPlatformNodeDelegateMac::ConvertBoundsFromLocalToScreen(
96 const gfx::RectF& local_bounds)
const {
98 NSRect ns_local_bounds =
99 NSMakeRect(local_bounds.x(), local_bounds.y(), local_bounds.width(), local_bounds.height());
104 ns_local_bounds.origin.y = -ns_local_bounds.origin.y - ns_local_bounds.size.height;
106 NSCAssert(view_controller_.viewLoaded,
@"Flutter view must be loaded.");
107 NSRect ns_view_bounds = [view_controller_.flutterView convertRectFromBacking:ns_local_bounds];
108 NSRect ns_window_bounds = [view_controller_.flutterView convertRect:ns_view_bounds toView:nil];
109 NSRect ns_screen_bounds =
110 [[view_controller_.flutterView window] convertRectToScreen:ns_window_bounds];
111 gfx::RectF screen_bounds(ns_screen_bounds.origin.x, ns_screen_bounds.origin.y,
112 ns_screen_bounds.size.width, ns_screen_bounds.size.height);
113 return screen_bounds;
116 gfx::RectF FlutterPlatformNodeDelegateMac::ConvertBoundsFromScreenToGlobal(
117 const gfx::RectF& screen_bounds)
const {
120 NSScreen* screen = [[NSScreen screens] firstObject];
121 NSRect primary_screen_bounds = [screen frame];
123 float flipped_y = primary_screen_bounds.size.height - screen_bounds.y() - screen_bounds.height();
124 return {screen_bounds.x(), flipped_y, screen_bounds.width(), screen_bounds.height()};