@@ -2244,6 +2244,8 @@ internal struct AvailableDevice
2244
2244
private bool m_NativeBeforeUpdateHooked ;
2245
2245
private bool m_HaveDevicesWithStateCallbackReceivers ;
2246
2246
private bool m_HasFocus ;
2247
+ private bool m_DiscardOutOfFocusEvents ;
2248
+ private double m_FocusRegainedTime ;
2247
2249
private InputEventStream m_InputEventStream ;
2248
2250
2249
2251
// 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)
3032
3034
}
3033
3035
else
3034
3036
{
3037
+ m_DiscardOutOfFocusEvents = true ;
3038
+ m_FocusRegainedTime = m_Runtime . currentTime ;
3035
3039
// On focus gain, reenable and sync devices.
3036
3040
for ( var i = 0 ; i < m_DevicesCount ; ++ i )
3037
3041
{
@@ -3319,23 +3323,10 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
3319
3323
}
3320
3324
#endif
3321
3325
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
+
3331
3327
#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 ) )
3339
3330
{
3340
3331
m_InputEventStream . Advance ( false ) ;
3341
3332
continue ;
@@ -3678,6 +3669,8 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
3678
3669
break ;
3679
3670
}
3680
3671
3672
+ m_DiscardOutOfFocusEvents = false ;
3673
+
3681
3674
m_Metrics . totalEventProcessingTime +=
3682
3675
( ( double ) ( Stopwatch . GetTimestamp ( ) - processingStartTime ) ) / Stopwatch . Frequency ;
3683
3676
m_Metrics . totalEventLagTime += totalEventLag ;
@@ -3706,6 +3699,55 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
3706
3699
m_CurrentUpdate = default ;
3707
3700
}
3708
3701
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
+
3709
3751
bool AreMaximumEventBytesPerUpdateExceeded ( uint totalEventBytesProcessed )
3710
3752
{
3711
3753
if ( m_Settings . maxEventBytesPerUpdate > 0 &&
0 commit comments