Skip to content

Commit 4e72b8d

Browse files
committed
Merge branch 'develop' into joao/editor-runtime-split-for-module
2 parents 8ef8139 + c335859 commit 4e72b8d

21 files changed

Lines changed: 1444 additions & 755 deletions

Assets/Tests/InputSystem/APIVerificationTests.cs

Lines changed: 186 additions & 12 deletions
Large diffs are not rendered by default.

Assets/Tests/InputSystem/CoreTests_Actions.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,9 @@ public void Actions_DoNotGetTriggeredByEditorUpdates()
631631

632632
using (var trace = new InputActionTrace(action))
633633
{
634-
runtime.PlayerFocusLost();
634+
ScheduleFocusChangedEvent(applicationHasFocus: false);
635+
InputSystem.Update(InputUpdateType.Dynamic);
636+
635637
Set(gamepad.leftTrigger, 0.123f, queueEventOnly: true);
636638
InputSystem.Update(InputUpdateType.Editor);
637639

@@ -661,13 +663,13 @@ public void Actions_DoNotGetTriggeredByOutOfFocusEventInEditor(InputSettings.Bac
661663
// could just rely on order of event. Which means this test work for a fixed timestamp and it should
662664
// changed accordingly.
663665
currentTime += 1.0f;
664-
runtime.PlayerFocusLost();
666+
ScheduleFocusChangedEvent(applicationHasFocus: false);
665667
currentTime += 1.0f;
666668
// Queuing an event like it would be in the editor when the GameView is out of focus.
667669
Set(mouse.position, new Vector2(0.234f, 0.345f) , queueEventOnly: true);
668670
currentTime += 1.0f;
669671
// Gaining focus like it would happen in the editor when the GameView regains focus.
670-
runtime.PlayerFocusGained();
672+
ScheduleFocusChangedEvent(applicationHasFocus: true);
671673
currentTime += 1.0f;
672674
// This emulates a device sync that happens when the player regains focus through an IOCTL command.
673675
// That's why it also has it's time incremented.
@@ -720,14 +722,15 @@ public void Actions_TimeoutsDoNotGetTriggeredInEditorUpdates()
720722

721723
trace.Clear();
722724

723-
runtime.PlayerFocusLost();
725+
ScheduleFocusChangedEvent(applicationHasFocus: false);
726+
InputSystem.Update(InputUpdateType.Dynamic);
724727
currentTime = 10;
725728

726729
InputSystem.Update(InputUpdateType.Editor);
727730

728731
Assert.That(trace, Is.Empty);
729732

730-
runtime.PlayerFocusGained();
733+
ScheduleFocusChangedEvent(applicationHasFocus: true);
731734
InputSystem.Update(InputUpdateType.Dynamic);
732735

733736
actions = trace.ToArray();

Assets/Tests/InputSystem/CoreTests_Devices.cs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using UnityEngine.Scripting;
2020
using UnityEngine.TestTools;
2121
using UnityEngine.TestTools.Utils;
22+
using UnityEngineInternal.Input;
2223
using Gyroscope = UnityEngine.InputSystem.Gyroscope;
2324
using UnityEngine.TestTools.Constraints;
2425
using Is = NUnit.Framework.Is;
@@ -1522,7 +1523,7 @@ public void Devices_CanReconnectDevice_WhenDisconnectedWhileAppIsOutOfFocus()
15221523
Assert.That(device, Is.Not.Null);
15231524

15241525
// Loose focus.
1525-
runtime.PlayerFocusLost();
1526+
ScheduleFocusChangedEvent(applicationHasFocus: false);
15261527
InputSystem.Update();
15271528

15281529
// Disconnect.
@@ -1534,7 +1535,7 @@ public void Devices_CanReconnectDevice_WhenDisconnectedWhileAppIsOutOfFocus()
15341535
Assert.That(InputSystem.devices, Is.Empty);
15351536

15361537
// Regain focus.
1537-
runtime.PlayerFocusGained();
1538+
ScheduleFocusChangedEvent(applicationHasFocus: true);
15381539
InputSystem.Update();
15391540

15401541
var newDeviceId = runtime.ReportNewInputDevice(deviceDesc);
@@ -4604,7 +4605,13 @@ void DeviceChangeCallback(InputDevice device, InputDeviceChange change)
46044605
InputSystem.onDeviceChange += DeviceChangeCallback;
46054606

46064607
var eventCount = 0;
4607-
InputSystem.onEvent += (eventPtr, _) => ++ eventCount;
4608+
InputSystem.onEvent += (eventPtr, _) =>
4609+
{
4610+
// Focus events will always be processed no matter the state
4611+
// Since the test relies on counting events based on state, dont count focus events
4612+
if (eventPtr.data->type != (FourCC)FocusConstants.kEventType)
4613+
++eventCount;
4614+
};
46084615

46094616
Assert.That(trackedDevice.enabled, Is.True);
46104617
Assert.That(mouse.enabled, Is.True);
@@ -4647,7 +4654,8 @@ void DeviceChangeCallback(InputDevice device, InputDeviceChange change)
46474654
}
46484655

46494656
// Lose focus.
4650-
runtime.PlayerFocusLost();
4657+
ScheduleFocusChangedEvent(applicationHasFocus: false);
4658+
InputSystem.Update(InputUpdateType.Dynamic);
46514659

46524660
Assert.That(sensor.enabled, Is.False);
46534661
Assert.That(disabledDevice.enabled, Is.False);
@@ -5068,7 +5076,8 @@ void DeviceChangeCallback(InputDevice device, InputDeviceChange change)
50685076
commands.Clear();
50695077

50705078
// Regain focus.
5071-
runtime.PlayerFocusGained();
5079+
ScheduleFocusChangedEvent(applicationHasFocus: true);
5080+
InputSystem.Update(InputUpdateType.Dynamic);
50725081

50735082
Assert.That(sensor.enabled, Is.False);
50745083
Assert.That(disabledDevice.enabled, Is.False);
@@ -5275,13 +5284,10 @@ void DeviceChangeCallback(InputDevice device, InputDeviceChange change)
52755284
"Sync Gamepad", "Sync Joystick",
52765285
"Sync TrackedDevice", "Sync TrackedDevice2",
52775286
"Sync Mouse", "Sync Mouse2", "Sync Mouse3",
5278-
"Sync Keyboard", "Reset Joystick"
5279-
}));
5280-
// Enabled devices that don't support syncs get reset.
5281-
Assert.That(changes, Is.EquivalentTo(new[]
5282-
{
5283-
"SoftReset Mouse1", "SoftReset Mouse3", "HardReset Joystick", "SoftReset TrackedDevice2"
5287+
"Sync Keyboard"
52845288
}));
5289+
// Enabled devices that don't support syncs dont get reset for Ignore Focus as we do not want to cancel any actions.
5290+
Assert.That(changes, Is.Empty);
52855291
break;
52865292
}
52875293
}
@@ -5318,7 +5324,13 @@ public void Devices_CanSkipProcessingEventsWhileInBackground()
53185324
Assert.That(performedCount, Is.EqualTo(1));
53195325

