Skip to content

Commit 009e6b3

Browse files
authored
FIX: Avoid jumping around Actions list due to premature asset saving (ISXB-801) (#1886)
* FIX: Avoid jumping around Actions list due to premature asset saving (ISXB-801)
1 parent dca1633 commit 009e6b3

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

Packages/com.unity.inputsystem/InputSystem/Editor/ControlPicker/InputControlPathEditor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ public void OnGUI(Rect rect, GUIContent label = null, SerializedProperty propert
162162

163163
private void ShowDropdown(Rect rect, SerializedProperty serializedProperty, Action modifiedCallback)
164164
{
165+
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
166+
InputActionsEditorSettingsProvider.SetIMGUIDropdownVisible(true, false);
167+
#endif
165168
if (m_PickerDropdown == null)
166169
{
167170
m_PickerDropdown = new InputControlPickerDropdown(

Packages/com.unity.inputsystem/InputSystem/Editor/ControlPicker/InputControlPickerDropdown.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public void SetPickedCallback(Action<string> action)
6565

6666
protected override void OnDestroy()
6767
{
68+
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
69+
InputActionsEditorSettingsProvider.SetIMGUIDropdownVisible(false, false);
70+
#endif
6871
m_RebindingOperation?.Dispose();
6972
m_RebindingOperation = null;
7073
}
@@ -120,6 +123,9 @@ protected override AdvancedDropdownItem BuildCustomSearch(string searchString,
120123

121124
protected override void ItemSelected(AdvancedDropdownItem item)
122125
{
126+
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
127+
InputActionsEditorSettingsProvider.SetIMGUIDropdownVisible(false, true);
128+
#endif
123129
var path = ((InputControlDropdownItem)item).controlPathWithDevice;
124130
m_OnPickCallback(path);
125131
}

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorSettingsProvider.cs

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
22
using System.Collections.Generic;
3+
using System.Threading.Tasks;
34
using UnityEditor;
45
using UnityEditor.ShortcutManagement;
56
using UnityEngine.UIElements;
@@ -16,6 +17,7 @@ internal class InputActionsEditorSettingsProvider : SettingsProvider
1617
private bool m_HasEditFocus;
1718
private bool m_IgnoreActionChangedCallback;
1819
private bool m_IsActivated;
20+
private static bool m_IMGUIDropdownVisible;
1921
StateContainer m_StateContainer;
2022
private static InputActionsEditorSettingsProvider m_ActiveSettingsProvider;
2123

@@ -95,6 +97,50 @@ private void OnEditFocus(FocusInEvent @event)
9597
{
9698
m_HasEditFocus = true;
9799
m_ActiveSettingsProvider = this;
100+
SetIMGUIDropdownVisible(false, false);
101+
}
102+
}
103+
104+
void SaveAssetOnFocusLost()
105+
{
106+
#if UNITY_INPUT_SYSTEM_INPUT_ACTIONS_EDITOR_AUTO_SAVE_ON_FOCUS_LOST
107+
var asset = GetAsset();
108+
if (asset != null)
109+
ValidateAndSaveAsset(asset);
110+
#endif
111+
}
112+
113+
public static void SetIMGUIDropdownVisible(bool visible, bool optionWasSelected)
114+
{
115+
// If we selected an item from the dropdown, we *should* still be focused on this settings window - but
116+
// since the IMGUI dropdown is technically a separate window, we have to refocus manually.
117+
//
118+
// If we didn't select a dropdown option, there's not a simple way to know where the focus has gone,
119+
// so assume we lost focus and save if appropriate. ISXB-801
120+
if (!visible && m_IMGUIDropdownVisible)
121+
{
122+
if (optionWasSelected)
123+
m_ActiveSettingsProvider.m_RootVisualElement.Focus();
124+
else
125+
m_ActiveSettingsProvider.SaveAssetOnFocusLost();
126+
}
127+
else if (visible && !m_IMGUIDropdownVisible)
128+
{
129+
m_ActiveSettingsProvider.m_HasEditFocus = false;
130+
}
131+
132+
m_IMGUIDropdownVisible = visible;
133+
}
134+
135+
private async void DelayFocusLost(bool relatedTargetWasNull)
136+
{
137+
await Task.Delay(120);
138+
139+
// We delay this call to ensure that the IMGUI flag has a chance to change first.
140+
if (relatedTargetWasNull && m_HasEditFocus && !m_IMGUIDropdownVisible)
141+
{
142+
m_HasEditFocus = false;
143+
SaveAssetOnFocusLost();
98144
}
99145
}
100146

@@ -105,16 +151,7 @@ private void OnEditFocusLost(FocusOutEvent @event)
105151
// elements outside of project settings Editor Window. Also note that @event is null when we call this
106152
// from OnDeactivate().
107153
var element = (VisualElement)@event?.relatedTarget;
108-
if (element == null && m_HasEditFocus)
109-
{
110-
m_HasEditFocus = false;
111-
112-
#if UNITY_INPUT_SYSTEM_INPUT_ACTIONS_EDITOR_AUTO_SAVE_ON_FOCUS_LOST
113-
var asset = GetAsset();
114-
if (asset != null)
115-
ValidateAndSaveAsset(asset);
116-
#endif
117-
}
154+
DelayFocusLost(element == null);
118155
}
119156

120157
private void OnStateChanged(InputActionsEditorState newState)

0 commit comments

Comments
 (0)