Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ internal unsafe interface IInputRuntime
/// command sent to the device.</returns>
long DeviceCommand(int deviceId, InputDeviceCommand* commandPtr);

/// <summary>
/// Initialize the focus state based on current conditions of the application.
/// </summary>
/// <seealso cref="focusState"/>
void InitializeFocusState();

/// <summary>
/// Set delegate to be called on input updates.
/// </summary>
Expand Down Expand Up @@ -113,11 +119,15 @@ internal unsafe interface IInputRuntime
/// <summary>
/// Set delegate to call when the application changes focus.
/// </summary>
/// <seealso cref="Application.onFocusChanged"/>
/// <seealso cref="Application.focusChanged"/>
Action<bool> onPlayerFocusChanged { get; set; }
#endif

/// <summary>
/// Flags indicating various focus states for the application and editor.
/// </summary>
FocusFlags focusState { get; set; }

/// <summary>
/// Is true when the player or game view has focus.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,25 @@ internal enum FocusFlags : ushort
/// <summary>
/// In editor this means the GameView has focus. In a built player this means the player has focus.
/// </summary>
ApplicationFocus = (1 << 0)
ApplicationFocus = (1 << 0),
Comment thread
VeraMommersteeg marked this conversation as resolved.
};

internal partial class InputManager
{
internal void OnFocusChanged(bool focus)
{
// We set this to temporarily override applicationHasFocus before processing the focus change
// as defaultUpdateType is influenced by it. Before returning from this method, clear the
// bool to stop overriding to indicate this manager has finished processing the focus change.
m_IsHandlingFocusChange = true;
m_ApplicationHadFocus = !focus;
Comment thread
chris-massie marked this conversation as resolved.

#if UNITY_EDITOR
SyncAllDevicesWhenEditorIsActivated();

if (!m_Runtime.isInPlayMode)
{
focusState = focus ? FocusFlags.ApplicationFocus : FocusFlags.None;
m_IsHandlingFocusChange = false;
return;
}

Expand All @@ -54,12 +60,11 @@ internal void OnFocusChanged(bool focus)
m_Runtime.runInBackground;
#endif

var backgroundBehavior = m_Settings.backgroundBehavior;
if (backgroundBehavior == InputSettings.BackgroundBehavior.IgnoreFocus && runInBackground)
if (m_Settings.backgroundBehavior == InputSettings.BackgroundBehavior.IgnoreFocus && runInBackground)
{
// If runInBackground is true, no device changes should happen, even when focus is gained. So early out.
// If runInBackground is false, we still want to sync devices when focus is gained. So we need to continue further.
focusState = focus ? FocusFlags.ApplicationFocus : FocusFlags.None;
m_IsHandlingFocusChange = false;
return;
}

Expand Down Expand Up @@ -121,8 +126,7 @@ internal void OnFocusChanged(bool focus)
m_CurrentUpdate = InputUpdateType.None;
#endif

// We set this *after* the block above as defaultUpdateType is influenced by the setting.
focusState = focus ? FocusFlags.ApplicationFocus : FocusFlags.None;
m_IsHandlingFocusChange = false;
}

/// <summary>
Expand Down Expand Up @@ -150,8 +154,6 @@ private bool ShouldFlushEventBuffer()
/// <summary>
/// Determines if we should exit early from event processing without handling events.
/// </summary>
/// <param name="eventBuffer">The current event buffer</param>
/// <param name="canFlushBuffer">Whether the buffer can be flushed</param>
/// <param name="updateType">The current update type</param>
/// <returns>True if we should exit early, false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
54 changes: 20 additions & 34 deletions Packages/com.unity.inputsystem/InputSystem/Runtime/InputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public InputUpdateType defaultUpdateType
// The solution here would be to make update calls explicitly specify the update type and no longer use this property.
if (!m_RunPlayerUpdatesInEditMode && (!gameIsPlaying || !gameHasFocus))
return InputUpdateType.Editor;
#endif
#endif

return m_UpdateMask.GetUpdateTypeForPlayer();
}
Expand All @@ -264,27 +264,6 @@ public InputSettings.ScrollDeltaBehavior scrollDeltaBehavior
}
}

public FocusFlags focusState
{
get
{
#if UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
return m_Runtime.focusState;
#else
return m_FocusState;
#endif
}
set
{
#if UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
if (m_Runtime != null)
m_Runtime.focusState = value;
#else
m_FocusState = value;
#endif
}
}