53205326
// Lose focus
5321-
runtime.PlayerFocusLost();
5327+
ScheduleFocusChangedEvent(applicationHasFocus: false);
5328+
#if UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS
5329+
// in the new system, we have to process the focus event to update the state of the devices.
5330+
// In the old system, this wouldn't work and would make the test fal
5331+
InputSystem.Update();
5332+
#endif
5333+
53225334
Assert.That(gamepad.enabled, Is.False);
53235335

53245336
// Queue an event while in the background. We don't want to see this event to be processed once focus
@@ -5329,7 +5341,7 @@ public void Devices_CanSkipProcessingEventsWhileInBackground()
53295341
InputSystem.Update();
53305342

53315343
// Gain focus
5332-
runtime.PlayerFocusGained();
5344+
ScheduleFocusChangedEvent(applicationHasFocus: true);
53335345

53345346
// Run update to try process events accordingly once focus is gained
53355347
InputSystem.Update();

Assets/Tests/InputSystem/CoreTests_Editor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,7 +2720,8 @@ public void Editor_CanForceKeyboardAndMouseInputToGameViewWithoutFocus()
27202720
var keyboard = InputSystem.AddDevice<Keyboard>();
27212721
var mouse = InputSystem.AddDevice<Mouse>();
27222722

2723-
runtime.PlayerFocusLost();
2723+
ScheduleFocusChangedEvent(applicationHasFocus: false);
2724+
InputSystem.Update(InputUpdateType.Dynamic);
27242725

