Status Update
Comments
so...@google.com <so...@google.com>
yi...@google.com <yi...@google.com> #2
Branch: androidx-main
commit 755b3f1f06c682b37c39b7bf3b80bccb638b642d
Author: Nader Jawad <njawad@google.com>
Date: Mon Feb 12 23:43:23 2024
GraphicsLayer API Part 4/N
Relnote: "Update Compose framework to expose a
GraphicsContext composition local alongside
updating Owner, DelegateableNode and drawWithCache
Modifier implementations to expose access to the
GraphicsContext for scoped access that will automatically
cleanup GraphicsLayer instances when Modifiers are torn
down."
Bug: 288494724
Test: Ran AndroidGraphicsLayerTest
Change-Id: I64a2f6a2e156f9305fe32ac2a6f9be2b61f7f0ed
M compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
M compose/ui/ui-unit/api/current.txt
M compose/ui/ui-unit/api/restricted_current.txt
M compose/ui/ui-unit/src/androidUnitTest/kotlin/androidx/compose/ui/unit/IntSizeTest.kt
M compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntSize.kt
M compose/ui/ui/api/current.txt
M compose/ui/ui/api/restricted_current.txt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/draw/DrawModifierTest.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/Helpers.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/node/NodeChainTester.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
M compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
M compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerScope.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatableNode.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt
M compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
am...@twitter.com <am...@twitter.com> #3
Branch: androidx-main
commit 88951ea1f54623398ffdac8a24e35db3fbfeeb8a
Author: Nader Jawad <njawad@google.com>
Date: Mon Feb 12 22:54:56 2024
GraphicsLayer API Part 3/N
Relnote: "Introduce GraphicsContext function constructor
to create a factory to create GraphicsLayer instances"
Created GraphicsLayerV29 as the RenderNode backed
GraphicsLayer for Android
Bug: 288494724
Test: Added AndroidGraphicsLayerTest
Change-Id: Ib98d6b140fab3d857f74faa4fa227927e1625bed
M compose/ui/ui-graphics/api/current.txt
M compose/ui/ui-graphics/api/restricted_current.txt
A compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV29.android.kt
so...@google.com <so...@google.com> #4
Branch: androidx-main
commit 25e6f1b21e6136f816097bd0b7e395d81cbaaaa6
Author: Nader Jawad <njawad@google.com>
Date: Tue Mar 05 14:16:52 2024
GraphicsLayer API Part 5/N
Introduce LayerManager as an internal
mechanism for persisting of GraphicsLayer
displaylists by invoking a placeholder render
with empty content within the layer in order
to increment the internal ref count of RenderNode
instances within HWUI.
Bug: 288494724
Test: Ran AndroidGraphicsLayerTest
Change-Id: I52203a1bca59ea024cb7dfa665994a7ccc573756
M compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/LayerManager.android.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/draw/DrawModifierTest.kt
fa...@gmail.com <fa...@gmail.com> #5
Branch: androidx-main
commit 55240af3dcdb65f46679c8840f9b6148034bc7e0
Author: Nader Jawad <njawad@google.com>
Date: Mon Feb 12 22:13:31 2024
GraphicsLayer API Part 2/N
Relnote: "Exposed GraphicsLayer API
to provide developer defined flexibility
in capturing drawing commands that can be
used to draw elsewhere and also apply
different visual effects to the end result."
Introduced AndroidGraphicsLayer actual
implementation with interface definition
to abstract away differences between different
Android API levels.
Added placeholder Desktop GraphicsLayer implementation
to be completed in a subsequent CL.
Bug: 288494724
Test: Added with Android GraphicsLayer implementation
Change-Id: I802452c9375fc6949ed85fb65d77173456893907
M compose/ui/ui-graphics/api/current.txt
M compose/ui/ui-graphics/api/restricted_current.txt
A compose/ui/ui-graphics/samples/src/main/java/androidx/compose/ui/graphics/samples/GraphicsLayerSamples.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
M compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsContext.kt
M compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
A compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/layer/CompositingStrategy.kt
M compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt
A compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.desktop.kt
yi...@google.com <yi...@google.com> #6
Branch: androidx-main
commit e32ca4769a50717045b75f9cd7bb1436fe48a751
Author: Nader Jawad <njawad@google.com>
Date: Mon Feb 12 21:44:06 2024
GraphicsLayer API Part 1/N
Relnote: "Added GraphicsLayer expect/actual
API defintion to support capturing and replaying
of drawing commands with optional compositing
visual effects and transforms.
Introduce GraphicsContext interface to contain
graphics dependencies including creation and
management of GraphicsLayer instances.
"
Bug: 288494724
Test: Added with expect/actual implementation
Change-Id: I4a8d67d7b45798d5e8afa78402168d14512e4318
A compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsContext.kt
A compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt
fa...@gmail.com <fa...@gmail.com> #7
Branch: androidx-main
commit 1e39396a77297efa4a5a2e4d49e49b7e86b44593
Author: Nader Jawad <njawad@google.com>
Date: Mon Feb 12 23:09:08 2024
GraphicsLayer API Part 6/N
Added Android GraphicsLayer implementation for
Android API level 23+ leveraging RenderNode stubs
Updated ViewCapture.android.kt to remove the API
level requirement for capturing View content to a
bitmap for testing scenarios
Bug: 288494724
Test: Ran AndroidGraphicsLayerTest on Android API 23
Change-Id: I8013c73b7d115b49bacb5ecdb67c731094262580
M compose/ui/ui-graphics/build.gradle
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV23.android.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/draw/DrawModifierTest.kt
fa...@gmail.com <fa...@gmail.com> #8
Branch: androidx-main
commit f8340787db926919283189376e67e0ea8247b214
Author: Nader Jawad <njawad@google.com>
Date: Mon Feb 12 23:23:04 2024
GraphicsLayer API Part 7/N
Added View backed GraphicsLayer implementation
for Android L/P and as a fallback for Android devices
that do not support the RenderNode stub approach.
Updated AndroidGraphicsContext to return View backed
graphics layers.
Moved resource identifier for Views used as layers
to the ui-graphics module.
Relnote: "Introduced HardwareCanvas stub for
Android L usage"
Bug: 288494724
Test: Ran AndroidGraphicsLayerTest on Android L
Change-Id: I1c3b5821c20f51b9c8ae96f81c822174583251b7
M compose/material/material-ripple/build.gradle
M compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/RippleContainer.android.kt
M compose/ui/ui-android-stubs/api/current.txt
M compose/ui/ui-android-stubs/api/restricted_current.txt
A compose/ui/ui-android-stubs/src/main/java/android/view/HardwareCanvas.java
M compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/view/PlaceholderHardwareCanvas.android.kt
A compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/view/ViewLayerContainer.android.kt
A compose/ui/ui-graphics/src/androidMain/res/values/ids.xml
M compose/ui/ui-inspection/build.gradle
M compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/compose/AndroidComposeViewWrapper.kt
M compose/ui/ui-tooling/build.gradle
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/draw/DrawModifierTest.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayerContainer.android.kt
M compose/ui/ui/src/androidMain/res/values/ids.xml
am...@twitter.com <am...@twitter.com> #9
Branch: androidx-main
commit 49d0d5cb25a6b493e0c20dee322e377519d9da5f
Author: Nader Jawad <njawad@google.com>
Date: Tue Feb 13 12:23:39 2024
GraphicsLayer API Part 8/N
Introduce Compose Desktop GraphicsLayer
implementation
Bug: 288494724
Test: Added DesktopGraphicsLayerTest
Change-Id: I05f5190e8118ccbd2c26e260e6f6ae2f20f013db
M compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
M compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.desktop.kt
A compose/ui/ui-graphics/src/desktopTest/kotlin/androidx/compose/ui/graphics/layer/DesktopGraphicsLayerTest.kt
M compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
yi...@google.com <yi...@google.com> #10
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.material:material-ripple:1.7.0-alpha05
androidx.compose.material:material-ripple-android:1.7.0-alpha05
androidx.compose.material:material-ripple-desktop:1.7.0-alpha05
androidx.compose.ui:ui:1.7.0-alpha05
androidx.compose.ui:ui-android:1.7.0-alpha05
androidx.compose.ui:ui-android-stubs:1.7.0-alpha05
androidx.compose.ui:ui-desktop:1.7.0-alpha05
androidx.compose.ui:ui-graphics:1.7.0-alpha05
androidx.compose.ui:ui-graphics-android:1.7.0-alpha05
androidx.compose.ui:ui-graphics-desktop:1.7.0-alpha05
androidx.compose.ui:ui-tooling:1.7.0-alpha05
androidx.compose.ui:ui-tooling-android:1.7.0-alpha05
androidx.compose.ui:ui-tooling-desktop:1.7.0-alpha05
androidx.compose.ui:ui-unit:1.7.0-alpha05
androidx.compose.ui:ui-unit-android:1.7.0-alpha05
androidx.compose.ui:ui-unit-desktop:1.7.0-alpha05
ae...@google.com <ae...@google.com> #11
The implementation of placeAt
in the linked CL on line 118, the overloaded method call does not seem to do anything with the passed in GraphicsLayer
:
protected open fun placeAt(
position: IntOffset,
zIndex: Float,
layer: GraphicsLayer
) {
placeAt(position, zIndex, null)
}
When I tested on the latest snapshot, passing in a GraphicsLayer
was a no-op. I'm not sure if this is a bug, or it is supposed to be addressed in a follow up CL.
fa...@gmail.com <fa...@gmail.com> #13
Branch: androidx-main
commit 6bb3dd89bf83fc4d6f2825effb2f0fc613c94774
Author: Nader Jawad <njawad@google.com>
Date: Wed Mar 27 18:43:56 2024
Update GraphicsLayer API based on Compose Design
Review feedback
Relnote: "Rename GraphicsLayer#buildLayer to
record to mirror the begin/endRecording methods of
Displaylist backed APIs like RenderNode and Picture.
Updated rememberGraphicsLayer to leverage rememberObserver."
Bug: 288494724
Fixes: 330758155
Test: re-ran compose tests
Change-Id: I312c1120358d04fccfe8a646001a883017fb0fb3
M compose/ui/ui-graphics/api/current.txt
M compose/ui/ui-graphics/api/restricted_current.txt
M compose/ui/ui-graphics/samples/src/main/java/androidx/compose/ui/graphics/samples/GraphicsLayerSamples.kt
M compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidGraphicsContext.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV23.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayerV29.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt
M compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/LayerSnapshot.android.kt
M compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
M compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.kt
M compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsLayer.desktop.kt
M compose/ui/ui-graphics/src/desktopTest/kotlin/androidx/compose/ui/graphics/layer/DesktopGraphicsLayerTest.kt
M compose/ui/ui/api/current.txt
M compose/ui/ui/api/restricted_current.txt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/draw/DrawModifierTest.kt
M compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/draw/DrawingPrebuiltGraphicsLayerTest.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/GraphicsLayerOwnerLayer.android.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerScope.kt
M compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/draw/DesktopDrawingPrebuiltGraphicsLayerTest.kt
yi...@google.com <yi...@google.com> #14
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.ui:ui:1.7.0-alpha07
androidx.compose.ui:ui-android:1.7.0-alpha07
androidx.compose.ui:ui-desktop:1.7.0-alpha07
androidx.compose.ui:ui-graphics:1.7.0-alpha07
androidx.compose.ui:ui-graphics-android:1.7.0-alpha07
androidx.compose.ui:ui-graphics-desktop:1.7.0-alpha07
yi...@google.com <yi...@google.com> #15
he...@ataulm.com <he...@ataulm.com> #16
"allow navigation between fixed components on screen like the app bar and fab " seems to be a feature which should implemented in talkback.
Agree.
I think it's important to distinguish between properly describing the UI and correct TalkBack behavior.
Agree.
My suggestion was that it should be possible to describe the nature of components like FABs and other app chrome like appbars by being able to mark them as chrome, similar to how it's possible to mark arbitrary views as headings. This needs to be implemented in compose and/or the view system since this is what the app developer has access to.
It adds metadata about these components that accessibility services can then use (which is separate). TalkBack could add it as a navigation type like headings, paragraphs, words etc. which allows the user to jump between layers. TalkBack could use it in the autoscroll case that Phill mentioned too (iterate through app chrome before autoscroll - though it does sound annoying, maybe it could be an opt-out setting). Switch access could incorporate it too, since it has the same issue.
cb...@google.com <cb...@google.com> #17
Headings allow this somewhat, but only if there are no headings in the list.
Panes also allow jumping out of the list, with more flexibility, now that we have next-window actions.
The best option seems to be generalized containers with enter/exit actions & gestures.
> components like FABs and other app chrome like appbars by being able to mark them as chrome,
I like this idea, because it provides high-level information that gives talkback flexibility to apply various navigation policies. But it does not necessarily solve the infinite-list problems since chrome may not exist before/after the list.
> order by sortPriority then by ordering left-to-right, top-to-bottom.
This sounds functionally equivalent to traverse-before/after, though somewhat easier to use.
pb...@google.com <pb...@google.com> #18
Hey, so we are working on App Widgets, and one of the layout we are working with is this:
There are five locations for buttons, and iterating through them should probably be from more important to less important, meaning the center first, and then around in a circle, starting probably from top-left, although this might depend on whether the UI is LTR or RTL and on the exact application.
yi...@google.com <yi...@google.com>
pw...@google.com <pw...@google.com> #19
fa...@gmail.com <fa...@gmail.com> #20
Being able to influence the reading order by importance is really useful to offer a good user experience to blind user.
ro...@gmail.com <ro...@gmail.com> #21
lo...@gmail.com <lo...@gmail.com> #22
Blocked by a private issue 😪
da...@omadahealth.com <da...@omadahealth.com> #23
Building rich experience for vision impaired users aren't easy, but I think we should embrace that fact and give more tools and education for the devs, so when we are building complex things, we have all the tools in our disposal.
al...@dayforce.com <al...@dayforce.com> #24
Agree with #23. It would be ideal to have the tools and implement them on a case-by-case for some of our more complex components. I don't believe anyone wants to make inconsistent behaviour for end-users but getting to that consistent behaviour should be available to us if the default implementation can't reach it in this case. It's problematic for us when our expected traversal order in design (which may be set by accessibility analysts) doesn't meet our actual implementation and sometimes the design/implementation refactor costs are high.
While not on compose, there's been issues in the past with traversal where even with refactors we couldn't get an expected result leading to difficult decisions, which is not ideal for end-users.
Let us take responsibility for meeting the compliance, consistency, and accessibility of our own implementation.
ae...@google.com <ae...@google.com> #25
Thanks for the feedback. What I would find helpful to make progress here is to hear the concrete cases you're running into where the default order deviates from the one your a11y analysts recommend. Feel free to file those as separate bugs under the following component:
Then, case by case, we could: 1) suggest a technical workaround to make the order conform without redesigning your app, 2) fix our implementation so that the default order conforms to what you want, or 3) acknowledge that it is technically impossible right now and block those bugs on this feature request. If we wind up accumulating a critical mass of case 3), that would justify putting this on our roadmap, as well as making sure that it supports all the motivating use cases.
al...@gmail.com <al...@gmail.com> #26
Here is an example:
I have a list item (see screenshot) where there is Text, Detail Text, and Meta text. I want these to be announced in that same order.
However, talkback announces the order by default like "Text, Meta text, Detail text".
I believe this is because my layout is like this:
Column {
Row {
Text()
MetaText()
}
DetailText()
}
So I think the only way I could workaround this is by creating a custom layout that places the composables in the same order that they should be read out loud in talkback. But this isn't very convenient.
pw...@google.com <pw...@google.com>
va...@google.com <va...@google.com> #27
Another use case:
In short, there is a topBar
in a Scaffold
that is being placed in the same location as the content
slot (and the content is given the space that the top bar occupies as padding values via subcomposition)
Since topBar
and content
are placed at the same location, the logic in SemanticsSort
eventually choose the content
first, since it is a taller element:
That is unexpected, however, since the topBar
will visually be the top-most element. There doesn't appear to be any way currently to affect this ordering, other than by changing where the topBar
and content
are placed.
The same issue is also currently affecting the M3 Scaffold
for the same reason.
ae...@google.com <ae...@google.com> #28
Indeed, so far, more than half the focus-traversal problem cases I've heard involve a top bar. We'll see what we can do to improve that particular use case.
ap...@google.com <ap...@google.com> #29
Branch: androidx-main
commit 58ef0380e0f989b7532babbff23bcef0d3ba64b6
Author: Melba Nuzen <mnuzen@google.com>
Date: Thu Oct 27 16:35:09 2022
Internal change from using SemanticsSort to 'setTraversal'
This change is meant to be pre-work for a larger refactoring of focus order in Compose and shouldn’t introduce any changes in A11y behavior.
Issues seen in
This patch is just meant to check that we can use `setTraversalBefore` to determine our own custom order for semantics nodes (overriding the existing hierarchies). `setTraversalValues` in `AndroidComposeViewAccessibilityDelegateCompat` should order semantics nodes in the same way `SemanticsSort` did, except by setting the `traversalBefore` value for each node that will be read by TalkBack.
This ordering is set in a mapping when semantic nodes are first retrieved. Then when a nodeInfo is created, the code now looks up our custom traversal order and uses `setTraversalBefore` on that ANI. That way, when TalkBack goes through the ANI tree, it’ll use the `traversalBefore` parameter and traverse in the way that we want regardless, of parent/child hierarchies.
Bug: 186443263
Test: compose/ui/AndroidAccessibilityTest/testCreateAccessibilityNodeInfo_forTraversalOrder
Change-Id: I339010bea62afb359e63d6e63889acff2c72cf27
M compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/UiDemos.kt
A compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/accessibility/ComplexAccessibility.kt
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
b....@gmail.com <b....@gmail.com> #30
Here is another example where we think it would be nice to have an API to specify the custom accessibility focus order. Have a look at LazyRow
of tabs and a HorizontalPager
. When used with TalkBack, the user has to scroll through all the pages back to the first element of the first page to finally jump out of the Pager
and to return to the tabs. The tabs are there to quicken the navigation (the user selects a tab, then the Pager
goes straight to its content). So we think it would be nice to allow the user to exit from the current page in the middle of the Pager
straight to the active tab - not to the previous page. Maybe, it would also be helpful to automatically focus the page right after the user selects a tab, so it is not required to scroll through all the rest tabs in LazyRow
to reach the now-active page.
jo...@gmail.com <jo...@gmail.com> #31
Hello, anybody can show a use case of:
modifier = modifier
.semantics {
requestFocus(label = "label", action = {
anyAction()
true
} ...
For handle talkback focus
Or:
modifier = modifier
.semantics {
focused = false
...
to lost a focus and recovery again.
Thanks!
ap...@google.com <ap...@google.com> #32
Branch: androidx-main
commit c8984d286586fa208df859b6a6f906364db47823
Author: Melba Nuzen <mnuzen@google.com>
Date: Wed Mar 15 11:24:57 2023
Only sort speaking nodes and implement traversal index API
Test: AndroidAccessibilityTest.testSortedAccessibilityNodeInfo_traversalIndex() and others
Bug: 186443263
Relnote: "New semantics property traversalIndex, a float used to reorder nodes in TalkBack traversal (lower values come before)."
The first change in this CL switches the semantics sorting logic so that only `structurallySignificant` or `screenReaderFocusable` nodes are considered in the sorting algorithm. `structurallySignificant` is only true if the node is a container/traversalGroup, or is a scrollable, or has collectionInfo. `screenReaderFocusable` is true when a node will be traversed by TalkBack.
The second change in this CL adds in a `traversalIndex` API that can be used to customize TalkBack traversal order. When the `traversalIndex` semantics property is set on a container/traversalGroup or on a screenreader-focusable node, then the sorting algorithm will prioritize nodes with smaller `traversalIndices` first.
The default traversalIndex value is zero. If a screenreader-focusable node is inside a `traversalGroup`, then it’ll inherit placement of the `traversalGroup`, but inside the `traversalGroup` itself, still have default value of 0. This way, developers can use `traversalIndex` on a group to change the ordering of the group (relative to its peers) as a whole, but still be able to customize the traversal order of the children of that `traversalGroup`.
See go/traversal-index-changes for more details.
Change-Id: I9a81b4acf33c355c1142e28e6fd94788f7937cec
M compose/ui/ui/api/current.txt
M compose/ui/ui/api/public_plus_experimental_current.txt
M compose/ui/ui/api/restricted_current.txt
M compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/accessibility/ComplexAccessibility.kt
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
lu...@livefront.com <lu...@livefront.com> #33
Any news on when this fix will actually hit a release? The changes look beautiful!
ae...@google.com <ae...@google.com> #34
The new traversalIndex
/traversalGroup
SemanticsProperties will first be released in 1.5.0-beta01, scheduled for mid-next-week. We think it should be a flexible tool to improve a11y focus order for many of the known use cases, I hope it solves your problem!
If it doesn't behave as you expect, please post a video along with sample code, and we'll investigate. Also, please note that there are still known issues with TalkBack initial focus after navigation which traversalIndex
is not yet able to solve (see
lu...@livefront.com <lu...@livefront.com> #35
Greatly appreciated. My use case will definitely put it to the test!
lu...@livefront.com <lu...@livefront.com> #36
Thank you so much for the travesalIndex
/traversalGroup
release! It has mostly worked as expected. The one issue I am seeing is when the parent has semantics(mergeDescendants = true) {}
. I made an example:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TraveralTestTheme {
TraversalExample(
modifier = Modifier
.semantics(mergeDescendants = true) { }
.background(color = Color.Gray)
.fillMaxSize()
)
}
}
}
}
@Composable
fun TraversalExample(
modifier: Modifier = Modifier,
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = modifier.semantics { isTraversalGroup = true },
){
Column {
Text(
text = "I should be announced first",
modifier = Modifier
.padding(16.dp)
.semantics { traversalIndex = 1f },
)
Text(
text = "I should be announced third",
modifier = Modifier
.padding(16.dp)
.semantics { traversalIndex = 3f },
)
}
Text(
text = "I should be announced second",
modifier = Modifier
.padding(16.dp)
.semantics { traversalIndex = 2f },
)
}
}
The announcement order is: 1,3,2.
The announced string is: "I should be announced first, I should be announced third, I should be announced second"
ae...@google.com <ae...@google.com> #37
Got it. traversalIndex
's current implementation only control the order that TalkBack moves its focus box around: we hadn't yet considered the use case of controlling the announcement order within a single merged element. Feel free to file a separate bug on that.
For now, clearAndSetSemantics { contentDescription = "I should be announced first, I should be announced second, I should be announced third" }
could be an alternate way of solving this, although I recognize clearAndSetSemantics
has downsides and it's usually better to avoid it.
lu...@livefront.com <lu...@livefront.com> #38
OK. I will do that! Thank you very much. I have noticed other interesting behavior but haven't been as successful in reproducing it. We think some of the behavior is related to this:
Also remove the idea of 'structurally significant' to only talk about
traversalGroups
by addingisTraversalGroup = true
to Foundation classes (Modifier.scroll semantics and LazyLayoutSemantics). This way, all scrollables are consideredtraversalGroups
in preparation of aosp/2491418 and go/traversal-index-changes.
as we have solved some of our issues by using Modifier.semantics { isTraversalGroup = false }
with scrollable components. The basic description of the issue "the scrollable item seems to be moved deeper into the traversal tree than its peers as it is skipped until the next layer is announced. However, it is properly announced if isTraversalGroup
is set to false
".
ae...@google.com <ae...@google.com> #39
OK, that sounds like another thing worth filing a separate bug for. We can use your example either to improve our default behavior, or to provide guidance on when to specify isTraversalGroup = false
. Please include two videos of what you are seeing (with isTraversalGroup = false
on the scrollable, and without).
lu...@livefront.com <lu...@livefront.com> #40
Of course. Thank you!
lu...@livefront.com <lu...@livefront.com> #41
I made the issue for that first bug!
eg...@gmail.com <eg...@gmail.com> #42
Thanks for this long waiting feature. During integration we faced runtime crash when we switch compose screens: java.lang.IllegalStateException: LayoutNode should be attached to an owner
Similar issue:
ae...@google.com <ae...@google.com> #43
Marking this bug fixed because the new traversalIndex
traversalGroup
If anyone still can't find a way to solve their use case after experimenting with them, please file a new bug and post a video along with sample code.
Description
It would be really useful to be able to change focus order as we were able to do it before with accessibilityTraversalAfter accessibilityTraversalBefore.
This feature is a must have, specifically when designing a view on the Z axe to actually specify to talkback in which order to read element.
Moreover, it is also necessary when using a FAB button, if the element behind is an infinite list, we should be able to set the focus to the FAB Button first otherwise the user experience for a blind person is really poor.
Thanks for you work on Jetpack Compose, and keep going !