public float pollingFrequency
{
get
Expand Down Expand Up @@ -557,7 +536,17 @@ internal static void StopEditorEventPassthrough()
#else
true;
#endif
private bool applicationHasFocus => (focusState & FocusFlags.ApplicationFocus) != FocusFlags.None;
private bool applicationHasFocus
{
get
{
#if !UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
if (m_IsHandlingFocusChange)
return m_ApplicationHadFocus;
#endif
return m_Runtime != null ? m_Runtime.isPlayerFocused : Application.isFocused;
}
}

private bool gameHasFocus =>
#if UNITY_EDITOR
Expand Down Expand Up @@ -2027,11 +2016,6 @@ internal void InitializeData()
// we don't know which one the user is going to use. The user
// can manually turn off one of them to optimize operation.
m_UpdateMask = InputUpdateType.Dynamic | InputUpdateType.Fixed;
#if !UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
m_FocusState = Application.isFocused
? m_FocusState | FocusFlags.ApplicationFocus
: m_FocusState & ~FocusFlags.ApplicationFocus;
#endif
#if UNITY_EDITOR
m_EditorIsActive = true;
m_UpdateMask |= InputUpdateType.Editor;
Expand Down Expand Up @@ -2277,9 +2261,7 @@ internal void InstallRuntime(IInputRuntime runtime)
#endif
m_Runtime.pollingFrequency = pollingFrequency;

focusState = m_Runtime.isPlayerFocused
? focusState | FocusFlags.ApplicationFocus
: focusState & ~FocusFlags.ApplicationFocus;
m_Runtime.InitializeFocusState();

// We only hook NativeInputSystem.onBeforeUpdate if necessary.
if (m_BeforeUpdateListeners.length > 0 || m_HaveDevicesWithStateCallbackReceivers)
Expand Down Expand Up @@ -2451,9 +2433,14 @@ internal struct AvailableDevice
private bool m_NativeBeforeUpdateHooked;
private bool m_HaveDevicesWithStateCallbackReceivers;
#if !UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
private FocusFlags m_FocusState = FocusFlags.ApplicationFocus;
private bool m_DiscardOutOfFocusEvents;
private double m_FocusRegainedTime;
// These two bools are used for overriding applicationHasFocus which affects gameHasFocus
// and thus defaultUpdateType. See comments in defaultUpdateType. While processing the
// focus change in the OnFocusChanged method, these are used to temporarily override
// those properties.
private bool m_IsHandlingFocusChange;
private bool m_ApplicationHadFocus;
#endif
private InputEventStream m_InputEventStream;

Expand Down Expand Up @@ -3938,8 +3925,7 @@ private void ProcessDeviceConfigurationEvent(InputDevice device)
private unsafe void ProcessFocusEvent(InputEvent* currentEventReadPtr)
{
var focusEventPtr = (InputFocusEvent*)currentEventReadPtr;
FocusFlags state = focusEventPtr->focusFlags;
focusState = state;
m_Runtime.focusState = focusEventPtr->focusFlags;

#if UNITY_EDITOR
SyncAllDevicesWhenEditorIsActivated();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,22 @@ private bool OnWantsToShutdown()
return true;
}

public void InitializeFocusState()
{
m_FocusState = Application.isFocused
? m_FocusState | FocusFlags.ApplicationFocus
: m_FocusState & ~FocusFlags.ApplicationFocus;
}

#if !UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
private Action<bool> m_FocusChangedMethod;

private void OnFocusChanged(bool focus)
{
m_FocusState = focus
? m_FocusState | FocusFlags.ApplicationFocus
: m_FocusState & ~FocusFlags.ApplicationFocus;

m_FocusChangedMethod(focus);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,19 @@ public unsafe long DeviceCommand(int deviceId, InputDeviceCommand* commandPtr)
}
}

public void InitializeFocusState()
{
// Testing should start in focus and individual tests can change this test runtime to lose focus
// by calling InvokePlayerFocusChanged via InputTestFixture.ScheduleFocusChangedEvent.
m_FocusState = FocusFlags.ApplicationFocus;
}

public void InvokePlayerFocusChanged(bool newFocusState)
{
m_FocusState = newFocusState
? m_FocusState | FocusFlags.ApplicationFocus
: m_FocusState & ~FocusFlags.ApplicationFocus;

onPlayerFocusChanged?.Invoke(newFocusState);
}

Expand Down
Loading