Skip to content

Commit

Permalink
Persist Runtime TabTitle and Maximize/Focus/Fullscreen states (#12073)
Browse files Browse the repository at this point in the history
This commit adds additional information to the persisted window layouts.
- Runtime tab titles
- Focus, Maximized, and Fullscreen modes.

Also,
- Adds actions for Set{Focus,FullScreen} that take a boolean
  to work in addition to the current Toggle{Focus, Fullscreen} actions.
- Adds SetMaximized that takes a boolean.
  This adds the capability to maximize (resp restore) a window using
  standard terminal actions.
  This also involves hooking up a good amount of state tracking between
  the terminal page and the window to see when maximize state has changed
  so that it can be persisted.
- These actions are not added to the default settings, but they could be.
  The intention is that they could assist with automation (and was originally)
  how I planned on persisting the state instead of augmenting the LaunchMode.
- The fullscreen/maximized saving isn't perfect because we don't have a
  way to save the non-maximized/fullscreen size, so exiting the modes
  won't restore whatever the previous size was.

References #9800 
Closes #11878 
Closes #11426
  • Loading branch information
Rosefield authored Jan 10, 2022
1 parent 591b949 commit acbfb30
Show file tree
Hide file tree
Showing 25 changed files with 354 additions and 23 deletions.
63 changes: 63 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,10 @@
"tabSearch",
"toggleAlwaysOnTop",
"toggleFocusMode",
"setFocusMode",
"toggleFullscreen",
"setFullScreen",
"setMaximized",
"togglePaneZoom",
"toggleSplitOrientation",
"toggleReadOnlyMode",
Expand Down Expand Up @@ -823,6 +826,66 @@
"colorScheme"
]
},
"SetFocusModeAction": {
"description": "Arguments for a setFocusMode action",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "setFocusMode"
},
"isFocusMode": {
"type": "boolean",
"description": "whether focus mode is enabled"
}
}
}
],
},
"SetFullScreenAction": {
"description": "Arguments for a setFullScreen action",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "setFullScreen"
},
"isFullScreen": {
"type": "boolean",
"description": "whether the window should be full screen"
}
}
}
],
},
"SetMaximizedAction": {
"description": "Arguments for a setMaximized action",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "setMaximized"
},
"isMaximized": {
"type": "boolean",
"description": "whether the window should be maximized"
}
}
}
],
},
"WtAction": {
"description": "Arguments corresponding to a wt Action",
"allOf": [
Expand Down
30 changes: 30 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,43 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}

void TerminalPage::_HandleSetFocusMode(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<SetFocusModeArgs>())
{
SetFocusMode(realArgs.IsFocusMode());
args.Handled(true);
}
}

void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
ToggleFullscreen();
args.Handled(true);
}

void TerminalPage::_HandleSetFullScreen(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<SetFullScreenArgs>())
{
SetFullscreen(realArgs.IsFullScreen());
args.Handled(true);
}
}

void TerminalPage::_HandleSetMaximized(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<SetMaximizedArgs>())
{
RequestSetMaximized(realArgs.IsMaximized());
args.Handled(true);
}
}

void TerminalPage::_HandleToggleAlwaysOnTop(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
Expand Down
36 changes: 25 additions & 11 deletions src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,23 +279,22 @@ namespace winrt::TerminalApp::implementation
// launched _fullscreen_, toggle fullscreen mode. This will make sure
// that the window size is _first_ set up as something sensible, so
// leaving fullscreen returns to a reasonable size.
//
// We know at the start, that the root TerminalPage definitely isn't
// in focus nor fullscreen mode. So "Toggle" here will always work
// to "enable".
const auto launchMode = this->GetLaunchMode();
if (IsQuakeWindow())
if (IsQuakeWindow() || WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
{
_root->ToggleFocusMode();
_root->SetFocusMode(true);
}
else if (launchMode == LaunchMode::FullscreenMode)

// The IslandWindow handles (creating) the maximized state
// we just want to record it here on the page as well.
if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode))
{
_root->ToggleFullscreen();
_root->Maximized(true);
}
else if (launchMode == LaunchMode::FocusMode ||
launchMode == LaunchMode::MaximizedFocusMode)

if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode))
{
_root->ToggleFocusMode();
_root->SetFullscreen(true);
}
});
_root->Create();
Expand Down Expand Up @@ -662,6 +661,13 @@ namespace winrt::TerminalApp::implementation
// commandline, then use that to override the value from the settings.
const auto valueFromSettings = _settings.GlobalSettings().LaunchMode();
const auto valueFromCommandlineArgs = _appArgs.GetLaunchMode();
if (const auto layout = _root->LoadPersistedLayout(_settings))
{
if (layout.LaunchMode())
{
return layout.LaunchMode().Value();
}
}
return valueFromCommandlineArgs.has_value() ?
valueFromCommandlineArgs.value() :
valueFromSettings;
Expand Down Expand Up @@ -1443,6 +1449,14 @@ namespace winrt::TerminalApp::implementation
return _root ? _root->Fullscreen() : false;
}

