diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index c1d85b5094..eca55251d9 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -92,6 +92,7 @@ however, it has to be formatted properly to pass verification tests. - Fixed InputManager.asset file growing in size on each Reset call. - Fixed Opening InputDebugger throws 'Action map must have state at this point' error. - Fixed Cut/Paste behaviour to match Editor - Cut items will now be cleared from clipboard after pasting. +- Fixed Pasting items between Input Action Editor windows having no effect until an item in the Action Map/Action lists was selected. - Improved window layout to avoid elements being hidden (both the Input Actions in Project Settings, and standalone Input Actions Editor windows). - Fixed InputAction asset appearing dirty after rename [ISXB-749](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-749). - Fixed Error logged when InputActionsEditor window opened without a valid asset. diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs index 2ecf5c9bdd..11b3a55072 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs @@ -285,6 +285,12 @@ private void DirtyInputActionsEditorWindow(InputActionsEditorState newState) UpdateWindowTitle(); } + private void OnFocus() + { + // Apply focus here so that Paste works when users tab into the window (handled in InputActionsEditorView) + rootVisualElement.Focus(); + } + private void OnLostFocus() { // Auto-save triggers on focus-lost instead of on every change diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs index 678b14d80d..b724e5a756 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs @@ -169,6 +169,7 @@ private void OnExecuteCommand(ExecuteCommandEvent evt) if (allowUICommandExecution) { + // NB: Paste is handled in InputActionsEditorView. switch (evt.commandName) { case CmdEvents.Rename: @@ -187,11 +188,6 @@ private void OnExecuteCommand(ExecuteCommandEvent evt) case CmdEvents.Cut: CutItems(); break; - case CmdEvents.Paste: - var isActionCopied = CopyPasteHelper.GetCopiedClipboardType() == typeof(InputAction); - if (CopyPasteHelper.HasPastableClipboardData(typeof(InputActionMap))) - PasteItems(isActionCopied); - break; default: return; // Skip StopPropagation if we didn't execute anything } @@ -205,6 +201,7 @@ private void OnExecuteCommand(ExecuteCommandEvent evt) private void OnValidateCommand(ValidateCommandEvent evt) { // Mark commands as supported for Execute by stopping propagation of the event + // Paste is handled in InputActionsEditorView. switch (evt.commandName) { case CmdEvents.Rename: @@ -213,7 +210,6 @@ private void OnValidateCommand(ValidateCommandEvent evt) case CmdEvents.Duplicate: case CmdEvents.Copy: case CmdEvents.Cut: - case CmdEvents.Paste: evt.StopPropagation(); break; } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs index e301f6e6b5..3ae3e8a107 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs @@ -390,6 +390,7 @@ private void OnExecuteCommand(ExecuteCommandEvent evt) if (allowUICommandExecution) { + // NB: Paste is handled in InputActionsEditorView. var data = (ActionOrBindingData)m_ActionsTreeView.selectedItem; switch (evt.commandName) { @@ -412,11 +413,6 @@ private void OnExecuteCommand(ExecuteCommandEvent evt) case CmdEvents.Cut: CutItems(); break; - case CmdEvents.Paste: - var hasPastableData = CopyPasteHelper.HasPastableClipboardData(data.isAction ? typeof(InputAction) : typeof(InputBinding)); - if (hasPastableData) - PasteItems(); - break; default: return; // Skip StopPropagation if we didn't execute anything } @@ -430,6 +426,7 @@ private void OnExecuteCommand(ExecuteCommandEvent evt) private void OnValidateCommand(ValidateCommandEvent evt) { // Mark commands as supported for Execute by stopping propagation of the event + // Paste is handled in InputActionsEditorView. switch (evt.commandName) { case CmdEvents.Rename: @@ -438,7 +435,6 @@ private void OnValidateCommand(ValidateCommandEvent evt) case CmdEvents.Duplicate: case CmdEvents.Copy: case CmdEvents.Cut: - case CmdEvents.Paste: evt.StopPropagation(); break; } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CopyPasteHelper.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CopyPasteHelper.cs index 9712b6d1e3..ac6d5b3dcb 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CopyPasteHelper.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CopyPasteHelper.cs @@ -211,9 +211,13 @@ private static void PasteActionsFromClipboard(InputActionsEditorState state, boo : Selectors.GetSelectedActionMap(state)?.wrappedProperty; var actionArray = actionMap?.FindPropertyRelative(nameof(InputActionMap.m_Actions)); if (actionArray == null) return; + var index = state.selectedActionIndex; - if (addLast) + if (addLast || index >= actionArray.arraySize) index = actionArray.arraySize - 1; + if (index < 0) + index = 0; + PasteData(EditorHelpers.GetSystemCopyBufferContents(), new[] {index}, actionArray); } @@ -384,7 +388,7 @@ private static bool IsPartOfComposite(string json) private static SerializedProperty AddElement(SerializedProperty arrayProperty, string name, int index = -1) { var uniqueName = InputActionSerializationHelpers.FindUniqueName(arrayProperty, name); - if (index < 0) + if (index < 0 || index > arrayProperty.arraySize) index = arrayProperty.arraySize; arrayProperty.InsertArrayElementAtIndex(index); 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 75700a20b8..e7cf90cfab 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs @@ -1,4 +1,5 @@ #if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS +using CmdEvents = UnityEngine.InputSystem.Editor.InputActionsEditorConstants.CommandEvents; using System; using System.Collections.Generic; using System.Linq; @@ -22,6 +23,9 @@ internal class InputActionsEditorView : ViewBase("control-schemes-toolbar-menu"); @@ -103,6 +108,10 @@ public InputActionsEditorView(VisualElement root, StateContainer stateContainer, selectedDeviceIndex = state.selectedDeviceRequirementIndex }); + root.RegisterCallback(OnValidateCommand); + root.RegisterCallback(OnExecuteCommand); + root.focusable = true; // Required for CommandEvents to work + s_OnPasteCutElements.Add(this); } @@ -240,6 +249,41 @@ public class ViewState public int selectedDeviceIndex; } + void OnExecuteCommand(ExecuteCommandEvent evt) + { + if (allowUICommandExecution) + { + if (evt.commandName != CmdEvents.Paste) + return; + + var copiedType = CopyPasteHelper.GetCopiedClipboardType(); + + if (copiedType == typeof(InputActionMap)) + { + evt.StopPropagation(); + m_ActionMapsView.PasteItems(false); + allowUICommandExecution = false; + } + else if (copiedType == typeof(InputAction) || copiedType == typeof(InputBinding)) + { + evt.StopPropagation(); + m_ActionsTreeView.PasteItems(); + allowUICommandExecution = false; + } + } + } + + void OnValidateCommand(ValidateCommandEvent evt) + { + // Mark commands as supported for Execute by stopping propagation of the event + switch (evt.commandName) + { + case CmdEvents.Paste: + evt.StopPropagation(); + break; + } + } + internal static List s_OnPasteCutElements = new(); public override void DestroyView()