You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Root cause
The action system is driven by state change events. We can see different eventIds for the handled event vs the
action‑triggering event, so the action was coming from a separate input event.
Fix
While dispatching InputSystem.onEvent, stop calling remaining listeners once handled becomes true.
When an event is handled (policy = SuppressStateUpdates), temporarily suppress action processing for that device
for the rest of the update (and next update).
In InputActionState, skip processing control changes if the device is suppressed.
Testing status & QA
Manually verified using repro project + dualsense controller.
Overall Product Risks
Complexity: Low
Halo Effect: Low
Comments to reviewers
Only applies when policy is SuppressStateUpdates and a listener explicitly sets handled = true.
Normal input flow remains unchanged.
This simply makes “handled” cover the entire physical press, even if it arrives as multiple events.
Checklist
Before review:
Changelog entry added.
Explains the change in Changed, Fixed, Added sections.
For API change contains an example snippet and/or migration example.
JIRA ticket linked, example (case %%). If it is a private issue, just add the case ID without a link.
Here are some key observations to aid the review process:
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
The PR modifies core event loop logic and input suppression mechanisms, requiring a careful check of the event processing flow and potential side effects on input timing and loss.
🏅 Score: 92
The changes effectively address the reported bug by introducing a targeted suppression mechanism for handled events. The logic is sound, side effects are minimized by the policy check, and a relevant reproduction test is included.
In ShouldSuppressActionsForDevice, m_SuppressActionsForDeviceUpdate is defined as uint[] and InputUpdate.s_UpdateStepCount is a uint. Casting these values to int before comparison is unnecessary. While the wrap-around arithmetic likely holds for both signed and unsigned integers in this context, maintaining uint is cleaner and avoids potential confusion regarding overflow behavior.
Latest suggestions up to b94a66b
Explore these optional code suggestions:
Category
Suggestion
Impact
Possible issue
Ignore uninitialized zero values in check
The m_SuppressActionsForDeviceUpdate array entries default to 0. This causes ShouldSuppressActionsForDevice to incorrectly return true for all uninitialized entries during updates 0 and 1 (because 0 == 0 and 0 + 1 == 1), leading to incorrect action suppression at startup. Treat 0 as an uninitialized value to avoid this issue.
Why: The default value of elements in m_SuppressActionsForDeviceUpdate is 0. At the start of the application (when s_UpdateStepCount is 0 or 1), this default value satisfies the suppression condition (0 == 0 or 0 + 1 == 1), causing actions from uninitialized devices to be suppressed incorrectly. Treating 0 as 'uninitialized' prevents this false positive.
Medium
More suggestions
🤖 Helpful? Please react with 👍/👎 | Questions❓Please reach out in Slack #ask-u-pr
The marker.End() call is currently unreachable in the return false path and missing in the return true path, which will cause profiler imbalances. Ensure marker.End() is called before returning in both scenarios.
Why: The suggested fix addresses a critical issue where marker.End() is skipped when returning early, and the existing marker.End() call is unreachable code. This ensures proper profiler balancing.
High
General
Prevent incorrect action suppression on startup
The m_SuppressActionsForDeviceUpdate array initializes with zeros. If s_UpdateStepCount is 0 or 1 at startup, this logic will mistakenly suppress actions for all devices (since 0 or 0+1 will match). Ignore the default 0 value to prevent this.
var lastUpdate = (int)m_SuppressActionsForDeviceUpdate[deviceIndex];
+ if (lastUpdate == 0)+ return false;+
var currentUpdate = (int)InputUpdate.s_UpdateStepCount;
return lastUpdate == currentUpdate || lastUpdate + 1 == currentUpdate;
Suggestion importance[1-10]: 8
__
Why: The suggestion correctly identifies a logic flaw where the default zero-initialization of the m_SuppressActionsForDeviceUpdate array could cause false positives for action suppression during the initial updates (steps 0 and 1).
AswinRajGopal
changed the title
Fix handled events still triggering actions when switching PlayerInput device
"FIX": handled events still triggering actions when switching PlayerInput device
Jan 30, 2026
AswinRajGopal
changed the title
"FIX": handled events still triggering actions when switching PlayerInput device
FIX: handled events still triggering actions when switching PlayerInput device
Jan 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Bug: https://issuetracker.unity3d.com/issues/setting-inputeventptr-dot-handled-to-true-does-not-prevent-actions-from-triggering-when-changing-devices
When
InputUser.onUnpairedDeviceUsedmarkseventPtr.handled= true, we expect no action to fire from that samebutton press.
But on devices like DualSense, a single press can generate multiple input events. The handled flag only stops the
one event, and another event in the same press still triggers the action.
Root cause
The action system is driven by state change events. We can see different eventIds for the handled event vs the
action‑triggering event, so the action was coming from a separate input event.
Fix
InputSystem.onEvent, stop calling remaining listeners once handled becomes true.for the rest of the update (and next update).
InputActionState, skip processing control changes if the device is suppressed.Testing status & QA
Manually verified using repro project + dualsense controller.
Overall Product Risks
Comments to reviewers
SuppressStateUpdatesand a listener explicitly sets handled = true.Checklist
Before review:
Changed,Fixed,Addedsections.Area_CanDoX,Area_CanDoX_EvenIfYIsTheCase,Area_WhenIDoX_AndYHappens_ThisIsTheResult.During merge:
NEW: ___.FIX: ___.DOCS: ___.CHANGE: ___.RELEASE: 1.1.0-preview.3.