godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Add ui_focus_next and prev to PopupMenu #10281

Open Giganzo opened 1 month ago

Giganzo commented 1 month ago

Describe the project you are working on

Menus for game/program.

Describe the problem or limitation you are having in your project

Right now you can't navigate PopupMenus with tab or shift+tab in either the project you create or in the editor itself. If you create programs this functionality would probably be expected by the some users. See Krita (File, Layer, etc) as an example or this menu in Firefox:

Screencast_20240725_145019.webm

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Makes it possible to navigate with tab and not just arrow keys.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

See linked pull request. it adds ui_focus_next and prev to same functions as arrow keys has. https://github.com/godotengine/godot/pull/94743

If this enhancement will not be used often, can it be worked around with a few lines of script?

Maybe possible with gui_input. But this would also help the navigation in the editor.

Is there a reason why this should be core and not an add-on in the asset library?

Improves accessibility of the PopupMenu

KoBeWi commented 1 month ago

What's the advantage over using up/down arrows? While it exists in some applications, it's not really a standard behavior (unlike arrows).

Giganzo commented 1 month ago

What's the advantage over using up/down arrows? While it exists in some applications, it's not really a standard behavior (unlike arrows).

KDE and Gnome stuff looks to work like that as another example.

What does it offer over arrow keys. Option for other method of input. I think that's good for accessibility and personal preference.

Another suggestion could be to add it as an option for the PopopMenu.

I am open to hearing other suggestion if they think this is helpful or a problem in any way.

Could see tab key working with the PopupMenu in another way. And that is that it should close the PopupMenu (right now i does nothing) and then set focus to next item (preferable a way to set what to focus).

Giganzo commented 1 month ago

And it looks possible to add tab navigation to a PopupMenu with gdscript. Havent tried replicateing the mouse behavior, but this is a quick example with tab key navigation on a MenuButton:

extends MenuButton

func _ready() -> void:
    focus_mode = FOCUS_ALL
    setup_popup() # func to add the items
    get_popup().window_input.connect(_on_popup_gui_input)

func _on_popup_gui_input(event: InputEvent) -> void:
    if event.is_action_pressed("ui_focus_next", false, true):
        get_popup().set_focused_item(get_popup().get_focused_item() + 1 if get_popup().get_focused_item() + 1 < get_popup().item_count else 0)
    elif event.is_action_pressed("ui_focus_prev", false, true):
        get_popup().set_focused_item(get_popup().get_focused_item() - 1 if get_popup().get_focused_item() - 1 > -1 else get_popup().item_count - 1)
KoBeWi commented 1 month ago

KDE and Gnome stuff looks to work like that as another example.

Well GIMP is GNOME (I think?) and doesn't support it.

Option for other method of input.

You already have that option. Just rebind ui_up and ui_down.

Giganzo commented 1 month ago

Well GIMP is GNOME (I think?) and doesn't support it.

GIMP doesn't that is true. If its part of GNOME I don't know. Spectacle, Konsole, KWrite in KDE are examples that does.

You already have that option. Just rebind ui_up and ui_down.

Wouldn't that cause problem as then the tab key would also trigger these actions where you don't want too

Giganzo commented 1 month ago

As I understand @KoBeWi you don't like this proposal. Do you have any input on why? Do you believe it would cause some usability problems and such.

And what do you think about this

Could see tab key working with the PopupMenu in another way. And that is that it should close the PopupMenu (right now i does nothing) and then set focus to next item (preferable a way to set what to focus).

Thanks for your feedback :)

KoBeWi commented 1 month ago

As I understand @KoBeWi you don't like this proposal. Do you have any input on why?

Well, I find it unnecessary, because it duplicates up/down keys. But that's just one opinion, other people might like it and find it useful.

And what do you think about this

Currently menu buttons are unfocusable. You can focus OptionButtons, but there is no way to close the popup and keep the focus. I think pressing Escape should close the menu and keep the button focused, but that's unrelated to Tab.

Giganzo commented 1 month ago

Currently menu buttons are unfocusable. You can focus OptionButtons, but there is no way to close the popup and keep the focus. I think pressing Escape should close the menu and keep the button focused, but that's unrelated to Tab.

If we look at https://www.w3.org/WAI/ARIA/apg/patterns/menubar/ they have this for tab key:

When focus is on a menuitem in a menu or menubar, move focus out of the menu or menubar, and close all menus and submenus.

And if we follow there guidelines for menubar, tab shouldn't be used for navigating the dropdown.

Note that Tab and Shift + Tab do not move focus into a menu.

Giganzo commented 1 month ago

For your own project it is possible to do the tab navigation up and down:

Screencast_20240725_233916.webm

Updated code example above. Maybe it should be a custom node that could be shared on the Asset library if anyone find it helpful.

If this isn't something added to the engine maybe the ARIA pattern mentioned above could be another proposal for navigating in the editor.

The menubar pattern can be setup with gdscript too:

Screencast_20240725_233755.webm

Giganzo commented 1 month ago

Here is an example from ARIA where they uses both tab and arrow keys for navigating a menu: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/ So depends of which pattern fits the use-case