@@ -2244,6 +2244,8 @@ internal struct AvailableDevice
22442244 private bool m_NativeBeforeUpdateHooked ;
22452245 private bool m_HaveDevicesWithStateCallbackReceivers ;
22462246 private bool m_HasFocus ;
2247+ private bool m_DiscardOutOfFocusEvents ;
2248+ private double m_FocusRegainedTime ;
22472249 private InputEventStream m_InputEventStream ;
22482250
22492251 // We want to sync devices when the editor comes back into focus. Unfortunately, there's no
@@ -3032,6 +3034,8 @@ internal void OnFocusChanged(bool focus)
30323034 }
30333035 else
30343036 {
3037+ m_DiscardOutOfFocusEvents = true ;
3038+ m_FocusRegainedTime = m_Runtime . currentTime ;
30353039 // On focus gain, reenable and sync devices.
30363040 for ( var i = 0 ; i < m_DevicesCount ; ++ i )
30373041 {
@@ -3319,23 +3323,10 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
33193323 }
33203324#endif
33213325
3322- // In the editor, we discard all input events that occur in-between exiting edit mode and having
3323- // entered play mode as otherwise we'll spill a bunch of UI events that have occurred while the
3324- // UI was sort of neither in this mode nor in that mode. This would usually lead to the game receiving
3325- // an accumulation of spurious inputs right in one of its first updates.
3326- //
3327- // NOTE: There's a chance the solution here will prove inadequate on the long run. We may do things
3328- // here such as throwing partial touches away and then letting the rest of a touch go through.
3329- // Could be that ultimately we need to issue a full reset of all devices at the beginning of
3330- // play mode in the editor.
3326+
33313327#if UNITY_EDITOR
3332- if ( ( currentEventType == StateEvent . Type ||
3333- currentEventType == DeltaStateEvent . Type ) &&
3334- ( updateType & InputUpdateType . Editor ) == 0 &&
3335- InputSystem . s_SystemObject . exitEditModeTime > 0 &&
3336- currentEventTimeInternal >= InputSystem . s_SystemObject . exitEditModeTime &&
3337- ( currentEventTimeInternal < InputSystem . s_SystemObject . enterPlayModeTime ||
3338- InputSystem . s_SystemObject . enterPlayModeTime == 0 ) )
3328+ // Skip events that should be discarded based on timing or focus state
3329+ if ( ShouldDiscardEvent ( currentEventType , currentEventTimeInternal , updateType ) )
33393330 {
33403331 m_InputEventStream . Advance ( false ) ;
33413332 continue ;
@@ -3678,6 +3669,8 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
36783669 break ;
36793670 }
36803671
3672+ m_DiscardOutOfFocusEvents = false ;
3673+
36813674 m_Metrics . totalEventProcessingTime +=
36823675 ( ( double ) ( Stopwatch . GetTimestamp ( ) - processingStartTime ) ) / Stopwatch . Frequency ;
36833676 m_Metrics . totalEventLagTime += totalEventLag ;
@@ -3706,6 +3699,55 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
37063699 m_CurrentUpdate = default ;
37073700 }
37083701
3702+ /// <summary>
3703+ /// Determines if an event should be discarded based on timing or focus state.
3704+ /// </summary>
3705+ /// <param name="eventType">The type of the current event</param>
3706+ /// <param name="eventTime">The internal time of the current event</param>
3707+ /// <param name="updateType">The current update type</param>
3708+ /// <returns>True if the event should be discarded, false otherwise.</returns>
3709+ private bool ShouldDiscardEvent ( FourCC eventType , double eventTime , InputUpdateType updateType )
3710+ {
3711+ // Check if this is an event that occurred during edit mode transition
3712+ if ( ShouldDiscardEditModeTransitionEvent ( eventType , eventTime , updateType ) )
3713+ return true ;
3714+
3715+ // // Check if this is an out-of-focus event that should be discarded
3716+ if ( ShouldDiscardOutOfFocusEvent ( eventTime ) )
3717+ return true ;
3718+
3719+ return false ;
3720+ }
3721+
3722+ /// <summary>
3723+ /// In the editor, we discard all input events that occur in-between exiting edit mode and having
3724+ /// entered play mode as otherwise we'll spill a bunch of UI events that have occurred while the
3725+ /// UI was sort of neither in this mode nor in that mode. This would usually lead to the game receiving
3726+ /// an accumulation of spurious inputs right in one of its first updates.
3727+ ///
3728+ /// NOTE: There's a chance the solution here will prove inadequate on the long run. We may do things
3729+ /// here such as throwing partial touches away and then letting the rest of a touch go through.
3730+ /// Could be that ultimately we need to issue a full reset of all devices at the beginning of
3731+ /// play mode in the editor.
3732+ /// </summary>
3733+ private bool ShouldDiscardEditModeTransitionEvent ( FourCC eventType , double eventTime , InputUpdateType updateType )
3734+ {
3735+ return ( eventType == StateEvent . Type || eventType == DeltaStateEvent . Type ) &&
3736+ ( updateType & InputUpdateType . Editor ) == 0 &&
3737+ InputSystem . s_SystemObject . exitEditModeTime > 0 &&
3738+ eventTime >= InputSystem . s_SystemObject . exitEditModeTime &&
3739+ ( eventTime < InputSystem . s_SystemObject . enterPlayModeTime ||
3740+ InputSystem . s_SystemObject . enterPlayModeTime == 0 ) ;
3741+ }
3742+
3743+ /// <summary>
3744+ /// Checks if an event should be discarded because it occurred while out of focus.
3745+ /// </summary>
3746+ private bool ShouldDiscardOutOfFocusEvent ( double eventTime )
3747+ {
3748+ return m_DiscardOutOfFocusEvents && eventTime < m_FocusRegainedTime ;
3749+ }
3750+
37093751 bool AreMaximumEventBytesPerUpdateExceeded ( uint totalEventBytesProcessed )
37103752 {
37113753 if ( m_Settings . maxEventBytesPerUpdate > 0 &&
0 commit comments