This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
[macOS] Remove a single accessibility root assumption #40316
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,7 +58,7 @@ @implementation AccessibilityBridgeTestViewController | |
} | ||
} // namespace | ||
|
||
TEST(AccessibilityBridgeMacTest, sendsAccessibilityCreateNotificationToWindowOfFlutterView) { | ||
TEST(AccessibilityBridgeMacTest, SendsAccessibilityCreateNotificationToWindowOfFlutterView) { | ||
FlutterViewController* viewController = CreateTestViewController(); | ||
FlutterEngine* engine = viewController.engine; | ||
[viewController loadView]; | ||
|
@@ -112,7 +112,84 @@ @implementation AccessibilityBridgeTestViewController | |
[engine shutDownEngine]; | ||
} | ||
|
||
TEST(AccessibilityBridgeMacTest, doesNotSendAccessibilityCreateNotificationWhenHeadless) { | ||
// Flutter used to assume that the accessibility root had ID 0. | ||
// In a multi-view world, each view has its own accessibility root | ||
// with a globally unique node ID. | ||
// | ||
// node1 | ||
// | | ||
// node2 | ||
TEST(AccessibilityBridgeMacTest, NonZeroRootNodeId) { | ||
FlutterViewController* viewController = CreateTestViewController(); | ||
FlutterEngine* engine = viewController.engine; | ||
[viewController loadView]; | ||
|
||
NSWindow* expectedTarget = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600) | ||
styleMask:NSBorderlessWindowMask | ||
backing:NSBackingStoreBuffered | ||
defer:NO]; | ||
expectedTarget.contentView = viewController.view; | ||
// Setting up bridge so that the AccessibilityBridgeMacDelegateSpy | ||
// can query semantics information from. | ||
engine.semanticsEnabled = YES; | ||
auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>( | ||
viewController.accessibilityBridge.lock()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #40334 ... you saw nothing 🤫 |
||
|
||
FlutterSemanticsNode node1; | ||
std::vector<int32_t> node1_children{2}; | ||
node1.id = 1; | ||
node1.flags = static_cast<FlutterSemanticsFlag>(0); | ||
node1.actions = static_cast<FlutterSemanticsAction>(0); | ||
node1.text_selection_base = -1; | ||
node1.text_selection_extent = -1; | ||
node1.label = "node1"; | ||
node1.hint = ""; | ||
node1.value = ""; | ||
node1.increased_value = ""; | ||
node1.decreased_value = ""; | ||
node1.tooltip = ""; | ||
node1.child_count = node1_children.size(); | ||
node1.children_in_traversal_order = node1_children.data(); | ||
node1.children_in_hit_test_order = node1_children.data(); | ||
node1.custom_accessibility_actions_count = 0; | ||
|
||
FlutterSemanticsNode node2; | ||
node2.id = 2; | ||
node2.flags = static_cast<FlutterSemanticsFlag>(0); | ||
node2.actions = static_cast<FlutterSemanticsAction>(0); | ||
node2.text_selection_base = -1; | ||
node2.text_selection_extent = -1; | ||
node2.label = "node2"; | ||
node2.hint = ""; | ||
node2.value = ""; | ||
node2.increased_value = ""; | ||
node2.decreased_value = ""; | ||
node2.tooltip = ""; | ||
node2.child_count = 0; | ||
node2.custom_accessibility_actions_count = 0; | ||
|
||
bridge->AddFlutterSemanticsNodeUpdate(node1); | ||
bridge->AddFlutterSemanticsNodeUpdate(node2); | ||
bridge->CommitUpdates(); | ||
|
||
// Look up the root node delegate. | ||
auto root_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock(); | ||
ASSERT_TRUE(root_delegate); | ||
ASSERT_EQ(root_delegate->GetChildCount(), 1); | ||
|
||
// Look up the child node delegate. | ||
auto child_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock(); | ||
ASSERT_TRUE(child_delegate); | ||
ASSERT_EQ(child_delegate->GetChildCount(), 0); | ||
|
||
// Ensure a node with ID 0 does not exist. | ||
auto invalid_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); | ||
ASSERT_FALSE(invalid_delegate); | ||
|
||
[engine shutDownEngine]; | ||
} | ||
|
||
TEST(AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenHeadless) { | ||
FlutterViewController* viewController = CreateTestViewController(); | ||
FlutterEngine* engine = viewController.engine; | ||
[viewController loadView]; | ||
|
@@ -158,7 +235,7 @@ @implementation AccessibilityBridgeTestViewController | |
[engine shutDownEngine]; | ||
} | ||
|
||
TEST(AccessibilityBridgeMacTest, doesNotSendAccessibilityCreateNotificationWhenNoWindow) { | ||
TEST(AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenNoWindow) { | ||
FlutterViewController* viewController = CreateTestViewController(); | ||
FlutterEngine* engine = viewController.engine; | ||
[viewController loadView]; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chunhtai Do you know a widget that exercises this scenario? This scenario can only be reached by nodes with the
kEditable
state that don't have thekTextField
role.The logic to create
AXNode
s only gives thekEditable
state to semantic nodes with thekFlutterSemanticsFlagIsTextField
flag but not thekFlutterSemanticsFlagIsReadOnly
flag. However, such a semantics node would have thekTextField
role. In other words, it seems this code is unreachable. Please let me know if I misunderstood something.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there documentation in the
ax::mojo::State
enum for this role?The
ax::mojo::State
enum is defined as strictly powers of two? i.e. there's no statekFoo
that happens to bekBar | kEditable
I assume? Agreed that at first glance, it certainly looks like this is probably dead code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like these are defined as
enum class
so the answer appears to be that at least today, this is unused code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh just to make sure it's clear: semantic nodes have both
state
bit flags and arole
enum. These are separate :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is copied code from chromium, I don't think flutter have such widget that would run this code. We may in the future though, and we would need to update the common a11y_bridge to support that, but I am ok if we delete this code path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. I'll leave it in for now given we may have such a widget in the future.