diff --git a/Assets/Tests/InputSystem.Editor/InputActionsEditorTests.cs b/Assets/Tests/InputSystem.Editor/InputActionsEditorTests.cs index 5d31d5e306..96a51f9a7a 100644 --- a/Assets/Tests/InputSystem.Editor/InputActionsEditorTests.cs +++ b/Assets/Tests/InputSystem.Editor/InputActionsEditorTests.cs @@ -19,6 +19,7 @@ public override void OneTimeSetUp() { base.OneTimeSetUp(); m_Asset = AssetDatabaseUtils.CreateAsset(); + m_Asset.AddControlScheme(new InputControlScheme("test")); var actionMap = m_Asset.AddActionMap("First Name"); m_Asset.AddActionMap("Second Name"); m_Asset.AddActionMap("Third Name"); @@ -234,5 +235,28 @@ public IEnumerator CanRenameAction() // Check on the asset side Assert.That(m_Window.currentAssetInEditor.actionMaps[0].actions[1].name, Is.EqualTo("New Name")); } + + /// + /// ISXB-1607 + /// Fix an out of range exception when pressing undo after creating and editing a new control scheme. + /// + /// + [UnityTest] + [Ignore("Currently this is difficult to test, Darren - re-visit once we have converted the advanced dropdown to UIToolkit")] + public IEnumerator CanUndoActionMap_ControlSchemeEdit() + { + var controlSchemeToolbarMenu = m_Window.rootVisualElement.Q("control-schemes-toolbar-menu"); + + // changing the selection triggers a state change, wait for the scheduler to process the frame + yield return WaitForSchedulerLoop(); + yield return WaitForNotDirty(); + + SimulateClickOn(controlSchemeToolbarMenu); + + yield return WaitForSchedulerLoop(); + yield return WaitForNotDirty(); + + yield return WaitForFocus(m_Window.rootVisualElement.Q("control-schemes-toolbar-menu")); + } } #endif diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 4e981b4547..085c73551e 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -79,6 +79,7 @@ however, it has to be formatted properly to pass verification tests. - Fixed the compilation warnings when used with Unity 6.4 (ISX-2349). - Fixed an issue where `InputSystemUIInputModule.localMultiPlayerRoot` could not be set to `null` when using `MultiplayerEventSystem`. [ISXB-1610](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1610) - Fixed an issue in `Keyboard` where the sub-script operator would return a `null` key control for the deprecated key `Key.IMESelected`. Now, an aliased `KeyControl`mapping to the IMESelected bit is returned for compability reasons. It is still strongly advised to not rely on this key since `IMESelected` bit isn't strictly a key and will be removed from the `Key` enumeration type in a future major revision. [ISXB-1541](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1541). +- Fixed an ArgumentOutOfRangeException that was thrown when pressing the undo shortcut while changing a control scheme name. [ISXB-1607](https://issuetracker.unity3d.com/issues/argumentoutofrangeexception-error-is-thrown-when-pressing-the-undo-shortcut-while-changing-the-control-scheme-name) - Fixed an issue where the onAnyButtonPress callback would be triggered multiple times during unrelated events when a button is held down. See [ISXB-1005](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1005). - Fixed InputControl picker not updating correctly when the Input Actions Window was dirty. [ISXB-1221](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1221) - Fixed formatting issues on processor documentation page. diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs index 6b0ba03687..75aac494d3 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs @@ -145,10 +145,16 @@ public static Command ResetSelectedControlScheme() { return (in InputActionsEditorState state) => { - var controlSchemeSerializedProperty = state.selectedControlSchemeIndex == -1 ? null : - state.serializedObject - .FindProperty(nameof(InputActionAsset.m_ControlSchemes)) - .GetArrayElementAtIndex(state.selectedControlSchemeIndex); + SerializedProperty controlSchemeSerializedProperty = null; + var serializedProperty = state.serializedObject + .FindProperty(nameof(InputActionAsset.m_ControlSchemes)); + + if (state.selectedControlSchemeIndex < serializedProperty.arraySize) + { + controlSchemeSerializedProperty = state.selectedControlSchemeIndex == -1 ? null : + serializedProperty + .GetArrayElementAtIndex(state.selectedControlSchemeIndex); + } if (controlSchemeSerializedProperty == null) { diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs index 9b2057c7ac..ba1550a9ef 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs @@ -108,7 +108,6 @@ private void RemoveDeviceRequirement() public override void RedrawUI(InputControlScheme viewState) { rootElement.Q(kControlSchemeNameTextField).value = string.IsNullOrEmpty(m_NewName) ? viewState.name : m_NewName; - m_ListView.itemsSource?.Clear(); m_ListView.itemsSource = viewState.deviceRequirements.Count > 0 ? viewState.deviceRequirements.Select(r => (r.controlPath, r.isOptional)).ToList() : @@ -128,7 +127,7 @@ private void SaveAndClose() CloseView(); } - private void Cancel() + internal void Cancel() { // Reload the selected ControlScheme values from the SerilaizedProperty and throw away any changes Dispatch(ControlSchemeCommands.ResetSelectedControlScheme()); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs index e94e7427f9..1f1fd66d52 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs @@ -24,6 +24,8 @@ internal class InputActionsEditorView : ViewBase SelectControlScheme(-1), viewState.selectedControlSchemeIndex == -1 ? DropdownMenuAction.Status.Checked : DropdownMenuAction.Status.Normal); @@ -186,7 +194,7 @@ private void SetUpDevicesMenu(ViewState viewState) return; } m_DevicesToolbar.SetEnabled(true); - var currentControlScheme = viewState.controlSchemes.ElementAt(viewState.selectedControlSchemeIndex); + var currentControlScheme = viewState.controlSchemes.ElementAtOrDefault(viewState.selectedControlSchemeIndex); if (viewState.selectedDeviceIndex == -1) m_DevicesToolbar.text = "All Devices"; @@ -228,10 +236,13 @@ private void DeleteControlScheme(DropdownMenuAction obj) private void ShowControlSchemeEditor(VisualElement parent, bool updateExisting = false) { - var controlSchemesView = CreateChildView(new ControlSchemesView(parent, stateContainer, updateExisting)); - controlSchemesView.UpdateView(stateContainer.GetState()); - - controlSchemesView.OnClosing += _ => DestroyChildView(controlSchemesView); + m_ControlSchemesView = CreateChildView(new ControlSchemesView(parent, stateContainer, updateExisting)); + m_ControlSchemesView.UpdateView(stateContainer.GetState()); + m_ControlSchemesView.OnClosing += _ => + { + DestroyChildView(m_ControlSchemesView); + m_ControlSchemesView = null; + }; } private void SelectControlScheme(int controlSchemeIndex) @@ -258,6 +269,7 @@ public override void DestroyView() { base.DestroyView(); s_OnPasteCutElements.Remove(this); + Undo.undoRedoPerformed -= CloseControlSchemeView; } public void OnPaste(InputActionsEditorState state)