Skip to content

Commit c997fab

Browse files
JSUYAclaude
andcommitted
Support accessibility focus blocking for blocked semantics nodes
When a Flutter widget sets accessibilityFocusBlockType to blockNode, mark the node as kIgnored so its ATK object is not created, making it invisible to the AT-SPI tree and unreachable by the screen reader. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3a3fba3 commit c997fab

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

flutter/shell/platform/common/accessibility_bridge.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ void AccessibilityBridge::SetStateFromFlutterUpdate(ui::AXNodeData& node_data,
377377
(actions & kHasScrollingAction) == 0 && node.value.empty() &&
378378
node.label.empty() && node.hint.empty()) {
379379
node_data.AddState(ax::mojom::State::kIgnored);
380+
} else if (flags->is_accessibility_focus_blocked) {
381+
node_data.AddState(ax::mojom::State::kIgnored);
380382
} else {
381383
// kFlutterSemanticsFlagIsFocusable means a keyboard focusable, it is
382384
// different from semantics focusable.

flutter/shell/platform/common/flutter_platform_node_delegate.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,13 @@ const ui::AXNodeData& FlutterPlatformNodeDelegate::GetData() const {
6262
}
6363

6464
gfx::NativeViewAccessible FlutterPlatformNodeDelegate::GetParent() {
65-
if (!ax_node_->parent()) {
65+
auto* unignored_parent = ax_node_->GetUnignoredParent();
66+
if (!unignored_parent) {
6667
return nullptr;
6768
}
6869
auto bridge_ptr = bridge_.lock();
6970
BASE_DCHECK(bridge_ptr);
70-
return bridge_ptr->GetNativeAccessibleFromId(ax_node_->parent()->id());
71+
return bridge_ptr->GetNativeAccessibleFromId(unignored_parent->id());
7172
}
7273

7374
gfx::NativeViewAccessible FlutterPlatformNodeDelegate::GetFocus() {

flutter/shell/platform/tizen/flutter_platform_node_delegate_tizen.cc

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,29 @@ FlutterPlatformNodeDelegateTizen::~FlutterPlatformNodeDelegateTizen() {
2424
void FlutterPlatformNodeDelegateTizen::Init(std::weak_ptr<OwnerBridge> bridge,
2525
ui::AXNode* node) {
2626
FlutterPlatformNodeDelegate::Init(bridge, node);
27-
platform_node_ = ui::AXPlatformNode::Create(this);
28-
FT_LOG(Debug) << "Create platform node for AXNode "
29-
<< node->data().ToString();
27+
if (!node->data().IsIgnored()) {
28+
platform_node_ = ui::AXPlatformNode::Create(this);
29+
FT_LOG(Debug) << "Create platform node for AXNode "
30+
<< node->data().ToString();
31+
}
32+
}
33+
34+
void FlutterPlatformNodeDelegateTizen::NodeDataChanged(
35+
const ui::AXNodeData& old_node_data,
36+
const ui::AXNodeData& new_node_data) {
37+
const bool was_ignored = old_node_data.IsIgnored();
38+
const bool is_ignored = new_node_data.IsIgnored();
39+
40+
if (was_ignored && !is_ignored) {
41+
if (!platform_node_) {
42+
platform_node_ = ui::AXPlatformNode::Create(this);
43+
}
44+
} else if (!was_ignored && is_ignored) {
45+
if (platform_node_) {
46+
platform_node_->Destroy();
47+
platform_node_ = nullptr;
48+
}
49+
}
3050
}
3151

3252
void FlutterPlatformNodeDelegateTizen::NotifyAccessibilityEvent(

flutter/shell/platform/tizen/flutter_platform_node_delegate_tizen.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class FlutterPlatformNodeDelegateTizen : public FlutterPlatformNodeDelegate {
3939
// |FlutterPlatformNodeDelegate|
4040
void Init(std::weak_ptr<OwnerBridge> bridge, ui::AXNode* node) override;
4141

42+
// |FlutterPlatformNodeDelegate|
43+
void NodeDataChanged(const ui::AXNodeData& old_node_data,
44+
const ui::AXNodeData& new_node_data) override;
45+
4246
private:
4347
ui::AXPlatformNode* platform_node_;
4448
};

0 commit comments

Comments
 (0)