From 28a83d693e92d91944af4dccd83e49e6a82093e1 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 23 Sep 2026 13:24:17 +0900 Subject: [PATCH] Pass a cancellation token through mouse press cleanup helpers FinishHeldButton and ReleaseHeldButtonAfterPause were added as async methods without the standard ct parameter, which fails the async cancellation-token guard in StaticFacadeStateGuardTests. The callers still pass CancellationToken.None because the release runs in a finally block and must complete even when the command itself was cancelled. --- .../MouseInputPressActionExecutor.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/MouseInputPressActionExecutor.cs b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/MouseInputPressActionExecutor.cs index 5c344f6c1a..8c6c7b3430 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/MouseInputPressActionExecutor.cs +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/MouseInputPressActionExecutor.cs @@ -85,7 +85,9 @@ internal static async Task ExecuteClick( } finally { - waitOutcome = await FinishHeldButton(mouse, button, waitOutcome, pressWasApplied) + // The release must still run when the command itself was cancelled, or the button stays held. + waitOutcome = await FinishHeldButton( + mouse, button, waitOutcome, pressWasApplied, CancellationToken.None) .ConfigureAwait(false); } @@ -179,7 +181,9 @@ internal static async Task ExecuteLongPress( } finally { - waitOutcome = await FinishHeldButton(mouse, button, waitOutcome, pressWasApplied) + // The release must still run when the command itself was cancelled, or the button stays held. + waitOutcome = await FinishHeldButton( + mouse, button, waitOutcome, pressWasApplied, CancellationToken.None) .ConfigureAwait(false); } @@ -216,7 +220,8 @@ private static async Task FinishHeldButton( Mouse mouse, RuntimeMouseButton button, InputSimulationWaitOutcome waitOutcome, - bool pressWasApplied) + bool pressWasApplied, + CancellationToken ct) { if (waitOutcome == InputSimulationWaitOutcome.TimedOut) { @@ -226,7 +231,7 @@ private static async Task FinishHeldButton( if (waitOutcome == InputSimulationWaitOutcome.Paused && pressWasApplied) { - return await ReleaseHeldButtonAfterPause(mouse, button).ConfigureAwait(false); + return await ReleaseHeldButtonAfterPause(mouse, button, ct).ConfigureAwait(false); } if (pressWasApplied) @@ -235,7 +240,7 @@ private static async Task FinishHeldButton( await MouseInputMainThreadCleanup.ReleaseButtonIfPossible( mouse, button, - CancellationToken.None).ConfigureAwait(false); + ct).ConfigureAwait(false); if (releaseOutcome == InputSimulationWaitOutcome.TimedOut) { MouseInputMainThreadCleanup.ScheduleTimedOutButtonCleanup(mouse, button, false); @@ -245,11 +250,11 @@ await MouseInputMainThreadCleanup.ReleaseButtonIfPossible( // The pause can also arrive while this release is queued, which discards it the same way. if (releaseOutcome == InputSimulationWaitOutcome.Paused) { - return await ReleaseHeldButtonAfterPause(mouse, button).ConfigureAwait(false); + return await ReleaseHeldButtonAfterPause(mouse, button, ct).ConfigureAwait(false); } } - await InputSystemUpdateHelper.SwitchToMainThreadIfNeeded(CancellationToken.None); + await InputSystemUpdateHelper.SwitchToMainThreadIfNeeded(ct); MouseInputState.SetButtonUp(button); if (waitOutcome == InputSimulationWaitOutcome.Paused) { @@ -269,13 +274,14 @@ await MouseInputMainThreadCleanup.ReleaseButtonIfPossible( /// private static async Task ReleaseHeldButtonAfterPause( Mouse mouse, - RuntimeMouseButton button) + RuntimeMouseButton button, + CancellationToken ct) { // Why: ApplyOnNextConfiguredUpdate already disposed the pending apply subscription when it // returned Paused, so a release routed through it again is discarded and the button stays // held until the next command. Writing after that dispose also keeps a queued edge from // re-applying the press once the Editor resumes. - await InputSystemUpdateHelper.SwitchToMainThreadIfNeeded(CancellationToken.None); + await InputSystemUpdateHelper.SwitchToMainThreadIfNeeded(ct); MouseInputMainThreadCleanup.ReleaseButtonImmediatelyAfterPauseInterruption(mouse, button); MouseInputState.SetButtonUp(button); SimulateMouseInputOverlayState.Clear();