fix(input): an input still held after the Insert menu no longer blocks the pads' other buttons #340
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
beanstalk: approved @ 1697603
beanstalk: approved @ 2c5a62e
beanstalk: approved @ 4fd82b7
beanstalk: approved @ 64d6d09
beanstalk: approved @ 6f91fae
beanstalk: approved @ 70a78f9
beanstalk: approved @ 8d361dc
beanstalk: approved @ 9d8356e
beanstalk: approved @ abf2227
beanstalk: approved @ d82f202
beanstalk: approved @ e5f1e40
beanstalk: approved @ ee8ab5f
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!340
Loading…
Reference in a new issue
No description provided.
Delete branch "jarynclouatre/Longshot:fix/pad-after-menu-each"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type: fix · Risk: low · Tested on: Linux x86-64 (game-free checks only) · Needs: none
Why
After the Insert menu was open once, the pads reach the game again only when no input of any controller is down. One input that stays down (a worn or mis-mapped trigger past its rest, a Guide button, something resting on a second controller) keeps every button and both sticks of every pad from the game for the rest of the session, while the Insert menu, which reads the raw word, still answers.
read_inputinhost/nn_hid.ckeeps one flag:if (rx_option(1, 0)) pad_after_menu = 1; else if (pad_after_menu && !pad_raw_now) pad_after_menu = 0;, and gives the game the pads only while it is clear.How to reproduce
Seen on: found reading the code; not seen in the game. Game-free checks on Linux x86-64.
Settings and switches: defaults.
Steps: Keep one controller input down, open the Insert menu and close it, then try another button and the sticks.
Expected: Each input held through the menu waits until released; the other buttons and sticks count after it closes.
Actual: Every button and both sticks of every pad stay out of the game until all controller inputs are up; the Insert menu still answers.
What changed
After the Insert menu closes, each pad input it used waits for its own release. Other buttons, the sticks and the ocarina notes can reach the game while one input stays down.
host/nn_hid.c,read_input):pad_after_menuis now the set of pad inputs (1 << HOS_PAD_*) that were down while the menu was open, or at the first read after it closed, so the press that closed it waits even when no read saw it while the menu was open. After the close each input leaves the set when it is let go, and the game getsbound_pad_buttonsof the others (pads_readkeeps the last read's inputs without the Back+Start chord inpad_raw_gamefor that). While the set is empty the game getspads_read's word as before. The sticks are withheld while the menu is open and count again as soon as it is closed.oc_notes,oc_pad_word): the note layer leaves out the waiting pad inputs instead of playing no notes until all are up.tests/test_pads_after_menu.py(new) compiles production'spads_read,bound_pad_buttonsandread_input's pad block with fakes for SDL, XInput and the clock. A trigger held through the menu and the close: the press that closed it and the trigger wait, the sticks count at once, South gives B with the trigger still down, the closing button counts when pressed again, the trigger counts once it was let go; a close press no read saw while the menu was open waits too; a button resting on a second pad waits while the first pad's buttons count.tests/test_ocarina_notes.pycase (j) now holds the (L) note's pad input after the menu: no note from it, the keys' notes still play, and the note comes back once it was let go.tests/input_background_test.cdeclares the new state.Measurements
Verdict: the new pad test fails on main and passes here; the suite gains one passing check with no new failures.
Hardware: none used (game-free checks on a Linux x86-64 PC, gcc 15.2, Python 3.14.4; no clang++ there)
Scene: none, the game was not run
Method: 2026-11-14; branch
fix/pad-after-menu-each.python3 -I -B tests/run_all.py, two runs each, interleaved (main, PR, main, PR, with the other two branches' runs between); both runs of a side gave the same counts. The PR's new or changed checks also run against main's source.How to reproduce: the commands above in a checkout of each commit
5ad0f50374998cc5tests/run_all.py(run 1, run 2)test_bake_portability.py,test_pad_layout.py,test_menu_keys.pytests/test_pads_after_menu.pytest_bake_portability.pyfails here for a missing Python module (zstandard), on main as well.test_pad_layout.pyfails on main since #137 (its fixture lackshost/hold_toggle.h; #331 and #338 fix it).test_menu_keys.pydoesn't build with g++ on main since #137 (#338 fixes it).Flags and settings
None.
Testing
Tested: the game-free suite on a Linux PC, as in Measurements.
host/nn_hid.ccompiles (-fsyntax-only) with llvm-mingw 20261104's x86_64-w64-mingw32-clang and with Linux gcc 15.2, with the same warnings as main's; no file paths are touched.Not tested: a controller in the game. The new test runs production's pad read and the pad block of
read_inputwith the pads faked at SDL's boundary.Must be tested: None.
Risks
What could break: Pad input handling after the Insert menu, including the ocarina's note layer.
Turning it off: Reverting the commit puts the single flag back.
Compatibility: The sticks now count right after the menu closes instead of after every input was let go;
host/pad_sdl.c's stick rest guard is unchanged.Reviewer notes
read_input(pads behind another window); one of the two will need a small rebase.Issues
For #296
Checklist
Everyone
type(scope): description) of the status line's type.main.python -I -B tests/run_all.pypasses (any failure that also fails onmainis named).third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
mainand passing here.tests/that reads changed source updated in this PR, not weakened.WIP: fix(input): an input still held after the Insert menu no longer blocks the pads' other buttonsto fix(input): an input still held after the Insert menu no longer blocks the pads' other buttonsView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.