KeyboardNavigation's per-frame focus restore fights intended MyGUI key focus resets
Issue Description
KeyboardNavigation::onFrame (apps/openmw/mwgui/keyboardnavigation.cpp) contains an old workaround that re-sets key focus to the previously focused widget every frame whenever the current focus became "unsuitable" (null, a Window, invisible or disabled). It has no way to tell a conscious focus change from an erroneous one, which causes the following:
- Clicking outside a text box does not dismiss the caret: MyGUI clears key focus as intended (
InputManager::injectMousePress→setKeyFocusWidget(nullptr)), and then the workaround puts it back on the next frame - In general clicking outside of UI with already selected element such as button (in exit prompt, dialogue, containers, settings) keep the focus on such element. While there is a thought of enhancing the player experience, the focus can't be removed at all, only moved, which can hinder the experience
- Every reset+restore cycle emits a focus lost + focus gained event pair even though effectively nothing changed; Lua UI sees these as phantom
focusLoss+focusGainevents - Any future API for clearing key focus programmatically (#9193) would be undone by the restore one frame later
As such, it is fair to assume that this a core reason behind #5887 (closed), as it affects not just the text input fields, but all the other UI elements too.
History
- The workaround came with the introduction of keyboard navigation (c11fe678 + 475ac46f, 2017). There are several comments in code acknowlodging this trade-off
- While these focus resets are intended behavior on MyGUI's side, it seems that since then MyGUI 3.4.0 has added a proper reset event firing
- A search field was exempt from the restore in 2018–2020; the exemption was dropped when search field behavior was unified, and then #5887 (closed) was opened
The proposed fix is that instead of enforcing the focus every frame, we remember the last suitable focus widget and resume keyboard navigation from it on the first navigation key press. (MR from me soon or maybe even already)
Related: #5887 (closed) (main symptom), #9193
Steps to Reproduce
- Open the inventory
- Click the item search field and type a few letters
- Click on an empty spot of the window background
- Click the field again
- Close the inventory and open it again
Expected: the cursor is dismissed, further keystrokes no longer go to the field; after re-opening the inventory the field is inactive. Actual: key focus returns to the field on the next frame, the cursor stays and typing continues into it; same with re-opening the inventory. Same with every other search/filter field and every Lua UI text input.
System Information
- OpenMW Version: 0.51.0 release and current master (b0c4c7)
- Operating System & Version: Arch Linux
Mods
- Are you using mods? No
- Are you using any shader mods? No
- Does it happen in a clean vanilla install? Yes (the built-in search fields are enough)