Skip to content
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

Add listbox support #498

Merged
merged 3 commits into from
Feb 26, 2025
Merged

Add listbox support #498

merged 3 commits into from
Feb 26, 2025

Conversation

DataTriny
Copy link
Member

Fixes #23

Adds support for list box controls on all supported platforms.

Known issues

VoiceOver only reports the selected items when the focus leaves the list box and if there is more than one child. I am not sure if this is the expected behavior for such controls. The accessibilityRows and accessibilitySelectedRows methods seem to never get called, but this might just be because of my very old macOS version.

Testing

These changes can be tested with this fork of Slint: cargo run -p _7guis --bin crud

The "Names" list view supports keyboard navigation: Up and Down arrows, PageUp, PageDown, Home and End keys, with the Control key modifier to move the focus but not the selection. However, multiple selections are not allowed. I think there are bugs in how the model syncs with the accessibility tree so adding or removing items usually put the application in an inconsistent state.

@mwcampbell
Copy link
Contributor

The code under consumer and platforms/windows looks good. But when I try to run the crud example from the slint fork, I get very intermittent speech feedback on Windows with NVDA. @DataTriny Have you tried that example on Windows?

@DataTriny
Copy link
Member Author

Windows 11 with NVDA is currently my setup for development so it is the combination I tested most extensively. Maybe what you are noticing is a short lag when moving the focus through the items. It happens with the Narrator as well. I haven't been able to find anything wrong for now so my current guess is that it is linked to the animation Slint plays when deselecting/selecting the items. The best proof of this is that it takes a bit of time for the AT to announce the first time an item gets the focus, but when you exit the list view and focus it back the focus change is immediately reported by the AT. I had a toy example before, only using winit, and I didn't notice this.

@DataTriny
Copy link
Member Author

I have set the duration of animations which apply to ListItem to 0ms (previously 150ms and 200ms) but I don't notice a real difference.

Instrumentation of the AccessKit codebase would really be helpful in such situation.

@mwcampbell
Copy link
Contributor

What I'm seeing is more severe. When I run the crud binary (a release build), also on Windows 11 with both NVDA and Narrator, there isn't even an announcement that the window is focused, though sometimes if I press Tab, it announces the window.

@DataTriny
Copy link
Member Author

This is something I have never experienced. I will only have access to a Windows 10 machine in the coming days, so I'm not sure if I'll be able to reproduce anything unfortunately.

@mwcampbell
Copy link
Contributor

Looks like a recent change in winit broke AccessKit on Windows. @DataTriny I suspect that if you update the Cargo.lock in your slint repo, you'll see it too. slint doesn't commit Cargo.lock to version control, so when I did a fresh clone of your fork, I got a new Cargo.lock file with the latest version of everything.

I guess we should open a new issue to track this.

@mwcampbell
Copy link
Contributor

I downgraded winit to 0.30.5 in my slint Cargo.lock, and now I can confirm that the listbox support looks good on Windows. Will look into macOS later.

@mwcampbell
Copy link
Contributor

In Node::selection_container and Node::items, I think we want to call the generic filter first, then only check whether the node is the parent or an item if it passes the generic filter. This is particularly important for items; if the generic filter returns ExcludeSubtree, I think we want to return that even if the node isn't item-like.

@mwcampbell
Copy link
Contributor

The UIA and AT-SPI implementations look good. On macOS, I think you forgot to add logic for enabling the setAccessibilitySelected: selector.

@MarcoZehe
Copy link

I just gave this a try on MacOS Sequoia 15.4 Beta 1. Here's what I found:

  1. Up and down arrowing through the list gives me the newly selected item.
  2. If I stop interacting (VoiceOver+Shift+UpArrow), I am told that I am on a list box and that one item is selected, and which item that is. This is the same I had just selected, so those parts work.
  3. Not sure if it is expected, but selecting an item in the list doesn't seem to populate the two text fields for name and surname.

I found one bug: If I add a name by typing in a name and surname, for example Beate Musterfrau, and hit Create, then return to the list box, the name is not spoken while I arrow. down, but is spoken when I arrow up. However, VoiceOver still only sees the three items that were there before, both in the interacting with the list box and on the list box itself. If I leave the selection on the newly created item, the item below it, Tisch, Roman, is told to be selected. So there is definitely an event problem when inserting an item into the list.

Possibly unrelated: I noticed that, while I was typing the name, the Braille display didn't follow and no text appeared. And later, the text was only spoken when focus moved to one of the text fields. Arrowing left and right gave no speech, and interacting with the text fields also didn't see any text inside. But again, that may be unrelated and possibly a different bug in the Mac text implementation.

@DataTriny
Copy link
Member Author

Thank you @MarcoZehe for your help. Overall I am experiencing the same on macOS 11.

Slint (the UI toolkit used in the example program) has an issue with listbox items that are offscreen. I think it explains the issues when adding a new item in the list. You can either resize the window so that more items can fit on the visible area of the list view, or first delete one or more items before creating some. I haven't noticed any bugs while doing this.

The issue with text fields not updating is also due to Slint not yet implementing editable text.

@DataTriny
Copy link
Member Author

What I am unsure about:

  • when interacting with the items, VoiceOver doesn't say that they can be selected. Is it the normal behavior?
  • When I press VoiceOver+Space to select an item, I can hear a sound but VoiceOver doesn't announce that the selection changed. Again, is this normal? Is the selection only announced when leaving the listbox?

@DataTriny
Copy link
Member Author

I'll rewrite the git history once the review is finished.

@MarcoZehe
Copy link

What I am unsure about:

  • when interacting with the items, VoiceOver doesn't say that they can be selected. Is it the normal behavior?

I think so. It should, however, state if the item is currently selected or not. Note that by default, VoiceOver cursor moves keyboard focus, so if you move from one item to the next, the selection changes as well. But yes, VoiceOver should say that an item is selected if that is the case. They don't have a concept of saying "selectable", only the state if the item is selected. if not, it should not say "selected" after the item. So the bug is that VoiceOver doesn't say "selected" when moving the VoiceOver cursor and therefore keyboard focus. However, I noticed that it does speak the selected state if I use the arrow keys instead of VoiceOver commands.

  • When I press VoiceOver+Space to select an item, I can hear a sound but VoiceOver doesn't announce that the selection changed. Again, is this normal? Is the selection only announced when leaving the listbox?

I think this is because the selection is currently not being recognized. If you press the item, at least in a listbox in Firefox or Safari, and the item gets deselected, VoiceOver will say "selection removed, 0 items selected". But yea, that would only happen if the item was previously recognized as being selected. I used this code snippet in Firefox and Safari to test this:

data:text/html,<select multiple size="5"><option>Option 1</option><option>Option 2</option><option>Option 3</option></select>

@DataTriny
Copy link
Member Author

DataTriny commented Feb 26, 2025

  • The first commit also contain changes to the Node::orientation method, to set a default vertical orientation if the node is a ListBox.
  • The second commit also contain changes to macOS adapter's README to mention the issue with selection.

@mwcampbell mwcampbell merged commit 6450470 into main Feb 26, 2025
10 checks passed
@mwcampbell mwcampbell deleted the listbox branch February 26, 2025 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add UIA support for list boxes
3 participants