diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 8746677939f..8cbaa808ddc 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -330,7 +330,10 @@ "tabSearch", "toggleAlwaysOnTop", "toggleFocusMode", + "setFocusMode", "toggleFullscreen", + "setFullScreen", + "setMaximized", "togglePaneZoom", "toggleSplitOrientation", "toggleReadOnlyMode", @@ -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": [ diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index f734425cc02..10b88252833 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -415,6 +415,16 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } + void TerminalPage::_HandleSetFocusMode(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + if (const auto& realArgs = args.ActionArgs().try_as()) + { + SetFocusMode(realArgs.IsFocusMode()); + args.Handled(true); + } + } + void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/, const ActionEventArgs& args) { @@ -422,6 +432,26 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } + void TerminalPage::_HandleSetFullScreen(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + if (const auto& realArgs = args.ActionArgs().try_as()) + { + SetFullscreen(realArgs.IsFullScreen()); + args.Handled(true); + } + } + + void TerminalPage::_HandleSetMaximized(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + if (const auto& realArgs = args.ActionArgs().try_as()) + { + RequestSetMaximized(realArgs.IsMaximized()); + args.Handled(true); + } + } + void TerminalPage::_HandleToggleAlwaysOnTop(const IInspectable& /*sender*/, const ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index ebc92d5058a..ec6ebf50fc5 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -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(); @@ -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; @@ -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; diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 813a057d8fd..19e891843b9 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -77,6 +77,7 @@ namespace winrt::TerminalApp::implementation bool FocusMode() const; bool Fullscreen() const; + void Maximized(bool newMaximized); bool AlwaysOnTop() const; bool ShouldUsePersistedLayout(); @@ -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); diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 973e8aa1a84..9121c3ccf9e 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -66,6 +66,7 @@ namespace TerminalApp Boolean FocusMode { get; }; Boolean Fullscreen { get; }; + void Maximized(Boolean newMaximized); Boolean AlwaysOnTop { get; }; void IdentifyWindow(); @@ -114,6 +115,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler RequestedThemeChanged; event Windows.Foundation.TypedEventHandler FocusModeChanged; event Windows.Foundation.TypedEventHandler FullscreenChanged; + event Windows.Foundation.TypedEventHandler ChangeMaximizeRequested; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; event Windows.Foundation.TypedEventHandler RaiseVisualBell; event Windows.Foundation.TypedEventHandler SetTaskbarProgress; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 9d795514cc7..be3717e7c4b 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1482,6 +1482,13 @@ namespace winrt::TerminalApp::implementation WindowLayout layout{}; layout.TabLayout(winrt::single_threaded_vector(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(_tabContent.ActualWidth()); const float contentHeight = ::base::saturated_cast(_tabContent.ActualHeight()); @@ -2607,10 +2614,10 @@ namespace winrt::TerminalApp::implementation // - 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()) @@ -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. @@ -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); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 2cbd93e97b5..bf570d7e0eb 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -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& actions); @@ -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); @@ -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 }; @@ -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; diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index fc5203d81fc..14ba0743d12 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -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()) diff --git a/src/cascadia/TerminalSettingsEditor/Launch.cpp b/src/cascadia/TerminalSettingsEditor/Launch.cpp index dcde4c9fe4d..d5c232faa35 100644 --- a/src/cascadia/TerminalSettingsEditor/Launch.cpp +++ b/src/cascadia/TerminalSettingsEditor/Launch.cpp @@ -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 diff --git a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw index 6304be967d8..25af7bfbe4c 100644 --- a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw @@ -919,6 +919,18 @@ Maximized focus An option to choose from for the "launch mode" setting. Opens the app maximized and in focus mode. + + Maximized full screen + An option to choose from for the "launch mode" setting. Opens the app maximized and in full screen. + + + Full screen focus + An option to choose from for the "launch mode" setting. Opens the app in full screen and in focus mode. + + + Maximized full screen focus + An option to choose from for the "launch mode" setting. Opens the app maximized in full screen and in focus mode. + Bell notification style 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). diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index 2ae6bb6da3b..28b0a656e5e 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -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" }; @@ -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") }, diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp index d713825cde8..2ce75db24df 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp @@ -18,6 +18,9 @@ #include "SendInputArgs.g.cpp" #include "SplitPaneArgs.g.cpp" #include "OpenSettingsArgs.g.cpp" +#include "SetFocusModeArgs.g.cpp" +#include "SetFullScreenArgs.g.cpp" +#include "SetMaximizedArgs.g.cpp" #include "SetColorSchemeArgs.g.cpp" #include "SetTabColorArgs.g.cpp" #include "RenameTabArgs.g.cpp" @@ -455,6 +458,33 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } } + winrt::hstring SetFocusModeArgs::GenerateName() const + { + if (IsFocusMode()) + { + return RS_(L"EnableFocusModeCommandKey"); + } + return RS_(L"DisableFocusModeCommandKey"); + } + + winrt::hstring SetFullScreenArgs::GenerateName() const + { + if (IsFullScreen()) + { + return RS_(L"EnableFullScreenCommandKey"); + } + return RS_(L"DisableFullScreenCommandKey"); + } + + winrt::hstring SetMaximizedArgs::GenerateName() const + { + if (IsMaximized()) + { + return RS_(L"EnableMaximizedCommandKey"); + } + return RS_(L"DisableMaximizedCommandKey"); + } + winrt::hstring SetColorSchemeArgs::GenerateName() const { // "Set color scheme to "{_SchemeName}"" diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index e578afb4390..1da433ca092 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -18,6 +18,9 @@ #include "SendInputArgs.g.h" #include "SplitPaneArgs.g.h" #include "OpenSettingsArgs.g.h" +#include "SetFocusModeArgs.g.h" +#include "SetFullScreenArgs.g.h" +#include "SetMaximizedArgs.g.h" #include "SetColorSchemeArgs.g.h" #include "SetTabColorArgs.g.h" #include "RenameTabArgs.g.h" @@ -119,6 +122,22 @@ private: #define OPEN_SETTINGS_ARGS(X) \ X(SettingsTarget, Target, "target", false, SettingsTarget::SettingsFile) +//////////////////////////////////////////////////////////////////////////////// +#define SET_FOCUS_MODE_ARGS(X) \ + X(bool, IsFocusMode, "isFocusMode", false, false) + +//////////////////////////////////////////////////////////////////////////////// +#define SET_MAXIMIZED_ARGS(X) \ + X(bool, IsMaximized, "isMaximized", false, false) + +//////////////////////////////////////////////////////////////////////////////// +#define SET_FULL_SCREEN_ARGS(X) \ + X(bool, IsFullScreen, "isFullScreen", false, false) + +//////////////////////////////////////////////////////////////////////////////// +#define SET_MAXIMIZED_ARGS(X) \ + X(bool, IsMaximized, "isMaximized", false, false) + //////////////////////////////////////////////////////////////////////////////// #define SET_COLOR_SCHEME_ARGS(X) \ X(winrt::hstring, SchemeName, "colorScheme", args->SchemeName().empty(), L"") @@ -549,6 +568,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation ACTION_ARGS_STRUCT(OpenSettingsArgs, OPEN_SETTINGS_ARGS); + ACTION_ARGS_STRUCT(SetFocusModeArgs, SET_FOCUS_MODE_ARGS); + + ACTION_ARGS_STRUCT(SetFullScreenArgs, SET_FULL_SCREEN_ARGS); + + ACTION_ARGS_STRUCT(SetMaximizedArgs, SET_MAXIMIZED_ARGS); + ACTION_ARGS_STRUCT(SetColorSchemeArgs, SET_COLOR_SCHEME_ARGS); ACTION_ARGS_STRUCT(SetTabColorArgs, SET_TAB_COLOR_ARGS); @@ -662,8 +687,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation BASIC_FACTORY(MoveFocusArgs); BASIC_FACTORY(MovePaneArgs); BASIC_FACTORY(SetTabColorArgs); + BASIC_FACTORY(RenameTabArgs); BASIC_FACTORY(SwapPaneArgs); BASIC_FACTORY(SplitPaneArgs); + BASIC_FACTORY(SetFocusModeArgs); + BASIC_FACTORY(SetFullScreenArgs); + BASIC_FACTORY(SetMaximizedArgs); BASIC_FACTORY(SetColorSchemeArgs); BASIC_FACTORY(RenameWindowArgs); BASIC_FACTORY(ExecuteCommandlineArgs); diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index 457feefced7..576e3704f96 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -207,6 +207,24 @@ namespace Microsoft.Terminal.Settings.Model SettingsTarget Target { get; }; }; + [default_interface] runtimeclass SetFocusModeArgs : IActionArgs + { + SetFocusModeArgs(Boolean isFocusMode); + Boolean IsFocusMode { get; }; + }; + + [default_interface] runtimeclass SetFullScreenArgs : IActionArgs + { + SetFullScreenArgs(Boolean isFullScreen); + Boolean IsFullScreen { get; }; + }; + + [default_interface] runtimeclass SetMaximizedArgs : IActionArgs + { + SetMaximizedArgs(Boolean isMaximized); + Boolean IsMaximized { get; }; + }; + [default_interface] runtimeclass SetColorSchemeArgs : IActionArgs { SetColorSchemeArgs(String name); @@ -221,6 +239,7 @@ namespace Microsoft.Terminal.Settings.Model [default_interface] runtimeclass RenameTabArgs : IActionArgs { + RenameTabArgs(String title); String Title { get; }; }; diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index aa06ae70cda..bab2ab0fd74 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -57,6 +57,9 @@ ON_ALL_ACTIONS(ToggleFullscreen) \ ON_ALL_ACTIONS(ToggleAlwaysOnTop) \ ON_ALL_ACTIONS(OpenSettings) \ + ON_ALL_ACTIONS(SetFocusMode) \ + ON_ALL_ACTIONS(SetFullScreen) \ + ON_ALL_ACTIONS(SetMaximized) \ ON_ALL_ACTIONS(SetColorScheme) \ ON_ALL_ACTIONS(SetTabColor) \ ON_ALL_ACTIONS(OpenTabColorPicker) \ @@ -101,6 +104,9 @@ ON_ALL_ACTIONS_WITH_ARGS(NewWindow) \ ON_ALL_ACTIONS_WITH_ARGS(NextTab) \ ON_ALL_ACTIONS_WITH_ARGS(OpenSettings) \ + ON_ALL_ACTIONS_WITH_ARGS(SetFocusMode) \ + ON_ALL_ACTIONS_WITH_ARGS(SetFullScreen) \ + ON_ALL_ACTIONS_WITH_ARGS(SetMaximized) \ ON_ALL_ACTIONS_WITH_ARGS(PrevTab) \ ON_ALL_ACTIONS_WITH_ARGS(RenameTab) \ ON_ALL_ACTIONS_WITH_ARGS(RenameWindow) \ diff --git a/src/cascadia/TerminalSettingsModel/ApplicationState.cpp b/src/cascadia/TerminalSettingsModel/ApplicationState.cpp index d623ced2974..00ca7fb1694 100644 --- a/src/cascadia/TerminalSettingsModel/ApplicationState.cpp +++ b/src/cascadia/TerminalSettingsModel/ApplicationState.cpp @@ -17,6 +17,7 @@ static constexpr std::wstring_view elevatedStateFileName{ L"elevated-state.json" static constexpr std::string_view TabLayoutKey{ "tabLayout" }; static constexpr std::string_view InitialPositionKey{ "initialPosition" }; static constexpr std::string_view InitialSizeKey{ "initialSize" }; +static constexpr std::string_view LaunchModeKey{ "launchMode" }; namespace Microsoft::Terminal::Settings::Model::JsonUtils { @@ -31,6 +32,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils GetValueForKey(json, TabLayoutKey, layout->_TabLayout); GetValueForKey(json, InitialPositionKey, layout->_InitialPosition); + GetValueForKey(json, LaunchModeKey, layout->_LaunchMode); GetValueForKey(json, InitialSizeKey, layout->_InitialSize); return *layout; @@ -47,6 +49,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils SetValueForKey(json, TabLayoutKey, val.TabLayout()); SetValueForKey(json, InitialPositionKey, val.InitialPosition()); + SetValueForKey(json, LaunchModeKey, val.LaunchMode()); SetValueForKey(json, InitialSizeKey, val.InitialSize()); return json; diff --git a/src/cascadia/TerminalSettingsModel/ApplicationState.h b/src/cascadia/TerminalSettingsModel/ApplicationState.h index 1c0943cfee2..a5e607e0b17 100644 --- a/src/cascadia/TerminalSettingsModel/ApplicationState.h +++ b/src/cascadia/TerminalSettingsModel/ApplicationState.h @@ -49,6 +49,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation WINRT_PROPERTY(Windows::Foundation::Collections::IVector, TabLayout, nullptr); WINRT_PROPERTY(winrt::Windows::Foundation::IReference, InitialPosition, nullptr); WINRT_PROPERTY(winrt::Windows::Foundation::IReference, InitialSize, nullptr); + WINRT_PROPERTY(winrt::Windows::Foundation::IReference, LaunchMode, nullptr); friend ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait; }; diff --git a/src/cascadia/TerminalSettingsModel/ApplicationState.idl b/src/cascadia/TerminalSettingsModel/ApplicationState.idl index b88ec144a92..13ea22bf0d3 100644 --- a/src/cascadia/TerminalSettingsModel/ApplicationState.idl +++ b/src/cascadia/TerminalSettingsModel/ApplicationState.idl @@ -22,6 +22,7 @@ namespace Microsoft.Terminal.Settings.Model Windows.Foundation.Collections.IVector TabLayout; Windows.Foundation.IReference InitialPosition; Windows.Foundation.IReference InitialSize; + Windows.Foundation.IReference LaunchMode; }; [default_interface] runtimeclass ApplicationState { diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl index 09448b57971..90e11994320 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl @@ -18,13 +18,14 @@ namespace Microsoft.Terminal.Settings.Model Windows.Foundation.IReference Y; }; + [flags] enum LaunchMode { - DefaultMode, - MaximizedMode, - FullscreenMode, - FocusMode, - MaximizedFocusMode, + DefaultMode = 0, + MaximizedMode = 1, + FullscreenMode = 2, + FocusMode = 4, + MaximizedFocusMode = 5 }; enum WindowingMode diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index 4bbe30f88e4..5ae1853a7e3 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -414,9 +414,27 @@ Toggle focus mode "Focus mode" is a mode with minimal UI elements, for a distraction-free experience + + Enable focus mode + + + Disable focus mode + Toggle fullscreen + + Enable fullscreen + + + Disable fullscreen + + + Maximize window + + + Restore maximized window + Toggle pane split orientation diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h index 3f98b0d7d69..26a83e0e42f 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h @@ -219,12 +219,15 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FirstWindowPrefe JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::LaunchMode) { - JSON_MAPPINGS(5) = { + JSON_MAPPINGS(8) = { pair_type{ "default", ValueType::DefaultMode }, pair_type{ "maximized", ValueType::MaximizedMode }, pair_type{ "fullscreen", ValueType::FullscreenMode }, + pair_type{ "maximizedFullscreen", ValueType::MaximizedMode | ValueType::FullscreenMode }, pair_type{ "focus", ValueType::FocusMode }, pair_type{ "maximizedFocus", ValueType::MaximizedFocusMode }, + pair_type{ "fullscreenFocus", ValueType::FullscreenMode | ValueType::FocusMode }, + pair_type{ "maximizedFullscreenFocus", ValueType::MaximizedMode | ValueType::FullscreenMode | ValueType::FocusMode }, }; }; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index cc4654cb060..2cc5af706ab 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -327,6 +327,14 @@ void AppHost::Initialize() _logic.AlwaysOnTopChanged({ this, &AppHost::_AlwaysOnTopChanged }); _logic.RaiseVisualBell({ this, &AppHost::_RaiseVisualBell }); _logic.SystemMenuChangeRequested({ this, &AppHost::_SystemMenuChangeRequested }); + _logic.ChangeMaximizeRequested({ this, &AppHost::_ChangeMaximizeRequested }); + + _window->MaximizeChanged([this](bool newMaximize) { + if (_logic) + { + _logic.Maximized(newMaximize); + } + }); _logic.Create(); @@ -640,6 +648,29 @@ void AppHost::_FullscreenChanged(const winrt::Windows::Foundation::IInspectable& _window->FullscreenChanged(_logic.Fullscreen()); } +void AppHost::_ChangeMaximizeRequested(const winrt::Windows::Foundation::IInspectable&, + const winrt::Windows::Foundation::IInspectable&) +{ + if (const auto handle = _window->GetHandle()) + { + // Shamelessly copied from TitlebarControl::_OnMaximizeOrRestore + // since there doesn't seem to be another way to handle this + POINT point1 = {}; + ::GetCursorPos(&point1); + const LPARAM lParam = MAKELPARAM(point1.x, point1.y); + WINDOWPLACEMENT placement = { sizeof(placement) }; + ::GetWindowPlacement(handle, &placement); + if (placement.showCmd == SW_SHOWNORMAL) + { + ::PostMessage(handle, WM_SYSCOMMAND, SC_MAXIMIZE, lParam); + } + else if (placement.showCmd == SW_SHOWMAXIMIZED) + { + ::PostMessage(handle, WM_SYSCOMMAND, SC_RESTORE, lParam); + } + } +} + void AppHost::_AlwaysOnTopChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index d2cd637e07e..debc0c3a807 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -48,6 +48,8 @@ class AppHost const winrt::Windows::Foundation::IInspectable& arg); void _FullscreenChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& arg); + void _ChangeMaximizeRequested(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable& arg); void _AlwaysOnTopChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& arg); void _RaiseVisualBell(const winrt::Windows::Foundation::IInspectable& sender, diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 8724d9aa6b4..87a4d345371 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -156,7 +156,7 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce } int nCmdShow = SW_SHOW; - if (launchMode == LaunchMode::MaximizedMode || launchMode == LaunchMode::MaximizedFocusMode) + if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode)) { nCmdShow = SW_MAXIMIZE; } @@ -471,6 +471,11 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize } case WM_SIZE: { + if (wparam == SIZE_RESTORED || wparam == SIZE_MAXIMIZED) + { + _MaximizeChangedHandlers(wparam == SIZE_MAXIMIZED); + } + if (wparam == SIZE_MINIMIZED && _isQuakeWindow) { ShowWindow(GetHandle(), SW_HIDE); @@ -613,6 +618,13 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize } case WM_SYSCOMMAND: { + // the low 4 bits contain additional information (that we don't care about) + auto highBits = wparam & 0xFFF0; + if (highBits == SC_RESTORE || highBits == SC_MAXIMIZE) + { + _MaximizeChangedHandlers(highBits == SC_MAXIMIZE); + } + if (wparam == SC_RESTORE && _fullscreen) { _ShouldExitFullscreenHandlers(); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 4cdb033ee3e..ed620925106 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -73,6 +73,7 @@ class IslandWindow : WINRT_CALLBACK(NotifyNotificationIconMenuItemSelected, winrt::delegate); WINRT_CALLBACK(NotifyReAddNotificationIcon, winrt::delegate); WINRT_CALLBACK(ShouldExitFullscreen, winrt::delegate); + WINRT_CALLBACK(MaximizeChanged, winrt::delegate); WINRT_CALLBACK(WindowMoved, winrt::delegate);