terminal/src/cascadia/TerminalSettingsModel/ApplicationState.cpp

173 lines
6.4 KiB
C++
Raw Normal View History

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ApplicationState.h"
#include "CascadiaSettings.h"
#include "ApplicationState.g.cpp"
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
#include "WindowLayout.g.cpp"
#include "ActionAndArgs.h"
#include "JsonUtils.h"
#include "FileUtils.h"
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
static constexpr std::wstring_view stateFileName{ L"state.json" };
static constexpr std::string_view TabLayoutKey{ "tabLayout" };
static constexpr std::string_view InitialPositionKey{ "initialPosition" };
static constexpr std::string_view InitialSizeKey{ "initialSize" };
namespace Microsoft::Terminal::Settings::Model::JsonUtils
{
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
using namespace winrt::Microsoft::Terminal::Settings::Model;
template<>
struct ConversionTrait<WindowLayout>
{
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
WindowLayout FromJson(const Json::Value& json)
{
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
auto layout = winrt::make_self<implementation::WindowLayout>();
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
GetValueForKey(json, TabLayoutKey, layout->_TabLayout);
GetValueForKey(json, InitialPositionKey, layout->_InitialPosition);
GetValueForKey(json, InitialSizeKey, layout->_InitialSize);
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
return *layout;
}
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
bool CanConvert(const Json::Value& json)
{
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
return json.isObject();
}
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
Json::Value ToJson(const WindowLayout& val)
{
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
Json::Value json{ Json::objectValue };
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
SetValueForKey(json, TabLayoutKey, val.TabLayout());
SetValueForKey(json, InitialPositionKey, val.InitialPosition());
SetValueForKey(json, InitialSizeKey, val.InitialSize());
return json;
}
std::string TypeDescription() const
{
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
return "WindowLayout";
}
};
}
using namespace ::Microsoft::Terminal::Settings::Model;
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// Returns the application-global ApplicationState object.
Microsoft::Terminal::Settings::Model::ApplicationState ApplicationState::SharedInstance()
{
static auto state = winrt::make_self<ApplicationState>(GetBaseSettingsPath() / stateFileName);
return *state;
}
ApplicationState::ApplicationState(std::filesystem::path path) noexcept :
_path{ std::move(path) },
_throttler{ std::chrono::seconds(1), [this]() { _write(); } }
{
_read();
}
// The destructor ensures that the last write is flushed to disk before returning.
ApplicationState::~ApplicationState()
{
// This will ensure that we not just cancel the last outstanding timer,
// but instead force it to run as soon as possible and wait for it to complete.
_throttler.flush();
}
// Re-read the state.json from disk.
void ApplicationState::Reload() const noexcept
{
_read();
}
// Returns the state.json path on the disk.
winrt::hstring ApplicationState::FilePath() const noexcept
{
return winrt::hstring{ _path.wstring() };
}
// Generate all getter/setters
#define MTSM_APPLICATION_STATE_GEN(type, name, key, ...) \
type ApplicationState::name() const noexcept \
{ \
const auto state = _state.lock_shared(); \
const auto& value = state->name; \
return value ? *value : type{ __VA_ARGS__ }; \
} \
\
void ApplicationState::name(const type& value) noexcept \
{ \
{ \
auto state = _state.lock(); \
state->name.emplace(value); \
} \
\
_throttler(); \
}
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
#undef MTSM_APPLICATION_STATE_GEN
// Deserializes the state.json at _path into this ApplicationState.
// * ANY errors during app state will result in the creation of a new empty state.
// * ANY errors during runtime will result in changes being partially ignored.
void ApplicationState::_read() const noexcept
try
{
const auto data = ReadUTF8FileIfExists(_path).value_or(std::string{});
if (data.empty())
{
return;
}
std::string errs;
std::unique_ptr<Json::CharReader> reader{ Json::CharReaderBuilder::CharReaderBuilder().newCharReader() };
Json::Value root;
if (!reader->parse(data.data(), data.data() + data.size(), &root, &errs))
{
throw winrt::hresult_error(WEB_E_INVALID_JSON_STRING, winrt::to_hstring(errs));
}
auto state = _state.lock();
// GetValueForKey() comes in two variants:
// * take a std::optional<T> reference
// * return std::optional<T> by value
// At the time of writing the former version skips missing fields in the json,
// but we want to explicitly clear state fields that were removed from state.json.
#define MTSM_APPLICATION_STATE_GEN(type, name, key, ...) state->name = JsonUtils::GetValueForKey<std::optional<type>>(root, key);
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
#undef MTSM_APPLICATION_STATE_GEN
}
CATCH_LOG()
// Serialized this ApplicationState (in `context`) into the state.json at _path.
// * Errors are only logged.
// * _state->_writeScheduled is set to false, signaling our
// setters that _synchronize() needs to be called again.
void ApplicationState::_write() const noexcept
try
{
Json::Value root{ Json::objectValue };
{
auto state = _state.lock_shared();
#define MTSM_APPLICATION_STATE_GEN(type, name, key, ...) JsonUtils::SetValueForKey(root, key, state->name);
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
#undef MTSM_APPLICATION_STATE_GEN
}
Json::StreamWriterBuilder wbuilder;
const auto content = Json::writeString(wbuilder, root);
WriteUTF8FileAtomic(_path, content);
}
CATCH_LOG()
}