Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Fixed

- Fixed the Input Actions editor window's unsaved-changes handling on close: it now uses the Editor's built-in save prompt (including on Editor quit), auto-saves pending changes when the window is closed with auto-save enabled, and prompts instead of silently dropping changes if an auto-save fails (e.g. version control refused the checkout). [UUM-154808](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-154808)
- Fixed misaligned labels in the Input Actions editor properties pane. [UUM-154536](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-154536)
- Fixed a single click producing two simultaneous touches when the Device Simulator view is open and "Simulate Touch Input From Mouse or Pen" is enabled in the Input Debugger; Touch Simulation now suppresses its events while a Device Simulator view is open [UUM-153420]
- Fixed the search field in the "Add supported device" popup (Input System Package Settings > Supported Devices > "+") drawing flush against the popup's left edge with no left margin, unlike its right-side spacing; it is now inset to match [UUM-150217](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-150217)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

private string m_AssetJson;
private bool m_IsDirty;
private bool m_IsEditorQuitting;
private bool m_AutoSaveFailed;

private StateContainer m_StateContainer;
private InputActionsEditorView m_View;
Expand Down Expand Up @@ -105,7 +105,7 @@
}

var window = GetWindow<InputActionsEditorWindow>();
if (window.m_IsDirty)
if (window.isDirty)
{
var assetPath = AssetDatabase.GUIDToAssetPath(window.m_AssetGUID);
if (!string.IsNullOrEmpty(assetPath))
Expand All @@ -127,7 +127,7 @@
}
}

window.m_IsDirty = false;
window.isDirty = false;
window.minSize = k_MinWindowSize;
window.SetAsset(asset, actionToSelect, actionMapToSelect);
window.Show();
Expand All @@ -146,12 +146,9 @@
return OpenWindow(asset, null, null);
}

private static GUIContent GetEditorTitle(InputActionAsset asset, bool isDirty)
private static GUIContent GetEditorTitle(InputActionAsset asset)
{
var text = asset.name + " (Input Actions Editor)";
if (isDirty)
text = "(*) " + text;
return new GUIContent(text);
return new GUIContent(asset.name + " (Input Actions Editor)");
}

private void SetAsset(InputActionAsset asset, string actionToSelect = null, string actionMapToSelect = null)
Expand Down Expand Up @@ -227,7 +224,10 @@
}
else
m_State = new InputActionsEditorState(m_State, new SerializedObject(m_AssetObjectForEditing));
m_IsDirty = HasContentChanged();
isDirty = HasContentChanged();

Check warning on line 227 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L227

Added line #L227 was not covered by tests

// saveChangesMessage is not serialized, so the prompt would be blank after a domain reload.
UpdateWindowTitle();

Check warning on line 230 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L230

