Skip to content

fix: commandInsert getting stuck in insert-mode after a missed key-release#7994

Open
DrRaider wants to merge 2 commits into
beyond-all-reason:masterfrom
DrRaider:fix-commandinsert-stuck-insert-mode
Open

fix: commandInsert getting stuck in insert-mode after a missed key-release#7994
DrRaider wants to merge 2 commits into
beyond-all-reason:masterfrom
DrRaider:fix-commandinsert-stuck-insert-mode

Conversation

@DrRaider

Copy link
Copy Markdown

Work done

cmd_commandinsert.lua turns insert-mode on while its action key is held: the key-press sets modifiers.prepend_between / modifiers.prepend_queue, and the key-release clears them. If that release is never delivered to the widget — which happens when the window loses focus while the key is still held (alt-tab, or a compositor key-grab; common on Wayland) — the flag stays set. From then on CommandNotify converts every order into a CMD.INSERT and returns true, so right-clicks stop issuing direct orders and box-select misbehaves, until a /luaui reload.

This adds a widget:Update failsafe that re-validates insert-mode against the real held state of the bound key(s) and clears it when none are held. Bound keys are resolved via GetActionHotKeys for the action+arg combinations (commandinsert prepend_between / commandinsert prepend_queue), so it works for any binding — modifier keys via GetModKeyState, regular keys (e.g. the default space) via GetKeyState.

Efficiency: the per-frame check early-outs unless a flag is set (two table reads, no engine call, no allocation). Engine state is polled only while insert-mode is actually active; the bound keys are resolved once and cached; there is no per-frame heap allocation. If the binding can't be resolved yet it fails safe (treats the key as held, so the feature is never broken, and retries). version bumped to 2.

Test steps

  • Hold the insert key (default space), alt-tab to another window, release the key there, return to the game → right-clicks issue direct orders. (Before: every order is inserted/queued until /luaui reload.)
  • Normal use still works: hold the insert key and click → the command is inserted into the queue as before (the failsafe only clears when the key is genuinely released).

Testing done

Verified in live games on Linux/Wayland with an instrumented build of this exact logic (a gated log line on each auto-clear). It correctly resolved the bound key (space) and, over a single ~3.5 h session, auto-cleared 17 genuine stuck-insert-mode occurrences — each of which would previously have required a manual /luaui reload. It did not fire during normal insert use (it only triggers while the bound key reads released), so the insert feature is unaffected. (An earlier build that polled the wrong key was discarded.)

AI / LLM usage statement

Root cause was diagnosed and the fix drafted with the assistance of Claude Code (Anthropic). All code was reviewed, edited, and verified in-game by me; the testing described above is from my own play sessions.

@DrRaider DrRaider changed the title Fix CommandInsert getting stuck in insert-mode after a missed key-release fix: commandInsert getting stuck in insert-mode after a missed key-release Jun 18, 2026
@efrec

efrec commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

We should not do spot-fixes for broader issues like mishandling general inputs. So I do not want to proceed with this change.

The diagnosis seems like a likely id for several issues, though.

@DrRaider

DrRaider commented Jun 18, 2026

Copy link
Copy Markdown
Author

Agreed, this is a symptom of the broader problem: key-release events getting lost when the window loses focus while a key is held (alt-tab / compositor key-grab; happens readily on Wayland). Any widget that latches key state on press/release can stick the same way, CommandInsert is just where I caught it.

It is quite impactful while playing tho, having to /luaui reload multiple times per game.

Happy to write this up as a general issue. If the right fix is the engine treating held keys as released (or re-syncing key state) on focus loss, that'd cover all such widgets at once rather than patching each.

@efrec

efrec commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

I think this is the starting point for general discussion: beyond-all-reason/RecoilEngine#2192

If we wanted to step outside of that discussion, then imo window control is an engine responsibility. Maybe the engine team would accept a WindowFocus callin with a similar code footprint to ViewResize.

Input events and handling might move away from the engine and towards being a game responsibility, though. See linked comments.

@efrec efrec added Widget Unsynced gameplay and UI code Review Session Candidate Review this on the next Github review voice session! labels Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review Session Candidate Review this on the next Github review voice session! Widget Unsynced gameplay and UI code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants