diff --git a/shell/platform/windows/accessibility_bridge_windows.cc b/shell/platform/windows/accessibility_bridge_windows.cc index 5d90d03c33a96..3c8ee215b09e9 100644 --- a/shell/platform/windows/accessibility_bridge_windows.cc +++ b/shell/platform/windows/accessibility_bridge_windows.cc @@ -45,10 +45,8 @@ void AccessibilityBridgeWindows::OnAccessibilityEvent( // only for the focused node whose selection has changed. If a valid // caret and selection exist in the app tree, they must both be within // the focus node. - ui::AXNode::AXID focus_id = GetAXTreeData().sel_focus_object_id; - auto focus_delegate = - GetFlutterPlatformNodeDelegateFromID(focus_id).lock(); - if (!focus_delegate) { + auto focus_delegate = GetFocusedNode().lock(); + if (focus_delegate) { win_delegate = std::static_pointer_cast( focus_delegate); @@ -204,4 +202,10 @@ bool AccessibilityBridgeWindows::IsAXFragmentRootAControlElement() { return true; } +std::weak_ptr +AccessibilityBridgeWindows::GetFocusedNode() { + ui::AXNode::AXID focus_id = GetAXTreeData().sel_focus_object_id; + return GetFlutterPlatformNodeDelegateFromID(focus_id); +} + } // namespace flutter diff --git a/shell/platform/windows/accessibility_bridge_windows.h b/shell/platform/windows/accessibility_bridge_windows.h index 18660bcf605e7..efb2f8a47aac6 100644 --- a/shell/platform/windows/accessibility_bridge_windows.h +++ b/shell/platform/windows/accessibility_bridge_windows.h @@ -68,6 +68,9 @@ class AccessibilityBridgeWindows : public AccessibilityBridge, std::shared_ptr CreateFlutterPlatformNodeDelegate() override; + // Retrieve the focused node for accessibility events. + virtual std::weak_ptr GetFocusedNode(); + private: FlutterWindowsView* view_; diff --git a/shell/platform/windows/accessibility_bridge_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_windows_unittests.cc index 92cfcc7ff8975..a07f52d5c4f25 100644 --- a/shell/platform/windows/accessibility_bridge_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_windows_unittests.cc @@ -50,7 +50,7 @@ class AccessibilityBridgeWindowsSpy : public AccessibilityBridgeWindows { void SetFocus(std::shared_ptr node_delegate) override { - focused_nodes_.push_back(node_delegate->GetAXNode()->id()); + focused_nodes_.push_back(std::move(node_delegate)); } void ResetRecords() { @@ -62,11 +62,24 @@ class AccessibilityBridgeWindowsSpy : public AccessibilityBridgeWindows { return dispatched_events_; } - const std::vector focused_nodes() const { return focused_nodes_; } + const std::vector focused_nodes() const { + std::vector ids; + std::transform(focused_nodes_.begin(), focused_nodes_.end(), + std::back_inserter(ids), + [](std::shared_ptr node) { + return node->GetAXNode()->id(); + }); + return ids; + } + + protected: + std::weak_ptr GetFocusedNode() override { + return focused_nodes_.back(); + } private: std::vector dispatched_events_; - std::vector focused_nodes_; + std::vector> focused_nodes_; FML_DISALLOW_COPY_AND_ASSIGN(AccessibilityBridgeWindowsSpy); }; @@ -189,6 +202,32 @@ void ExpectWinEventFromAXEvent(int32_t node_id, EXPECT_EQ(bridge->dispatched_events()[0].event_type, expected_event); } +void ExpectWinEventFromAXEventOnFocusNode(int32_t node_id, + ui::AXEventGenerator::Event ax_event, + ax::mojom::Event expected_event, + int32_t focus_id) { + auto window_binding_handler = + std::make_unique<::testing::NiceMock>(); + FlutterWindowsViewSpy view(std::move(window_binding_handler)); + view.SetEngine(GetTestEngine()); + view.OnUpdateSemanticsEnabled(true); + + auto bridge = GetAccessibilityBridgeSpy(view.GetEngine()); + PopulateAXTree(bridge); + + bridge->ResetRecords(); + auto focus_delegate = + bridge->GetFlutterPlatformNodeDelegateFromID(focus_id).lock(); + bridge->SetFocus(std::static_pointer_cast( + focus_delegate)); + bridge->OnAccessibilityEvent({AXNodeFromID(bridge, node_id), + {ax_event, ax::mojom::EventFrom::kNone, {}}}); + ASSERT_EQ(bridge->dispatched_events().size(), 1); + EXPECT_EQ(bridge->dispatched_events()[0].event_type, expected_event); + EXPECT_EQ(bridge->dispatched_events()[0].node_delegate->GetAXNode()->id(), + focus_id); +} + } // namespace TEST(AccessibilityBridgeWindows, GetParent) { @@ -342,9 +381,9 @@ TEST(AccessibilityBridgeWindows, OnAccessibilityStateChanged) { } TEST(AccessibilityBridgeWindows, OnDocumentSelectionChanged) { - ExpectWinEventFromAXEvent( + ExpectWinEventFromAXEventOnFocusNode( 1, ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED, - ax::mojom::Event::kDocumentSelectionChanged); + ax::mojom::Event::kDocumentSelectionChanged, 2); } } // namespace testing