Skip to content

Commit

Permalink
Accessibility: emit FOCUS_CHANGED events (flutter#30091)
Browse files Browse the repository at this point in the history
When calling Unserialize on an AXTreeUpdate, check whether the focus_id
has changed. If so, emit a FOCUS_CHANGED event from the event generator.
This allows the platform-specific FlutterPlatformNodeDelegate
implementations to handle focus changes originating from the framework,
and trigger the appropriate operating system focus-changed
notifications.

Issue: flutter/flutter#77838
  • Loading branch information
cbracken authored Dec 3, 2021
1 parent c80c8eb commit f196035
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
6 changes: 6 additions & 0 deletions third_party/accessibility/ax/ax_event_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,12 @@ void AXEventGenerator::OnTreeDataChanged(AXTree* tree,
}
if (new_tree_data.title != old_tree_data.title)
AddEvent(tree->root(), Event::DOCUMENT_TITLE_CHANGED);
if (new_tree_data.focus_id != old_tree_data.focus_id) {
AXNode* focus_node = tree->GetFromId(new_tree_data.focus_id);
if (focus_node) {
AddEvent(focus_node, Event::FOCUS_CHANGED);
}
}
}

void AXEventGenerator::OnNodeWillBeDeleted(AXTree* tree, AXNode* node) {
Expand Down
42 changes: 42 additions & 0 deletions third_party/accessibility/ax/ax_event_generator_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,48 @@ TEST(AXEventGeneratorTest, DocumentTitleChanged) {
AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED, 1));
}

// Do not emit a FOCUS_CHANGED event if focus_id is unchanged.
TEST(AXEventGeneratorTest, FocusIdUnchanged) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(2);
initial_state.nodes[0].id = 1;
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[1].id = 2;
initial_state.has_tree_data = true;
initial_state.tree_data.focus_id = 1;
AXTree tree(initial_state);

AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.tree_data.focus_id = 1;

ASSERT_TRUE(tree.Unserialize(update));
EXPECT_FALSE(
HasEvent(event_generator, AXEventGenerator::Event::FOCUS_CHANGED, 1));
}

// Emit a FOCUS_CHANGED event if focus_id changes.
TEST(AXEventGeneratorTest, FocusIdChanged) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(2);
initial_state.nodes[0].id = 1;
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[1].id = 2;
initial_state.has_tree_data = true;
initial_state.tree_data.focus_id = 1;
AXTree tree(initial_state);

AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.tree_data.focus_id = 2;

ASSERT_TRUE(tree.Unserialize(update));
EXPECT_TRUE(
HasEvent(event_generator, AXEventGenerator::Event::FOCUS_CHANGED, 2));
}

TEST(AXEventGeneratorTest, ExpandedAndRowCount) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
Expand Down

0 comments on commit f196035

Please sign in to comment.