diff --git a/osu.Framework.Tests/Visual/Input/TestScenePassThroughInputManager.cs b/osu.Framework.Tests/Visual/Input/TestScenePassThroughInputManager.cs index a6bf4f748a..7de2f5014d 100644 --- a/osu.Framework.Tests/Visual/Input/TestScenePassThroughInputManager.cs +++ b/osu.Framework.Tests/Visual/Input/TestScenePassThroughInputManager.cs @@ -132,6 +132,25 @@ public void TestPressKeyThenReleaseWhileDisabled() AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); AddStep("release key", () => InputManager.ReleaseKey(Key.A)); AddAssert("key released", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed); + + AddStep("press key", () => InputManager.PressKey(Key.A)); + AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); + + AddStep("add blocking layer", () => Add(new HandlingBox + { + RelativeSizeAxes = Axes.Both, + OnHandle = _ => true, + })); + + // with a blocking layer existing, the next key press will not be seen by PassThroughInputManager... + AddStep("release key", () => InputManager.ReleaseKey(Key.A)); + AddStep("press key again", () => InputManager.PressKey(Key.A)); + + AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); + + // ...but ensure it'll still release the key regardless of not seeing the corresponding press event (it does that by syncing releases every frame). + AddStep("release key", () => InputManager.ReleaseKey(Key.A)); + AddAssert("key released", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed); } [Test] diff --git a/osu.Framework/Input/PassThroughInputManager.cs b/osu.Framework/Input/PassThroughInputManager.cs index 587993ad9a..82cce921ea 100644 --- a/osu.Framework/Input/PassThroughInputManager.cs +++ b/osu.Framework/Input/PassThroughInputManager.cs @@ -173,6 +173,18 @@ protected override bool Handle(UIEvent e) return false; } + protected override void Update() + { + base.Update(); + + // There are scenarios wherein we cannot receive the release events of pressed inputs. For simplicity, sync every frame. + if (UseParentInput) + { + syncReleasedInputs(); + syncJoystickAxes(); + } + } + /// /// Updates state of any buttons that have been released by parent while was disabled. ///