Skip to content

Commit 4bd3c7e

Browse files
committed
Suppress blocked nodes from tree focus
1 parent 90832ea commit 4bd3c7e

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

flutter/shell/platform/common/accessibility_bridge.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,15 @@ void AccessibilityBridge::SetTooltipFromFlutterUpdate(
554554
void AccessibilityBridge::SetTreeData(const SemanticsNode& node,
555555
ui::AXTreeUpdate& tree_update) {
556556
const FlutterSemanticsFlags* flags = node.flags;
557+
const bool is_accessibility_focus_blocked =
558+
flags->is_accessibility_focus_blocked;
557559
// Set selection of the focused node if:
558560
// 1. this text field has a valid selection
559561
// 2. this text field doesn't have a valid selection but had selection stored
560562
// in the tree.
561563
if (flags->is_text_field &&
562-
flags->is_focused == FlutterTristate::kFlutterTristateTrue) {
564+
flags->is_focused == FlutterTristate::kFlutterTristateTrue &&
565+
!is_accessibility_focus_blocked) {
563566
if (node.text_selection_base != -1) {
564567
tree_update.tree_data.sel_anchor_object_id = node.id;
565568
tree_update.tree_data.sel_anchor_offset = node.text_selection_base;
@@ -573,13 +576,21 @@ void AccessibilityBridge::SetTreeData(const SemanticsNode& node,
573576
tree_update.tree_data.sel_focus_offset = -1;
574577
tree_update.has_tree_data = true;
575578
}
579+
} else if (tree_update.tree_data.sel_anchor_object_id == node.id) {
580+
tree_update.tree_data.sel_anchor_object_id = ui::AXNode::kInvalidAXID;
581+
tree_update.tree_data.sel_anchor_offset = -1;
582+
tree_update.tree_data.sel_focus_object_id = ui::AXNode::kInvalidAXID;
583+
tree_update.tree_data.sel_focus_offset = -1;
584+
tree_update.has_tree_data = true;
576585
}
577586

578-
if (flags->is_focused == FlutterTristate::kFlutterTristateTrue &&
587+
if (!is_accessibility_focus_blocked &&
588+
flags->is_focused == FlutterTristate::kFlutterTristateTrue &&
579589
tree_update.tree_data.focus_id != node.id) {
580590
tree_update.tree_data.focus_id = node.id;
581591
tree_update.has_tree_data = true;
582-
} else if (flags->is_focused != FlutterTristate::kFlutterTristateTrue &&
592+
} else if ((is_accessibility_focus_blocked ||
593+
flags->is_focused != FlutterTristate::kFlutterTristateTrue) &&
583594
tree_update.tree_data.focus_id == node.id) {
584595
tree_update.tree_data.focus_id = ui::AXNode::kInvalidAXID;
585596
tree_update.has_tree_data = true;

flutter/shell/platform/tizen/accessibility_bridge_unittests.cc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#include <algorithm>
6+
57
#include "flutter/shell/platform/common/test_accessibility_bridge.h"
68

79
#include "flutter/third_party/accessibility/ax/ax_action_data.h"
@@ -18,10 +20,11 @@ FlutterTransformation IdentityTransform() {
1820
};
1921
}
2022

21-
FlutterSemanticsFlags MakeFlags(bool blocked) {
23+
FlutterSemanticsFlags MakeFlags(bool blocked, bool focused = false) {
2224
FlutterSemanticsFlags flags = {};
2325
flags.struct_size = sizeof(FlutterSemanticsFlags);
2426
flags.is_accessibility_focus_blocked = blocked;
27+
flags.is_focused = focused ? kFlutterTristateTrue : kFlutterTristateFalse;
2528
return flags;
2629
}
2730

@@ -111,6 +114,32 @@ TEST(AccessibilityBridgeTest, BlockedNodeRejectsAccessibilityFocusAction) {
111114
EXPECT_EQ(bridge.GetLastFocusedId(), ui::AXNode::kInvalidAXID);
112115
}
113116

117+
TEST(AccessibilityBridgeTest, BlockedFocusedNodeDoesNotBecomeTreeFocus) {
118+
TestAccessibilityBridge bridge;
119+
auto flags = MakeFlags(true, true);
120+
auto node = MakeNode(1, &flags);
121+
122+
bridge.AddFlutterSemanticsNodeUpdate(node);
123+
bridge.CommitUpdates();
124+
125+
EXPECT_EQ(bridge.GetAXTreeData().focus_id, ui::AXNode::kInvalidAXID);
126+
EXPECT_EQ(std::find(bridge.accessibility_events.begin(),
127+
bridge.accessibility_events.end(),
128+
ui::AXEventGenerator::Event::FOCUS_CHANGED),
129+
bridge.accessibility_events.end());
130+
}
131+
132+
TEST(AccessibilityBridgeTest, UnblockedFocusedNodeBecomesTreeFocus) {
133+
TestAccessibilityBridge bridge;
134+
auto flags = MakeFlags(false, true);
135+
auto node = MakeNode(1, &flags);
136+
137+
bridge.AddFlutterSemanticsNodeUpdate(node);
138+
bridge.CommitUpdates();
139+
140+
EXPECT_EQ(bridge.GetAXTreeData().focus_id, node.id);
141+
}
142+
114143
TEST(AccessibilityBridgeTest, UnblockedNodeAcceptsAccessibilityFocusAction) {
115144
TestAccessibilityBridge bridge;
116145
auto flags = MakeFlags(false);

flutter/third_party/accessibility/ax/platform/ax_platform_node_auralinux.cc

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4358,9 +4358,6 @@ AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) {
43584358
}
43594359

43604360
bool AXPlatformNodeAuraLinux::GrabFocus() {
4361-
if (!GetData().HasState(ax::mojom::State::kFocusable))
4362-
return false;
4363-
43644361
AXActionData action_data;
43654362
action_data.action = ax::mojom::Action::kFocus;
43664363
return delegate_->AccessibilityPerformAction(action_data);
@@ -5064,17 +5061,13 @@ bool AXPlatformNodeAuraLinux::SetHighlighted(AtkObject* obj) {
50645061
return false;
50655062
}
50665063

5067-
if (!GetData().HasState(ax::mojom::State::kFocusable) || GetData().IsIgnored())
5068-
return false;
5069-
50705064
InvalidateHighlighted();
50715065

50725066
auto focused_obj = AXPlatformNodeAuraLinux::FromAtkObject(obj);
50735067

50745068
if (focused_obj) {
50755069
focused_obj->ScrollToNode(AXPlatformNodeBase::ScrollType::Anywhere);
5076-
if (!focused_obj->GrabFocus())
5077-
return false;
5070+
focused_obj->GrabFocus();
50785071
g_current_focused = obj;
50795072

50805073
atk_object_notify_state_change(g_current_focused, ATK_STATE_HIGHLIGHTED,

0 commit comments

Comments
 (0)