Status Update
Comments
so...@google.com <so...@google.com>
yi...@google.com <yi...@google.com> #2
First of all thanks for this detailed issue.
This issue had been investigated thoroughly when it was first reported internally. The surprising detail in this report is that the issue is not reproducible before 1.7
. I will look into this.
The main problem with POBox is the fact that it is deprecated. Since 2021 Sony has been shipping new Xperia devices with Gboard pre-installed. Although we are aware that there is still a considerable amount of users still using POBox, the described behavior is caused by POBox's noncompliant behavior with InputConnection
and InputMethodManager
documentation. However, this is understandable since TextView
implementation was also not respecting the behavior that is expected from Editors.
Ultimately we have decided to enforce the documented behavior with specifically regards to when editors should call InputMethodManager.updateSelection
. Also, although unconfirmed, there were traces of possible custom code being included in Sony OEM images that changed how InputMethodManager was notified from TextView. If POBox also depended on something like this, it would be impossible for Compose code to replicate the same unknown behavior.
am...@twitter.com <am...@twitter.com> #3
Or is that option not available?
Even if the root cause is POBox, from the perspective of the app's customers, it looks like an app bug, so this issue is a blocker against updating Jetpack Compose.
so...@google.com <so...@google.com> #4
Just to be sure, it is dangerous to replace Compose TextField with Android View EditText as a workaround for this issue.
Compose 1.7 has a bug that causes ANR when the focus is on EditText.
Another View-related bug in Compose 1.7 is that an Android View is focused by calling FocusManager.clearFocus().
Perhaps there is a lack of testing of Compose 1.7 in combination with Android View. There is also a possibility that there are other fatal bugs related to View.
In other words, the only options for apps targeting the Japanese market that require POBox support are to continue using Compose 1.6 or to use EditText in combination with various workarounds.
fa...@gmail.com <fa...@gmail.com> #5
Project: platform/frameworks/support
Branch: androidx-main
Author: Halil Ozercan <
Link:
Fix POBox keyboard issue
Expand for full commit details
Fix POBox keyboard issue
Fix: 373743376
Fix: 329209241
Test: NullableInputConnectionWrapperTest
Change-Id: I94e0e598274fb88b255f977f9fbd50dfbbb1ecb1
Files:
- M
compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/input/NullableInputConnectionWrapperTest.kt
- M
compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/NullableInputConnectionWrapper.android.kt
Hash: 57f58c4b80d5d8470b2aca325dfdcd55f235231e
Date: Thu Oct 24 01:25:20 2024
yi...@google.com <yi...@google.com> #6
Many thanks again for this report. Especially for giving us a huge clue in terms of what could be going wrong. The fix is now merged and I will ask for a cherry-pick into a stable release.
fa...@gmail.com <fa...@gmail.com> #7
Do you have any concrete plan to cherry-pick the fix into current stable version (1.7.x)? We are currently waiting it.
fa...@gmail.com <fa...@gmail.com> #8
Yes, this fix is planned to be included in a future 1.7.x
release.
am...@twitter.com <am...@twitter.com> #9
Thanks for the fix. Sorry to follow up on this. is it possible for you to share specific release version/date for the stable version? We are waiting on this to decide on our direction.
yi...@google.com <yi...@google.com> #10
screen like the app bar and fab " seems to be a feature which should implemented in talkback.
@Anastasia @Alex
Maybe when we order nodes, if two nodes partially overlap, we should consider z index first(top one first)? instead of relying on bounds (the current approach adopted from ViewGroup.java)?
ae...@google.com <ae...@google.com> #11
Yes, disambiguating based on zIndex
sounds like a good idea, I can't think of any reason not to do it that way. It looks like the reason ViewGroup didn't have it is simply because View System didn't have zIndex
(it supported translationZ
, but structurally zIndex
is better suited to calculate overlap order without requiring any matrix math).
pw...@google.com <pw...@google.com> #12
I agree with Yinglei that if TalkBack's auto-scrolling is preventing access to a FAB, that bug is likely best addressed in TalkBack, perhaps with a heuristic that everything on the screen should be traversed before a list that will auto-scroll. If ordering nodes based on z helps in the meantime, though, that seems like a reasonable change to make.
Since system-level FABs are in their own windows, maybe app-level FABs should be in their own panes? That seems semantically correct, and TalkBack does announce panes when they appear. Not sure if/how this concept is exposed in Compose, though.
fa...@gmail.com <fa...@gmail.com> #13
Here is the API that I think is doing that in SwiftUI
The developer could add a sortPriority to a composable and if we detect that it will influence the Semantic sort : you can first order by sortPriority then by ordering left-to-right, top-to-bottom.
(sorry for the intrusion but although the solution "consider z index first(top one first)?" is a working fix, I don't think it provide the best user experience and will probably be tricky to handle with the auto-scroll).
yi...@google.com <yi...@google.com> #14
I tried the "when we order nodes, if two nodes partially overlap, we should consider z index first(top one first)" approach. It does work if we have z-index defined, but by default, floating action button doesn't have a higher z index, as I can see from
demo app -> material-> scaffold -> scaffold with snackbar
both the scrollable node and fab have z-index 0.0, so by default (if we don't set a higher z-index for fab), it won't solve the problem (if we set z-index to 5.0, fab will be focused first).
Also, I'm not sure whether this z-index sorting approach is reliable because the sorting is done on layout node level instead of semantics tree, for example, if we have one layoutnode with two children: 1. scrollable layout node for lazy list, 2. a layout node(call it A) which is a parent of the fab. If we set the z-index of the fab only, we don't affect layout node A, and won't affect the sorting.
Now we have a problem: I'm not sure talkback has the plan to change auto scroll. In view system, we have this traverse order api(even though we don't like it, and I believe android message app has the same infinite scroll and not reach fab issue and they didn't fix it using the traverse order api), but in compose, we don't have anything. Maybe is a solution to add ordering api?
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 !