godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.47k stars 20.25k forks source link

Acessability: SpinBox, LineEdit and TextEdit are focus traps #97444

Open betalars opened 2 hours ago

betalars commented 2 hours ago

Tested versions

v4.3.stable.custom_build [41b17e249]

System information

KDE Plasma 6.1.2 - Wayland - on nixos

Issue description

When a SpinBox is part of a UI and is being navigated to with directional keys, it functions as a focus trap You can escape it using ui_focus_next and ui_focus_previous, but to my knowledge it is inescapable on a controller. The player cannot leave this element using a game-pad without losing focus entirely. They cannot navigate past this element at all on a gamepad.

Steps to reproduce

  1. Add a stack of buttons and a SpinBox in the middle.
  2. click the top button to gain focus
  3. try navigating past the SpinBox with only a gamepad

Minimal reproduction project (MRP)

n/a

betalars commented 2 hours ago

Requesting the Acessability Label for this Issue.

betalars commented 2 hours ago

I suggest having to press the Enter key to confirm starting to edit a text input field when you navigate into it using arrow keys. Pressing enter when the text is selected should bring focus back to the element and not the edited text.

This would mean the element has kind of a surface and a deep focus mode, where on the surface you just select the element and on the deep mode you edit the text.

betalars commented 2 hours ago

Update: it is no longer a focus trap when the focus_mode is set to all.

However I fail to see how you are then supposed to enter numbers.

  1. Opens Spinbox
  2. Looks Inside
  3. Line Edit!

:bulb:

So the LineEdit inside spinbox automatically gets focus when the SpinBox focus mode is set to none. That is really counter-intuitive imho.

betalars commented 1 hour ago

If anyone stumbles across this issue and wants a workaround here is what I did to remedy:

  1. I set the focus mode of the SpinBox to always.
  2. I use _input and check for focus to write a custom handle.
  3. When I am focused and the enter key is pressed, I enter a special mode where the navigational keys will increase and decrease the value by step
  4. I set a bunch of theme overrides for the LinEdit depending on the state of the SpinBox

As I prevent the underlying line edit from grabbing focus in the first place trough directional navigation, it is no longer acting as a focus trap.

Resolving this for Line Edits on your own is going to be a bit more difficult tho. You may ned to nest it into a parent control node that handles focus, have not looked into it yet, as I currently do not need that feature for my game.

betalars commented 1 minute ago

Oh I need to investigate a flaw in my own logic, but don't currently have a controller at hand to test it.

This issue does not need further investigation right now until i double checked something.