Walk the stickers and the GIFs of the panel with the keyboard - #31243
Open
rezabakhshilaktasaraei wants to merge 5 commits into
Open
rezabakhshilaktasaraei wants to merge 5 commits into
rezabakhshilaktasaraei wants to merge 5 commits into
Conversation
The emoji panel is a painted grid with no keyboard handling and nothing for a screen reader to read: opened from the keyboard, it appeared with no one to talk to, and pressing the "Emoji" button of a field seemed to do nothing. Expose every cell shown as an item of a list - named by the emoji itself, which the screen reader speaks in its own words, described by the section it is in (the category, or the title of a custom set); the last cell of a collapsed set is the "+N" that opens it. In screen reader mode the list takes the focus once the panel is shown and remembers where it came from; the arrows walk the cells (Up and Down by column, on into the next section), Home, End and the page keys too. Enter or Space chooses the emoji, Escape gives up - both return the focus to where it was and ask the panel to hide, which TabbedSelector::cancelled() passes on. A selection made from the keyboard survives the mouse leaving the list. SetFocus and Invoke from the screen reader work the same way. The "Emoji" toggle of a field gives the focus to its field before opening the panel: the fields of a box tell the target of a chosen emoji apart by the focus, which a toggle pressed from the keyboard held itself. With the mouse the field has it already.
The variants of an emoji - its skin tones - are picked from a small panel the mouse brings up over the emoji: right away on the first press of an emoji none of whose variants was ever chosen, and under the button held for a long press after that, while a click puts the emoji in with the tone chosen before. From the keyboard there was no way to it: the emoji went in with whatever tone it had. Enter and Space now do on an emoji with variants what the mouse does, with the same delay: the picker comes up right away for one never chosen from, under the key held for a long press otherwise, and the key let go before that chooses. The picker takes the focus, with the variant shown in the list selected; it is a list for a screen reader, named by the emoji, its items the variants. Left and Right, Home and End walk them, Enter or Space chooses - the tone is saved and the emoji goes in, as a click does, with the focus back where it came from and the panel done - and Escape backs out to the same emoji in the list. The picker is raised above the list rather than inside it, so the list gives the focus in it back the same way as its own, and keeps the emoji it was on when the picker hides.
An emoji with skin tones and one without sounded the same in the list; nothing said there was a picker to open. Report such an emoji as expandable - expanded while its picker is up - so the screen reader hears it as collapsed and offers to expand it, which opens the picker as Shift+Enter does; collapsing closes it. On Windows this needs the UIA ExpandCollapse pattern offered to expandable elements (Qt patch 0043).
The row of category icons under the emoji list and the groups beside its search field were painted strips with nothing for a screen reader and no keyboard; the search field itself was reachable, but nothing led from it to the results. The footer is a list for a screen reader - named "Categories" - with the recent section, the categories - the "all categories" icon as one item per category - and the custom emoji sets by title, the group's set by the group's name; on the stickers tab the favorites, the trending sets and the button to manage the sets as well. The section shown is the selected item. Left and Right, Home and End walk it, Enter or Space chooses the section, scrolls the list to it and puts the keyboard on its first emoji. The groups are a list too - "Search groups" - named by the titles the server sends with them, which were dropped. Choosing one runs its search and puts the keyboard on the first result once the results are in, and the keyboard keeps its place in the list through a refill of the results. Enter or Down in the search field goes on to the first result as well; the buttons around the field - search, back, clear - get names, and the emoji list itself is named as its tab is.
The stickers and the GIFs tabs of the panel were as the emoji tab was before: painted grids with nothing for a screen reader and no keyboard, and a tab switched to took the focus into its search on its own. The stickers are the items of a list, named by the emoji a sticker stands for and described by the title of its set; the GIFs are one too, each named the way the app names an animation, as they have no text of their own. Both are walked as the emoji are - the arrows, Home and End, the page keys - and Enter or Space sends the one the keyboard is on and hides the panel, with the focus back in the composer; a GIF is sent right away, as with Ctrl held, since the keyboard can't see whether the preview a click waits for has loaded. Escape gives up the same way. The footer of the GIFs tab names its sections by their emoji. Enter or Down in the search field of either tab goes on to the first result, a group chosen beside it lands on the first result once the results are in, the keyboard keeps its place in the stickers through a refill, and a set chosen in the footer lands on its first sticker. A tab switched to from the tab strip with a screen reader leaves the focus on the strip: the switch no longer resets it to the window, the strip is not hidden for the slide or its picture, and the tab shown does not take the focus into its search then. Opened afresh, the tabs behave as they did.
elfelfdeewun933-sys
approved these changes
Sep 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On top of #31242. The Stickers and GIFs tabs of the panel were as the Emoji tab was before #31240: painted grids with nothing for a screen reader and no keyboard.
StickersListWidget): a list named "Stickers"; each sticker named by the emoji it stands for, described by its set's title. Arrows, Home/End, page keys as in the emoji list; Enter or Space sends the sticker and hides the panel with the focus back in the composer; Escape gives up the same way. A set chosen in the footer lands on its first sticker; Enter/Down in the search field or a group chosen beside it lands on the first result once results are in.GifsListWidget): a list named "GIFs"; items are named "GIF" (the app's own label for animations — they have no text) with their position from the set. Enter sends right away, as with Ctrl held, since the keyboard can't see whether the preview a click waits for has loaded. The GIF footer names its sections by their emoji.TabbedSelector::beforeHiding), the strip isn't hidden for the slide or its picture (it wasn't in the picture anyway), and the tab shown doesn't take the focus into its search then (Inner::setKeepsFocusOnShow). Opening the panel afresh behaves as before. This part matters once the strip is focusable (Expose discrete slider sections as accessible tabs #31097); it compiles independently.Nothing changes without a screen reader. Verified with NVDA.