Skip to content

Commit 57cb44e

Browse files
Merge branch 'develop' into input/uitoolkit-input-asset
2 parents 4b8f6a6 + 01a0d7a commit 57cb44e

26 files changed

Lines changed: 1906 additions & 899 deletions

Assets/Tests/InputSystem/APIVerificationTests.cs

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

Assets/Tests/InputSystem/CoreTests_Actions.cs

Lines changed: 57 additions & 12 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();
@@ -1401,6 +1404,45 @@ public void Actions_ValueActionsEnabledInOnEvent_DoNotReactToCurrentStateOfContr
14011404
}
14021405
}
14031406

1407+
// Regression test for UUM-100125.
1408+
[Test]
1409+
[Category("Actions")]
1410+
public void Actions_InitialStateCheckAfterConfigurationChange_DoesNotTriggerForInactiveTouch()
1411+
{
1412+
var touchscreen = InputSystem.AddDevice<Touchscreen>();
1413+
var action = new InputAction(type: InputActionType.Value, binding: "<Touchscreen>/primaryTouch/position");
1414+
action.Enable();
1415+
1416+
// Run the first initial state check from enabling the action.
1417+
InputSystem.Update();
1418+
1419+
using (var trace = new InputActionTrace(action))
1420+
{
1421+
BeginTouch(1, new Vector2(123, 234));
1422+
EndTouch(1, new Vector2(345, 456));
1423+
1424+
Assert.That(touchscreen.primaryTouch.isInProgress, Is.False);
1425+
Assert.That(touchscreen.primaryTouch.position.ReadValue(), Is.Not.EqualTo(default(Vector2)));
1426+
1427+
trace.Clear();
1428+
1429+
// Configuration change causes full re-resolve and schedules initial state check.
1430+
InputSystem.QueueConfigChangeEvent(touchscreen);
1431+
InputSystem.Update();
1432+
InputSystem.Update();
1433+
1434+
// Full re-resolve may cancel the current action state. What must NOT happen is a synthetic
1435+
// Started/Performed pair from persisted inactive touch state.
1436+
Assert.AreEqual(1, trace.count);
1437+
foreach (var eventPtr in trace)
1438+
{
1439+
// The trace should only contain a Canceled event for the action.
1440+
Assert.AreEqual(InputActionPhase.Canceled, eventPtr.phase,
1441+
$"inactive touch state should not produce action callbacks, but received {eventPtr.phase}.");
1442+
}
1443+
}
1444+
}
1445+
14041446
// https://fogbugz.unity3d.com/f/cases/1192972/
14051447
[Test]
14061448
[Category("Actions")]
@@ -12481,17 +12523,20 @@ public void Actions_WithMultipleCompositeBindings_WithoutEvaluateMagnitude_Works
1248112523

1248212524
// Now when enabling actionMap ..
1248312525
actionMap.Enable();
12484-
// On the following update we will trigger OnBeforeUpdate which will rise started/performed
12485-
// from InputActionState.OnBeforeInitialUpdate as controls are "actuated"
12526+
// Inactive touches (ended before action was enabled) must NOT produce started/performed from
12527+
// OnBeforeInitialUpdate. Their persisted state (position, touchId) is non-default due to
12528+
// dontReset, but only TouchControl.isInProgress should be considered for initial-state check.
12529+
// Related to UUM-100125 and Actions_InitialStateCheckAfterConfigurationChange_DoesNotTriggerForInactiveTouch.
1248612530
InputSystem.Update();
12487-
Assert.That(values.Count, Is.EqualTo(prepopulateTouchesBeforeEnablingAction ? 2 : 0)); // started+performed arrive from OnBeforeUpdate
12531+
Assert.That(values.Count, Is.EqualTo(0));
1248812532
values.Clear();
1248912533

12490-
// Now subsequent touches should not be ignored
1249112534
BeginTouch(200, new Vector2(1, 1));
12492-
Assert.That(values.Count, Is.EqualTo(1));
12493-
Assert.That(values[0].InputId, Is.EqualTo(200));
12494-
Assert.That(values[0].Position, Is.EqualTo(new Vector2(1, 1)));
12535+
// If prepopulated, action was never actuated (synthetic initial-check is suppressed),
12536+
// so BeginTouch fires started+performed (2 events).
12537+
Assert.That(values.Count, Is.EqualTo(prepopulateTouchesBeforeEnablingAction ? 2 : 1));
12538+
Assert.That(values[values.Count - 1].InputId, Is.EqualTo(200));
12539+
Assert.That(values[values.Count - 1].Position, Is.EqualTo(new Vector2(1, 1)));
1249512540
}
1249612541

1249712542
// FIX: This test is currently checking if shortcut support is enabled by testing that the unwanted behaviour exists.

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

0 commit comments

Comments
 (0)