Skip to content

Conversation

@yjbanov
Copy link
Contributor

@yjbanov yjbanov commented Apr 4, 2018

  • Remove global sorting that's not supported by iOS. Instead it sorts locally using a new algorithm illustrated here.
  • RTL
  • Remove nextNodeId/previousNodeId

Fixes #12187
Fixes #14375
Fixes #14570 (together with flutter/engine#4937)

TODO:

  • remove traces of geometric sort order (e.g. the enum option)
  • pass hit test order so it can be applied on Android (iOS doesn't support it; this requires an engine-side change)

/cc @goderbauer @gspencergoog

@yjbanov yjbanov changed the title a11y traversal: sort locally; use new sorting algorithm [WIP] a11y traversal: sort locally; use new sorting algorithm Apr 5, 2018
Copy link
Member

@goderbauer goderbauer left a 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.geometricOrder option and instead replace it with a DebugSemanticsDumpOrder.traversalOrder option 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...

Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. Added.

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

@goderbauer goderbauer Apr 10, 2018

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>?

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. 👍

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@yjbanov yjbanov force-pushed the submit-traversal-order branch from 959c026 to ac6651c Compare April 18, 2018 21:04
Copy link
Member

@goderbauer goderbauer left a 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?

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. #16835

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Reverted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this file?

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. 👍

Copy link
Member

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?

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yjbanov yjbanov force-pushed the submit-traversal-order branch from 6068931 to c19f8ed Compare April 20, 2018 22:59
@yjbanov
Copy link
Contributor Author

yjbanov commented Apr 21, 2018

For some reason GitHub is not letting me respond to some of the comments, so responding here:

isCompatibleWithPreviousSortKey && sortNodes.isNotEmpty

I don't know where the appropriate place is, but it feels like we should document this somewhere.

This is documented in SemanticsSortKey:

/// 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.

Can you update what's left to do in the PR description? I believe it's remove geometric sort order and add hit testing?

Done.

@yjbanov yjbanov force-pushed the submit-traversal-order branch from afc9903 to 6fd77f4 Compare April 21, 2018 00:41
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yjbanov yjbanov changed the title [WIP] a11y traversal: sort locally; use new sorting algorithm a11y traversal: sort locally; use new sorting algorithm Apr 23, 2018
@yjbanov yjbanov merged commit d354096 into flutter:master Apr 23, 2018
DaveShuckerow pushed a commit to DaveShuckerow/flutter that referenced this pull request May 14, 2018
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
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

3 participants