Added line #L230 was not covered by tests
}
catch (Exception e)
{
Expand Down Expand Up @@ -293,7 +293,9 @@

private void UpdateWindowTitle()
{
titleContent = GetEditorTitle(GetEditedAsset(), m_IsDirty);
titleContent = GetEditorTitle(GetEditedAsset());
saveChangesMessage = "Do you want to save the changes you made in:\n" +
AssetDatabase.GUIDToAssetPath(m_AssetGUID) + "\n\nYour changes will be lost if you don't save them.";
}

private InputActionAsset GetEditedAsset()
Expand All @@ -312,6 +314,14 @@
if (InputActionAssetManager.SaveAsset(path, GetEditedAsset().ToJson()))
TryUpdateFromAsset();

// If an auto-save did not go through (e.g. version control refused the checkout), stop relying on
// auto-save so that closing the window prompts instead of silently dropping the changes.
if (isAutoSave && isDirty)
{
m_AutoSaveFailed = true;
UpdateUnsavedChangesState();
}

Check warning on line 323 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L320-L323

Added lines #L320 - L323 were not covered by tests

if (isAutoSave)
analytics.RegisterAutoSave();
else
Expand All @@ -327,40 +337,17 @@

private void DirtyInputActionsEditorWindow(InputActionsEditorState newState)
{
var isWindowDirty = HasContentChanged();

if (m_IsDirty == isWindowDirty)
return;

m_IsDirty = isWindowDirty;
UpdateWindowTitle();
isDirty = HasContentChanged();
}

private void OnEnable()
{
analytics.Begin();
EditorApplication.wantsToQuit += OnWantsToQuit;
}

private void OnDisable()
{
analytics.End();
EditorApplication.wantsToQuit -= OnWantsToQuit;
}

private bool OnWantsToQuit()
{
// Here the user will be prompted
bool isAllowedToQuit = CheckCanCloseAndPromptIfDirty(false);
m_IsEditorQuitting = isAllowedToQuit;

if (m_IsEditorQuitting)
{
// Reset flag in case another wantsToQuit listener aborts the quit.
EditorApplication.delayCall += () => m_IsEditorQuitting = false;
}

return m_IsEditorQuitting;
}

private void OnFocus()
Expand All @@ -370,7 +357,7 @@

private void OnLostFocus()
{
if (InputEditorUserSettings.autoSaveInputActionAssets && m_IsDirty)
if (InputEditorUserSettings.autoSaveInputActionAssets && isDirty)
{
// We'd like to avoid saving in case the focus was lost due to the drop-down window being spawned.
// This code should be cleaned up once we migrate the InputControl stuff from ImGUI completely.
Expand All @@ -385,84 +372,31 @@
analytics.RegisterEditorFocusOut();
}

/// <summary>
/// Shows a dialog when trying to close an input asset without saving changes.
/// </summary>
/// <param name="rebuildUIOnCancel">If true, reopens the editor window when user cancels.</param>
/// <returns> Returns true if you should allow the Unity Editor to close. </returns>
private bool CheckCanCloseAndPromptIfDirty(bool rebuildUIOnCancel)
public override void SaveChanges()
{
// Do we have unsaved changes that we need to ask the user to save or discard?
// Early out if asset up to date or editor closing.
if (!m_IsDirty || m_IsEditorQuitting)
return true;

// Get target asset path from GUID, if this fails file no longer exists and we need to abort.
var assetPath = AssetDatabase.GUIDToAssetPath(m_AssetGUID);
if (string.IsNullOrEmpty(assetPath))
return true;

// Prompt user with a dialog
var result = Dialog.InputActionAsset.ShowSaveChanges(assetPath);
switch (result)
{
case Dialog.Result.Save:
Save(isAutoSave: false);
return true;
case Dialog.Result.Cancel:
if (rebuildUIOnCancel)
{
// Cancel editor quit. (open new editor window with the edited asset)
ReshowEditorWindowWithUnsavedChanges();
}
Save(isAutoSave: false);
}

Check warning on line 378 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L377-L378

Added lines #L377 - L378 were not covered by tests

return false;
case Dialog.Result.Discard:
// Don't save, quit - reload the old asset from the json to prevent the asset from being dirtied
return true;
default:
throw new ArgumentOutOfRangeException(nameof(result));
}
public override void DiscardChanges()
{

Check warning on line 381 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L381

Added line #L381 was not covered by tests
// Clear the dirty state so OnDestroy does not auto-save the changes the user chose to discard.
isDirty = false;
base.DiscardChanges();

Check warning on line 384 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L383-L384

Added lines #L383 - L384 were not covered by tests
}

private void OnDestroy()
{
CheckCanCloseAndPromptIfDirty(true);
// Closing the tab does not always take focus away from the window, so OnLostFocus may not have run.
if (InputEditorUserSettings.autoSaveInputActionAssets && isDirty && m_AssetObjectForEditing != null)
Comment thread
josepmariapujol-unity marked this conversation as resolved.
Save(isAutoSave: true);

Check warning on line 391 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L391

Added line #L391 was not covered by tests

// Clean-up
CleanupStateContainer();
if (m_AssetObjectForEditing != null)
DestroyImmediate(m_AssetObjectForEditing);

m_View?.DestroyView();
}

private void ReshowEditorWindowWithUnsavedChanges()
{
var window = CreateWindow<InputActionsEditorWindow>();

// Move/transfer ownership of m_AssetObjectForEditing to new window
window.m_AssetObjectForEditing = m_AssetObjectForEditing;
m_AssetObjectForEditing = null;

// Move/transfer ownership of m_State to new window (struct)
window.m_State = m_State;
m_State = new InputActionsEditorState();

// Just copy trivial arguments
window.m_AssetGUID = m_AssetGUID;
window.m_AssetJson = m_AssetJson;
window.m_IsDirty = m_IsDirty;

// Note that view and state container will get destroyed with this window instance
// and recreated for this window below
window.BuildUI();
window.Show();

// Make sure window title is up to date
window.UpdateWindowTitle();
}

private bool TryUpdateFromAsset()
{
Debug.Assert(!string.IsNullOrEmpty(m_AssetGUID), "Asset GUID is empty");
Expand All @@ -480,7 +414,7 @@
workingCopy = InputActionAssetManager.CreateWorkingCopy(asset);
m_AssetJson = InputActionsEditorWindowUtils.ToJsonWithoutName(asset);
m_State = new InputActionsEditorState(m_State, new SerializedObject(workingCopy));
m_IsDirty = false;
isDirty = false;
}
catch (Exception e)
{
Expand All @@ -500,7 +434,24 @@
#region IInputActionEditorWindow

public string assetGUID => m_AssetGUID;
public bool isDirty => m_IsDirty;
public bool isDirty
{
get { return m_IsDirty; }
private set
{
m_IsDirty = value;
if (!value)
m_AutoSaveFailed = false;
UpdateUnsavedChangesState();
}
}

private void UpdateUnsavedChangesState()
{
// With auto-save enabled, changes are saved on focus loss or when the window is destroyed, so there is
// nothing to prompt for on close, unless a previous auto-save attempt failed.
hasUnsavedChanges = m_IsDirty && (!InputEditorUserSettings.autoSaveInputActionAssets || m_AutoSaveFailed);
}

public void OnAssetMoved()
{
Expand All @@ -512,7 +463,7 @@
{
// When associated asset is deleted on disk, just close the editor, but also mark the editor
// as not being dirty to avoid prompting the user to save changes.
m_IsDirty = false;
isDirty = false;

Check warning on line 466 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L466

Added line #L466 was not covered by tests
Close();
}

Expand All @@ -521,14 +472,14 @@
// If the editor has pending changes done by the user and the contents changes on disc, there
// is not much we can do about it but to ignore loading the changes. If the editors asset is
// unmodified, we can refresh the editor with the latest content from disc.
if (m_IsDirty)
if (isDirty)
return;

// If our asset has disappeared from disk, just close the window.
var assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
if (string.IsNullOrEmpty(assetPath))
{
m_IsDirty = false; // Avoid checks
isDirty = false; // Avoid checks

Check warning on line 482 in Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs#L482

Added line #L482 was not covered by tests
Close();
return;
}
Expand Down
Loading