27252726
Assert.That(keyboard.enabled, Is.True);
27262727
Assert.That(mouse.enabled, Is.True);
@@ -3016,7 +3017,8 @@ public void Editor_LeavingPlayMode_ReenablesAllDevicesTemporarilyDisabledDueToFo
30163017
Set(mouse.position, new Vector2(123, 234));
30173018
Press(gamepad.buttonSouth);
30183019

3019-
runtime.PlayerFocusLost();
3020+
ScheduleFocusChangedEvent(applicationHasFocus: false);
3021+
InputSystem.Update(InputUpdateType.Dynamic);
30203022

30213023
Assert.That(gamepad.enabled, Is.False);
30223024

Assets/Tests/InputSystem/CoreTests_State.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,9 @@ public void State_CanSetUpMonitorsForStateChanges_InEditor()
704704
InputState.AddChangeMonitor(gamepad.leftStick,
705705
(control, time, eventPtr, monitorIndex) => monitorFired = true);
706706

707-
runtime.PlayerFocusLost();
707+
ScheduleFocusChangedEvent(applicationHasFocus: false);
708+
InputSystem.Update(InputUpdateType.Dynamic);
709+
708710
Set(gamepad.leftStick, new Vector2(0.123f, 0.234f), queueEventOnly: true);
709711
InputSystem.Update(InputUpdateType.Editor);
710712

@@ -1676,7 +1678,9 @@ public void State_RecordingHistory_ExcludesEditorInputByDefault()
16761678
{
16771679
history.StartRecording();
16781680

1679-
runtime.PlayerFocusLost();
1681+
ScheduleFocusChangedEvent(applicationHasFocus: false);
1682+
InputSystem.Update(InputUpdateType.Dynamic);
1683+
16801684
Set(gamepad.leftTrigger, 0.123f, queueEventOnly: true);
16811685
InputSystem.Update(InputUpdateType.Editor);
16821686

@@ -1696,7 +1700,9 @@ public void State_RecordingHistory_CanCaptureEditorInput()
16961700
history.updateMask = InputUpdateType.Editor;
16971701
history.StartRecording();
16981702

1699-
runtime.PlayerFocusLost();
1703+
ScheduleFocusChangedEvent(applicationHasFocus: false);
1704+
InputSystem.Update(InputUpdateType.Dynamic);
1705+
17001706
Set(gamepad.leftTrigger, 0.123f, queueEventOnly: true);
17011707
InputSystem.Update(InputUpdateType.Editor);
17021708

Assets/Tests/InputSystem/Plugins/EnhancedTouchTests.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,10 @@ public void EnhancedTouch_SupportsEditorUpdates(InputSettings.UpdateMode updateM
158158
Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
159159

160160
// And make sure we're not seeing the data in the editor.
161-
runtime.PlayerFocusLost();
161+
ScheduleFocusChangedEvent(applicationHasFocus: false);
162162
InputSystem.Update(InputUpdateType.Editor);
163163

164164
Assert.That(Touch.activeTouches, Is.Empty);
165-
166165
// Feed some data into editor state.
167166
BeginTouch(2, new Vector2(0.234f, 0.345f), queueEventOnly: true);
168167
InputSystem.Update(InputUpdateType.Editor);
@@ -171,8 +170,25 @@ public void EnhancedTouch_SupportsEditorUpdates(InputSettings.UpdateMode updateM
171170
Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(2));
172171

173172
// Switch back to player.
174-
runtime.PlayerFocusGained();
175-
InputSystem.Update();
173+
ScheduleFocusChangedEvent(applicationHasFocus: true);
174+
175+
// Explicitly schedule the player's configured update type rather than relying on the default.
176+
// Without explicit scheduling, defaultUpdateType would be Editor (since focus has not yet been
177+
// gained during update), causing the editor buffer to be used instead of the player buffer,
178+
// which would retrieve the wrong active touch. A proper fix would require removing defaultUpdateType
179+
// and splitting player/editor update loops into separate methods.
180+
switch (updateMode)
181+
{
182+
case InputSettings.UpdateMode.ProcessEventsInDynamicUpdate:
183+
InputSystem.Update(InputUpdateType.Dynamic);
184+
break;
185+
case InputSettings.UpdateMode.ProcessEventsInFixedUpdate:
186+
InputSystem.Update(InputUpdateType.Fixed);
187+
break;
188+
case InputSettings.UpdateMode.ProcessEventsManually:
189+
InputSystem.Update(InputUpdateType.Manual);
190+
break;
191+
}
176192

177193
Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
178194
Assert.That(Touch.activeTouches[0].touchId, Is.EqualTo(1));
@@ -1160,7 +1176,7 @@ public void EnhancedTouch_ActiveTouchesGetCanceledOnFocusLoss_WithRunInBackgroun
11601176
Assert.That(Touch.activeTouches, Has.Count.EqualTo(1));
11611177
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began));
11621178

