Rebuild held input after lifecycle resets

A focus flip, visibility flip, joystick add/remove, or resume reset all
held input, and a still-held direction never re-fires keypressed, so any
spurious reset (macOS Bluetooth re-enumeration fires joystickadded with
no hotplug) parked the player until every direction was re-pressed.
Reconcile from device ground truth after each reset; only what is
physically down comes back, so swallowed releases still clear.
This commit is contained in:
johnjohto
2026-08-04 14:08:15 -04:00
parent 1820f411ae
commit 78ac154998
3 changed files with 162 additions and 3 deletions
+10 -3
View File
@@ -793,11 +793,13 @@ function Game:joystickhat(joystick, hat, direction)
end
-- Window focus/visibility flips: a release due while unfocused/hidden can
-- be swallowed by the OS. Reset on both edges -- gaining focus with a
-- physically held key won't re-fire keypressed, so trusting leftover
-- state is worse than asking the player to re-press.
-- be swallowed by the OS. Reset on both edges; on the regain, reconcile
-- re-arms only what is still physically held -- a held key won't re-fire
-- keypressed by itself, and without the rebuild a spurious lifecycle event
-- parked the player until every direction was re-pressed (#799).
function Game:focus(f)
Input:reset()
if f then Input:reconcile() end
TouchControls:reset()
end
@@ -812,6 +814,7 @@ end
function Game:onResume()
Input:reset()
Input:reconcile()
TouchControls:reset()
-- Chip music may survive NX suspend as a duplicate stream; stop it and let
-- the active screen re-cue on the next frame (hardware audio check: T19).
@@ -827,6 +830,10 @@ end
function Game:recoverInput(event, joystick)
Input:reset()
-- A hotplug can arrive with no hotplug (macOS Bluetooth re-enumeration),
-- and the blanket reset above also drops unrelated keyboard holds; put
-- back whatever is still physically down (#799).
Input:reconcile()
TouchControls:reset()
local SwitchDiagnostics = require("src.debug.SwitchDiagnostics")
if SwitchDiagnostics.isEnabled() then