void AppLogic::Maximized(bool newMaximized)
{
if (_root)
{
_root->Maximized(newMaximized);
}
}

bool AppLogic::AlwaysOnTop() const
{
return _root ? _root->AlwaysOnTop() : false;
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ namespace winrt::TerminalApp::implementation

bool FocusMode() const;
bool Fullscreen() const;
void Maximized(bool newMaximized);
bool AlwaysOnTop() const;

bool ShouldUsePersistedLayout();
Expand Down Expand Up @@ -193,6 +194,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(LastTabClosed, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs, _root, LastTabClosed);
FORWARDED_TYPED_EVENT(FocusModeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FocusModeChanged);
FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged);
FORWARDED_TYPED_EVENT(ChangeMaximizeRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, ChangeMaximizeRequested);
FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged);
FORWARDED_TYPED_EVENT(RaiseVisualBell, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, RaiseVisualBell);
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.idl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ namespace TerminalApp

Boolean FocusMode { get; };
Boolean Fullscreen { get; };
void Maximized(Boolean newMaximized);
Boolean AlwaysOnTop { get; };

void IdentifyWindow();
Expand Down Expand Up @@ -114,6 +115,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.ElementTheme> RequestedThemeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> ChangeMaximizeRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> RaiseVisualBell;
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
Expand Down
32 changes: 29 additions & 3 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,13 @@ namespace winrt::TerminalApp::implementation
WindowLayout layout{};
layout.TabLayout(winrt::single_threaded_vector<ActionAndArgs>(std::move(actions)));

LaunchMode mode = LaunchMode::DefaultMode;
WI_SetFlagIf(mode, LaunchMode::FullscreenMode, _isFullscreen);
WI_SetFlagIf(mode, LaunchMode::FocusMode, _isInFocusMode);
WI_SetFlagIf(mode, LaunchMode::MaximizedMode, _isMaximized);

layout.LaunchMode({ mode });

// Only save the content size because the tab size will be added on load.
const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
Expand Down Expand Up @@ -2607,10 +2614,10 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalPage::ToggleFocusMode()
{
_SetFocusMode(!_isInFocusMode);
SetFocusMode(!_isInFocusMode);
}

void TerminalPage::_SetFocusMode(const bool inFocusMode)
void TerminalPage::SetFocusMode(const bool inFocusMode)
{
const bool newInFocusMode = inFocusMode;
if (newInFocusMode != FocusMode())
Expand Down Expand Up @@ -2858,6 +2865,25 @@ namespace winrt::TerminalApp::implementation
_FullscreenChangedHandlers(*this, nullptr);
}

// Method Description:
// - Updates the page's state for isMaximized when the window changes externally.
void TerminalPage::Maximized(bool newMaximized)
{
_isMaximized = newMaximized;
}

// Method Description:
// - Asks the window to change its maximized state.
void TerminalPage::RequestSetMaximized(bool newMaximized)
{
if (_isMaximized == newMaximized)
{
return;
}
_isMaximized = newMaximized;
_ChangeMaximizeRequestedHandlers(*this, nullptr);
}

HRESULT TerminalPage::_OnNewConnection(const ConptyConnection& connection)
{
// We need to be on the UI thread in order for _OpenNewTab to run successfully.
Expand Down Expand Up @@ -3260,7 +3286,7 @@ namespace winrt::TerminalApp::implementation
// If we're entering Quake Mode from ~Focus Mode, then this will enter Focus Mode
// If we're entering Quake Mode from Focus Mode, then this will do nothing
// If we're leaving Quake Mode (we're already in Focus Mode), then this will do nothing
_SetFocusMode(true);
SetFocusMode(true);
_IsQuakeWindowChangedHandlers(*this, nullptr);
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ namespace winrt::TerminalApp::implementation
bool Fullscreen() const;
bool AlwaysOnTop() const;
void SetFullscreen(bool);
void SetFocusMode(const bool inFocusMode);
void Maximized(bool newMaximized);
void RequestSetMaximized(bool newMaximized);

void SetStartupActions(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);

Expand Down Expand Up @@ -137,6 +140,7 @@ namespace winrt::TerminalApp::implementation
TYPED_EVENT(SetTitleBarContent, IInspectable, winrt::Windows::UI::Xaml::UIElement);
TYPED_EVENT(FocusModeChanged, IInspectable, IInspectable);
TYPED_EVENT(FullscreenChanged, IInspectable, IInspectable);
TYPED_EVENT(ChangeMaximizeRequested, IInspectable, IInspectable);
TYPED_EVENT(AlwaysOnTopChanged, IInspectable, IInspectable);
TYPED_EVENT(RaiseVisualBell, IInspectable, IInspectable);
TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable);
Expand Down Expand Up @@ -176,6 +180,7 @@ namespace winrt::TerminalApp::implementation

