@@ -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
+ // Decide to skip events based on timing or focus state
3329
+ if ( ShouldDiscardEventInEditor ( currentEventType , currentEventTimeInternal , updateType ) )
3339
3330
{
3340
3331
m_InputEventStream . Advance ( false ) ;
3341
3332
continue ;
@@ -3695,6 +3686,8 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
3695
3686
throw ;
3696
3687
}
3697
3688
3689
+ m_DiscardOutOfFocusEvents = false ;
3690
+
3698
3691
if ( shouldProcessActionTimeouts )
3699
3692
ProcessStateChangeMonitorTimeouts ( ) ;
3700
3693
@@ -3706,6 +3699,60 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
3706
3699
m_CurrentUpdate = default ;
3707
3700
}
3708
3701
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
+
3709
3756
bool AreMaximumEventBytesPerUpdateExceeded ( uint totalEventBytesProcessed )
3710
3757
{
3711
3758
if ( m_Settings . maxEventBytesPerUpdate > 0 &&
0 commit comments