1163-
runtime.PlayerFocusLost();
1179+
ScheduleFocusChangedEvent(applicationHasFocus: false);
11641180

11651181
if (runInBackground)
11661182
{
@@ -1171,7 +1187,7 @@ public void EnhancedTouch_ActiveTouchesGetCanceledOnFocusLoss_WithRunInBackgroun
11711187
else
11721188
{
11731189
// When not running in the background, the same thing happens but only on focus gain.
1174-
runtime.PlayerFocusGained();
1190+
ScheduleFocusChangedEvent(applicationHasFocus: true);
11751191
InputSystem.Update();
11761192
}
11771193

Assets/Tests/InputSystem/Plugins/InputForUITests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -715,19 +715,19 @@ public void UIActions_DoNotGetTriggeredByOutOfFocusEventInEditor(InputSettings.B
715715
currentTime += 1.0f;
716716
Update();
717717
currentTime += 1.0f;
718-
runtime.PlayerFocusLost();
718+
ScheduleFocusChangedEvent(applicationHasFocus: false);
719719
currentTime += 1.0f;
720720
Set(mouse.position, outOfFocusPosition , queueEventOnly: true);
721721
currentTime += 1.0f;
722-
runtime.PlayerFocusGained();
722+
ScheduleFocusChangedEvent(applicationHasFocus: true);
723723
currentTime += 1.0f;
724724
Set(mouse.position, focusPosition, queueEventOnly: true);
725725
currentTime += 1.0f;
726726

727727
// We call specific updates to simulate editor behavior when regaining focus.
728728
InputSystem.Update(InputUpdateType.Editor);
729729
Assert.AreEqual(0, m_InputForUIEvents.Count);
730-
InputSystem.Update();
730+
InputSystem.Update(InputUpdateType.Dynamic);
731731
// Calling the event provider update after we call InputSystem updates so that we trigger InputForUI events
732732
EventProvider.NotifyUpdate();
733733

Assets/Tests/InputSystem/Plugins/UITests.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4128,7 +4128,9 @@ public IEnumerator UI_WhenAppLosesAndRegainsFocus_WhileUIButtonIsPressed_UIButto
41284128

41294129
scene.leftChildReceiver.events.Clear();
41304130

4131-
runtime.PlayerFocusLost();
4131+
ScheduleFocusChangedEvent(applicationHasFocus: false);
4132+
InputSystem.Update(InputUpdateType.Dynamic);
4133+
41324134
if (canRunInBackground)
41334135
Assert.That(clickCanceled, Is.EqualTo(0));
41344136
else
@@ -4139,7 +4141,9 @@ public IEnumerator UI_WhenAppLosesAndRegainsFocus_WhileUIButtonIsPressed_UIButto
41394141
Assert.That(scene.eventSystem.hasFocus, Is.False);
41404142
Assert.That(clicked, Is.False);
41414143

4142-
runtime.PlayerFocusGained();
4144+
ScheduleFocusChangedEvent(applicationHasFocus: true);
4145+
InputSystem.Update(InputUpdateType.Dynamic);
4146+
41434147
scene.eventSystem.SendMessage("OnApplicationFocus", true);
41444148

41454149
yield return null;
@@ -4168,11 +4172,13 @@ public IEnumerator UI_WhenAppLosesAndRegainsFocus_WhileUIButtonIsPressed_UIButto
41684172

41694173
// Ensure that losing and regaining focus doesn't cause the next click to be ignored
41704174
clicked = false;
4171-
runtime.PlayerFocusLost();
4175+
ScheduleFocusChangedEvent(applicationHasFocus: false);
4176+
InputSystem.Update(InputUpdateType.Dynamic);
41724177
scene.eventSystem.SendMessage("OnApplicationFocus", false);
41734178
yield return null;
41744179

4175-
runtime.PlayerFocusGained();
4180+
ScheduleFocusChangedEvent(applicationHasFocus: true);
4181+
InputSystem.Update(InputUpdateType.Dynamic);
41764182
scene.eventSystem.SendMessage("OnApplicationFocus", true);
41774183
yield return null;
41784184

Assets/Tests/InputSystem/Plugins/UserTests.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,8 +1268,21 @@ public void Users_DoNotReactToEditorInput()
12681268
++InputUser.listenForUnpairedDeviceActivity;
12691269
InputUser.onUnpairedDeviceUsed += (control, eventPtr) => Assert.Fail("Should not react!");
12701270

1271-
runtime.PlayerFocusLost();
1272-
1271+
// Process the focus event before pressing the button to ensure correct update type selection.
1272+
//
1273+
// Issue: When Update() is called without an update type, it uses defaultUpdateType which checks
1274+
// focus state. However, scheduled focus events aren't processed until an update runs, so the
1275+
// focus check sees stale state and selects the wrong update type.
1276+
//
1277+
// Workaround: Run a dynamic update first to process the focus event, ensuring the subsequent
1278+
// button press correctly uses editor update type.
1279+
//
1280+
// Alternative: Queue the button press and explicitly call an editor update to process both events.
1281+
//
1282+
// Proper fix: Remove defaultUpdateType and split editor/player loops, or always specify the
1283+
// update type explicitly when calling Update().
1284+
ScheduleFocusChangedEvent(applicationHasFocus: false);
1285+
InputSystem.Update(InputUpdateType.Dynamic);
12731286
Press(gamepad.buttonSouth);
12741287

12751288
Assert.That(gamepad.buttonSouth.isPressed, Is.True);

Assets/Tests/InputSystem/Unity.InputSystem.Tests.asmdef

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@
7171
"name": "Unity",
7272
"expression": "6000.3.0a6",
7373
"define": "UNITY_INPUT_SYSTEM_PLATFORM_POLLING_FREQUENCY"
74+
},
75+
{
76+
"name": "Unity",
77+
"expression": "6000.5.0a8",
78+
"define": "UNITY_INPUTSYSTEM_SUPPORTS_FOCUS_EVENTS"
7479
}
7580
],
7681
"noEngineReferences": false

0 commit comments

Comments
 (0)