-
Notifications
You must be signed in to change notification settings - Fork 29.7k
a11y traversal: sort locally; use new sorting algorithm #16253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
goderbauer
left a comment
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.
Some high level comments:
- We should remove the useless
DebugSemanticsDumpOrder.geometricOrderoption and instead replace it with aDebugSemanticsDumpOrder.traversalOrderoption that allows you to print the semantics tree in, well, traversal order. - I am still a little afraid of the complexity of this algorithm. I know, this should be mostly mitigated by the fact that n will be small, but still...
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.
Why the indirection via _MonthPickerSortKey? I think I'd find this easier to read/understand if it would just say sortKey: const OrdinalSortKey(1.0) right here.
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.
In general keys are grouped by type, so using plain OrdinalSortKey would cause these nodes to be sorted together with potentially unrelated nodes that roll up under the same parent. That's probably not going to happen in the current implementation of the picker.
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.
I assume the previousNodeId/nextNodeId here get removed in a follow-up PR? Maybe remove the "// Should be x" comments for now as these just seem more confusing now?
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.
nit: these lists were easier to read when there was one entry per line as before.
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.
I used generateTestSemanticsExpressionForCurrentSemanticsTree to update this test. I'll fix that method in a separate change when the dust settles.
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.
Does the sort key still have to be its own data type? Why do we not simplify this to be just a double now?
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.
A double value is undocumentable, so it's unclear what it means to have your nodes sorted together with nodes authored by someone else. The numbers would look magical in the source code. But if the sort keys are provided by one author then they can define and use a custom type.
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.
Position as determined by default sort order?
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.
True. Added.
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.
bonus points: would be great to link to the graphic from you slides here.
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.
Done.
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.
to avoid all this mapping, can search not operate on semanticsnodes and sortedIds be a List<SemanticNode>?
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.
It uses the position in the list as a tie breaker to guarantee that the sorting is stable. So for now I think this is the most idiomatic method. I also measured the efficiency of the entire algorithm across many of the Flutter Gallery screens. It never exceeded 100µs on Moto G4. This is not surprising as the SemanticsNode tree is very sparse compared to the RenderNode tree.
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.
do we have to do all this work to bring nodes, that specify a sort key, into default sort order only to re-sort them then according to their sort key?
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.
Unfortunately, this test still doesn't verify that the traversal order is defined correctly -- and I believe we currently have no way of asserting traversal order in a widget test like this because at this point the SemanticNodes have not been sorted yet?
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.
It does now. After fad0555 hasSemantics tests traversal order by default.
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.
Perfect. 👍
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.
Again, we need to find a way to assert that things are in the correct traversal order in a test.
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.
Done.
959c026 to
ac6651c
Compare
goderbauer
left a comment
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 looks good!
Can you update what's left to do in the PR description? I believe it's remove geometric sort order and add hit testing?
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.
Directionality is not enough to set the semantic textDirection? Might be worth filing an issue about this.
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.
Done. #16835
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 this change intentional?
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.
Oops. Reverted.
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.
Nice!
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.
Thanks!
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.
Love all these test cases. Should we add some test cases that use artificial sort keys?
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.
We have them. They just live in one of the semantics_#_test.dart files. We should revise this at some point. It's hard to tell what each of those files is testing.
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.
revert this file?
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.
Oops, pulled in my experiments. Fixed.
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.
Should this be traversalOrder by default?
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.
It is now. Thanks for the suggestiong.
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.
Perfect. 👍
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 this required for every App? Should it be part of MaterialApp? What changes if I don't specify a top level textDirection for semantics?
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.
I guess it reverts to paint order?
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.
Reverting for now. Let's address this in #16835.
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.
Why call _childrenInDefaultOrder twice in this case?
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.
My bad, the first one is unnecessary.
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.
I don't know where the appropriate place is, but it feels like we should document this somewhere.
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.
Can you add a test that verifies correct traversal order for app bar with a leading icon (e.g. hamburger menu), a title, and a trailing icon (e.g. three dots menu)? That's the traversal order we got most called out for in a11y reviews. Will be good to ensure with tests to keep it correct.
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.
Done.
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.
6068931 to
c19f8ed
Compare
|
For some reason GitHub is not letting me respond to some of the comments, so responding here:
This is documented in /// If subclasses of this class compare themselves to another subclass of
/// [SemanticsSortKey], they will compare as "equal" so that keys of the same
/// type are ordered only with respect to one another.I'm not sure this wording is accurate enough though, as it assumes a specific sorting algorithm. I'll try to think of a better wording.
Done. |
afc9903 to
6fd77f4
Compare
goderbauer
left a comment
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.
LGTM
New a11y traversal: - sort direct sibling SemanticsNodes only - use new sorting algorithm - implement RTL - test semantics in traversal order by default - add AppBar traversal test - breaking: remove nextNodeId/previousNodeId from the framework - breaking: remove DebugSemanticsDumpOrder.geometricOrder
nextNodeId/previousNodeIdFixes #12187
Fixes #14375
Fixes #14570 (together with flutter/engine#4937)
TODO:
/cc @goderbauer @gspencergoog