@@ -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+ // Decide to skip events based on timing or focus state
3329+ if ( ShouldDiscardEventInEditor ( 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,60 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
37063699 m_CurrentUpdate = default ;
37073700 }
37083701
3702+ #if UNITY_EDITOR
3703+ /// <summary>
3704+ /// Determines if an event should be discarded based on timing or focus state.
3705+ /// </summary>
3706+ /// <param name="eventType">The type of the current event</param>
3707+ /// <param name="eventTime">The internal time of the current event</param>
3708+ /// <param name="updateType">The current update type</param>
3709+ /// <returns>True if the event should be discarded, false otherwise.</returns>
3710+ private bool ShouldDiscardEventInEditor ( FourCC eventType , double eventTime , InputUpdateType updateType )
3711+ {
3712+ // Check if this is an event that occurred during edit mode transition
3713+ if ( ShouldDiscardEditModeTransitionEvent ( eventType , eventTime , updateType ) )
3714+ return true ;
3715+
3716+ // Check if this is an out-of-focus event that should be discarded
3717+ if ( ShouldDiscardOutOfFocusEvent ( eventTime ) )
3718+ return true ;
3719+
3720+ return false ;
3721+ }
3722+
3723+ /// <summary>
3724+ /// In the editor, we discard all input events that occur in-between exiting edit mode and having
3725+ /// entered play mode as otherwise we'll spill a bunch of UI events that have occurred while the
3726+ /// UI was sort of neither in this mode nor in that mode. This would usually lead to the game receiving
3727+ /// an accumulation of spurious inputs right in one of its first updates.
3728+ ///
3729+ /// NOTE: There's a chance the solution here will prove inadequate on the long run. We may do things
3730+ /// here such as throwing partial touches away and then letting the rest of a touch go through.
3731+ /// Could be that ultimately we need to issue a full reset of all devices at the beginning of
3732+ /// play mode in the editor.
3733+ /// </summary>
3734+ private bool ShouldDiscardEditModeTransitionEvent ( FourCC eventType , double eventTime , InputUpdateType updateType )
3735+ {
3736+ return ( eventType == StateEvent . Type || eventType == DeltaStateEvent . Type ) &&
3737+ ( updateType & InputUpdateType . Editor ) == 0 &&
3738+ InputSystem . s_SystemObject . exitEditModeTime > 0 &&
3739+ eventTime >= InputSystem . s_SystemObject . exitEditModeTime &&
3740+ ( eventTime < InputSystem . s_SystemObject . enterPlayModeTime ||
3741+ InputSystem . s_SystemObject . enterPlayModeTime == 0 ) ;
3742+ }
3743+
3744+ /// <summary>
3745+ /// Checks if an event should be discarded because it occurred while out of focus, under specific settings.
3746+ /// </summary>
3747+ private bool ShouldDiscardOutOfFocusEvent ( double eventTime )
3748+ {
3749+ if ( gameHasFocus && m_Settings . backgroundBehavior != InputSettings . BackgroundBehavior . IgnoreFocus )
3750+ return m_DiscardOutOfFocusEvents && eventTime < m_FocusRegainedTime ;
3751+ return false ;
3752+ }
3753+
3754+ #endif
3755+
37093756 bool AreMaximumEventBytesPerUpdateExceeded ( uint totalEventBytesProcessed )
37103757 {
37113758 if ( m_Settings . maxEventBytesPerUpdate > 0 &&
0 commit comments