bool _isInFocusMode{ false };
bool _isFullscreen{ false };
bool _isMaximized{ false };
bool _isAlwaysOnTop{ false };
winrt::hstring _WindowName{};
uint64_t _WindowId{ 0 };
Expand Down Expand Up @@ -404,8 +409,6 @@ namespace winrt::TerminalApp::implementation

void _UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element);

void _SetFocusMode(const bool inFocusMode);

winrt::Microsoft::Terminal::Settings::Model::Profile GetClosestProfileForDuplicationOfProfile(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile) const noexcept;

winrt::fire_and_forget _ConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
Expand Down
11 changes: 11 additions & 0 deletions src/cascadia/TerminalApp/TerminalTab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,17 @@ namespace winrt::TerminalApp::implementation
state.args.emplace_back(std::move(setColorAction));
}

if (!_runtimeTabText.empty())
{
ActionAndArgs renameTabAction{};
renameTabAction.Action(ShortcutAction::RenameTab);

RenameTabArgs renameTabArgs{ _runtimeTabText };
renameTabAction.Args(renameTabArgs);

state.args.emplace_back(std::move(renameTabAction));
}

// If we only have one arg, we only have 1 pane so we don't need any
// special focus logic
if (state.args.size() > 1 && state.focusedPaneId.has_value())
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Launch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

INITIALIZE_BINDABLE_ENUM_SETTING(FirstWindowPreference, FirstWindowPreference, FirstWindowPreference, L"Globals_FirstWindowPreference", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
// More options were added to the JSON mapper when the enum was made into [Flags]
// but we want to preserve the previous set of options in the UI.
_LaunchModeList.RemoveAt(7); // maximizedFullscreenFocus
_LaunchModeList.RemoveAt(6); // fullscreenFocus
_LaunchModeList.RemoveAt(3); // maximizedFullscreen
INITIALIZE_BINDABLE_ENUM_SETTING(WindowingBehavior, WindowingMode, WindowingMode, L"Globals_WindowingBehavior", L"Content");

// BODGY
Expand Down
12 changes: 12 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,18 @@
<value>Maximized focus</value>
<comment>An option to choose from for the "launch mode" setting. Opens the app maximized and in focus mode.</comment>
</data>
<data name="Globals_LaunchModeMaximizedFullscreen.Content" xml:space="preserve">
<value>Maximized full screen</value>
<comment>An option to choose from for the "launch mode" setting. Opens the app maximized and in full screen.</comment>
</data>
<data name="Globals_LaunchModeFullscreenFocus.Content" xml:space="preserve">
<value>Full screen focus</value>
<comment>An option to choose from for the "launch mode" setting. Opens the app in full screen and in focus mode.</comment>
</data>
<data name="Globals_LaunchModeMaximizedFullscreenFocus.Content" xml:space="preserve">
<value>Maximized full screen focus</value>
<comment>An option to choose from for the "launch mode" setting. Opens the app maximized in full screen and in focus mode.</comment>
</data>
<data name="Profile_BellStyle.Header" xml:space="preserve">
<value>Bell notification style</value>
<comment>Header for a control to select the how the app notifies the user. "Bell" is the common term in terminals for the BEL character (like the metal device used to chime).</comment>
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ static constexpr std::string_view TabSearchKey{ "tabSearch" };
static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" };
static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" };
static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" };
static constexpr std::string_view SetFocusModeKey{ "setFocusMode" };
static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" };
static constexpr std::string_view SetFullScreenKey{ "setFullScreen" };
static constexpr std::string_view SetMaximizedKey{ "setMaximized" };
static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" };
static constexpr std::string_view ToggleSplitOrientationKey{ "toggleSplitOrientation" };
static constexpr std::string_view LegacyToggleRetroEffectKey{ "toggleRetroEffect" };
Expand Down Expand Up @@ -354,7 +357,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") },
{ ShortcutAction::ToggleCommandPalette, L"" },
{ ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") },
{ ShortcutAction::SetFocusMode, L"" },
{ ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") },
{ ShortcutAction::SetFullScreen, L"" },
{ ShortcutAction::SetMaximized, L"" },
{ ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") },
{ ShortcutAction::ToggleSplitOrientation, RS_(L"ToggleSplitOrientationCommandKey") },
{ ShortcutAction::ToggleShaderEffects, RS_(L"ToggleShaderEffectsCommandKey") },
Expand Down
Loading

0 comments on commit acbfb30

Please sign in to comment.