diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 45ae9c79acc..6f8faa77e69 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -2526,6 +2526,11 @@ "description": "When set to true, the Terminal's tab row will display a shield icon when the Terminal is running with administrator privileges", "type": "boolean" }, + "showTabsFullscreen": { + "default": false, + "description": "When set to true, tabs remain visible in fullscreen mode. When set to false, tabs will be hidden when entering fullscreen mode.", + "type": "boolean" + }, "useAcrylicInTabRow": { "default": false, "description": "When set to true, the tab row will have an acrylic material background with 50% opacity.", diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp index 0eba4511a92..cf0df031750 100644 --- a/src/cascadia/TerminalApp/TabManagement.cpp +++ b/src/cascadia/TerminalApp/TabManagement.cpp @@ -243,10 +243,12 @@ namespace winrt::TerminalApp::implementation // - Handle changes in tab layout. void TerminalPage::_UpdateTabView() { - // Never show the tab row when we're fullscreen. Otherwise: - // Show tabs when there's more than 1, or the user has chosen to always - // show the tab bar. - const auto isVisible = (!_isFullscreen && !_isInFocusMode) && + // The tab row should only be visible if: + // - we're not in focus mode + // - we're not in full screen, or the user has enabled fullscreen tabs + // - there is more than one tab, or the user has chosen to always show tabs + const auto isVisible = !_isInFocusMode && + (!_isFullscreen || _showTabsFullscreen) && (_settings.GlobalSettings().ShowTabsInTitlebar() || (_tabs.Size() > 1) || _settings.GlobalSettings().AlwaysShowTabs()); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index d48ac1cfb03..dc6961a23c3 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -270,6 +270,7 @@ namespace winrt::TerminalApp::implementation _layoutUpdatedRevoker = _tabContent.LayoutUpdated(winrt::auto_revoke, { this, &TerminalPage::_OnFirstLayout }); _isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop(); + _showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen(); // DON'T set up Toasts/TeachingTips here. They should be loaded and // initialized the first time they're opened, in whatever method opens @@ -3605,6 +3606,8 @@ namespace winrt::TerminalApp::implementation _isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop(); AlwaysOnTopChanged.raise(*this, nullptr); + _showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen(); + // Settings AllowDependentAnimations will affect whether animations are // enabled application-wide, so we don't need to check it each time we // want to create an animation. @@ -4029,6 +4032,37 @@ namespace winrt::TerminalApp::implementation return _isAlwaysOnTop; } + // Method Description: + // - Returns true if the tab row should be visible when we're in full screen + // state. + // Arguments: + // - + // Return Value: + // - true if the tab row should be visible in full screen state + bool TerminalPage::ShowTabsFullscreen() const + { + return _showTabsFullscreen; + } + + // Method Description: + // - Updates the visibility of the tab row when in fullscreen state. + void TerminalPage::SetShowTabsFullscreen(bool newShowTabsFullscreen) + { + if (_showTabsFullscreen == newShowTabsFullscreen) + { + return; + } + + _showTabsFullscreen = newShowTabsFullscreen; + + // if we're currently in fullscreen, update tab view to make + // sure tabs are given the correct visibility + if (_isFullscreen) + { + _UpdateTabView(); + } + } + void TerminalPage::SetFullscreen(bool newFullscreen) { if (_isFullscreen == newFullscreen) diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 09b3fa8a952..8abbd2187b7 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -135,6 +135,8 @@ namespace winrt::TerminalApp::implementation bool FocusMode() const; bool Fullscreen() const; bool AlwaysOnTop() const; + bool ShowTabsFullscreen() const; + void SetShowTabsFullscreen(bool newShowTabsFullscreen); void SetFullscreen(bool); void SetFocusMode(const bool inFocusMode); void Maximized(bool newMaximized); @@ -244,6 +246,7 @@ namespace winrt::TerminalApp::implementation bool _isFullscreen{ false }; bool _isMaximized{ false }; bool _isAlwaysOnTop{ false }; + bool _showTabsFullscreen{ false }; std::optional _loadFromPersistedLayoutIdx{}; diff --git a/src/cascadia/TerminalApp/TerminalWindow.cpp b/src/cascadia/TerminalApp/TerminalWindow.cpp index 5f16e5a66be..6998d6a217d 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.cpp +++ b/src/cascadia/TerminalApp/TerminalWindow.cpp @@ -288,6 +288,11 @@ namespace winrt::TerminalApp::implementation return _settings.GlobalSettings().AlwaysOnTop(); } + bool TerminalWindow::GetInitialShowTabsFullscreen() + { + return _settings.GlobalSettings().ShowTabsFullscreen(); + } + bool TerminalWindow::GetMinimizeToNotificationArea() { return _settings.GlobalSettings().MinimizeToNotificationArea(); @@ -1009,6 +1014,11 @@ namespace winrt::TerminalApp::implementation return _root ? _root->AlwaysOnTop() : false; } + bool TerminalWindow::ShowTabsFullscreen() const + { + return _root ? _root->ShowTabsFullscreen() : false; + } + void TerminalWindow::SetSettingsStartupArgs(const std::vector& actions) { for (const auto& action : actions) diff --git a/src/cascadia/TerminalApp/TerminalWindow.h b/src/cascadia/TerminalApp/TerminalWindow.h index 29eda951587..695dea305d0 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.h +++ b/src/cascadia/TerminalApp/TerminalWindow.h @@ -93,6 +93,7 @@ namespace winrt::TerminalApp::implementation bool Fullscreen() const; void Maximized(bool newMaximized); bool AlwaysOnTop() const; + bool ShowTabsFullscreen() const; bool AutoHideWindow(); void IdentifyWindow(); @@ -112,6 +113,7 @@ namespace winrt::TerminalApp::implementation Microsoft::Terminal::Settings::Model::LaunchMode GetLaunchMode(); bool GetShowTabsInTitlebar(); bool GetInitialAlwaysOnTop(); + bool GetInitialShowTabsFullscreen(); float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const; Windows::UI::Xaml::UIElement GetRoot() noexcept; diff --git a/src/cascadia/TerminalApp/TerminalWindow.idl b/src/cascadia/TerminalApp/TerminalWindow.idl index 8b1bca78f94..c04027a4f8e 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.idl +++ b/src/cascadia/TerminalApp/TerminalWindow.idl @@ -71,6 +71,7 @@ namespace TerminalApp void Maximized(Boolean newMaximized); Boolean AlwaysOnTop { get; }; Boolean AutoHideWindow { get; }; + Boolean ShowTabsFullscreen { get; }; void IdentifyWindow(); void SetPersistedLayoutIdx(UInt32 idx); @@ -86,6 +87,7 @@ namespace TerminalApp Microsoft.Terminal.Settings.Model.LaunchMode GetLaunchMode(); Boolean GetShowTabsInTitlebar(); Boolean GetInitialAlwaysOnTop(); + Boolean GetInitialShowTabsFullscreen(); Single CalcSnappedDimension(Boolean widthOrHeight, Single dimension); void TitlebarClicked(); void CloseWindow(); diff --git a/src/cascadia/TerminalApp/TitlebarControl.cpp b/src/cascadia/TerminalApp/TitlebarControl.cpp index 1debd030544..1ed82f39ca6 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.cpp +++ b/src/cascadia/TerminalApp/TitlebarControl.cpp @@ -12,6 +12,8 @@ #include "TitlebarControl.g.cpp" +using namespace winrt::Windows::UI::Xaml; + namespace winrt::TerminalApp::implementation { TitlebarControl::TitlebarControl(uint64_t handle) : @@ -77,6 +79,11 @@ namespace winrt::TerminalApp::implementation } } + void TitlebarControl::FullscreenChanged(const bool fullscreen) + { + MinMaxCloseControl().Visibility(fullscreen ? Visibility::Collapsed : Visibility::Visible); + } + void TitlebarControl::_OnMaximizeOrRestore(byte flag) { POINT point1 = {}; diff --git a/src/cascadia/TerminalApp/TitlebarControl.h b/src/cascadia/TerminalApp/TitlebarControl.h index 8020ff90956..1008253ba8d 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.h +++ b/src/cascadia/TerminalApp/TitlebarControl.h @@ -22,6 +22,7 @@ namespace winrt::TerminalApp::implementation void SetWindowVisualState(WindowVisualState visualState); void Root_SizeChanged(const IInspectable& sender, const Windows::UI::Xaml::SizeChangedEventArgs& e); + void FullscreenChanged(const bool fullscreen); void Minimize_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e); void Maximize_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e); diff --git a/src/cascadia/TerminalApp/TitlebarControl.idl b/src/cascadia/TerminalApp/TitlebarControl.idl index b7a06ba987e..8f934fae951 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.idl +++ b/src/cascadia/TerminalApp/TitlebarControl.idl @@ -22,6 +22,7 @@ namespace TerminalApp { TitlebarControl(UInt64 parentWindowHandle); void SetWindowVisualState(WindowVisualState visualState); + void FullscreenChanged(Boolean fullscreen); void HoverButton(CaptionButton button); void PressButton(CaptionButton button); diff --git a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml index f227268613d..854fd733766 100644 --- a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml +++ b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml @@ -64,6 +64,12 @@ Style="{StaticResource ToggleSwitchInExpanderStyle}" /> + + + + + Display a shield in the title bar when Windows Terminal is running as Administrator Header for a control to toggle displaying a shield in the title bar of the app. "Admin" refers to elevated sessions like "run as Admin" + + Show tabs in full screen + Header for a control to toggle if the app should show the tabs when in full screen state. + + + When enabled, the tab bar will be visible when the app is full screen + A description for what the "show tabs in full screen" setting does. + Path translation Name for a control to select how file and directory paths are translated. diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl index e212fc6181c..32ab969645c 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl @@ -57,6 +57,7 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_SETTING(Int32, InitialRows); INHERITABLE_SETTING(Int32, InitialCols); INHERITABLE_SETTING(Boolean, AlwaysShowTabs); + INHERITABLE_SETTING(Boolean, ShowTabsFullscreen); INHERITABLE_SETTING(NewTabPosition, NewTabPosition); INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar); INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs); diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h index 820e426c4d3..55f385b3240 100644 --- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h +++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h @@ -69,7 +69,8 @@ Author(s): X(winrt::Windows::Foundation::Collections::IVector, NewTabMenu, "newTabMenu", winrt::single_threaded_vector({ Model::RemainingProfilesEntry{} })) \ X(bool, AllowHeadless, "compatibility.allowHeadless", false) \ X(bool, IsolatedMode, "compatibility.isolatedMode", false) \ - X(hstring, SearchWebDefaultQueryUrl, "searchWebDefaultQueryUrl", L"https://www.bing.com/search?q=%22%s%22") + X(hstring, SearchWebDefaultQueryUrl, "searchWebDefaultQueryUrl", L"https://www.bing.com/search?q=%22%s%22") \ + X(bool, ShowTabsFullscreen, "showTabsFullscreen", false) // Also add these settings to: // * Profile.idl diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 42c033f3b0c..43eb3cbd0f2 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -300,6 +300,7 @@ void AppHost::Initialize() _window->SetAlwaysOnTop(_windowLogic.GetInitialAlwaysOnTop()); _window->SetAutoHideWindow(_windowLogic.AutoHideWindow()); + _window->SetShowTabsFullscreen(_windowLogic.GetInitialShowTabsFullscreen()); // MORE EVENT HANDLERS HERE! // MAKE SURE THEY ARE ALL: @@ -1212,6 +1213,7 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta _window->SetMinimizeToNotificationAreaBehavior(_windowLogic.GetMinimizeToNotificationArea()); _window->SetAutoHideWindow(_windowLogic.AutoHideWindow()); + _window->SetShowTabsFullscreen(_windowLogic.ShowTabsFullscreen()); _updateTheme(); } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index a604ed53b80..0bcb8426244 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -992,6 +992,11 @@ void IslandWindow::ShowWindowChanged(const bool showOrHide) } } +void IslandWindow::SetShowTabsFullscreen(const bool newShowTabsFullscreen) +{ + _showTabsFullscreen = newShowTabsFullscreen; +} + // Method Description // - Flash the taskbar icon, indicating to the user that something needs their attention void IslandWindow::FlashTaskbar() diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index aac53006677..d6cacd601f3 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -51,6 +51,7 @@ class IslandWindow : void FullscreenChanged(const bool fullscreen); void SetAlwaysOnTop(const bool alwaysOnTop); void ShowWindowChanged(const bool showOrHide); + virtual void SetShowTabsFullscreen(const bool newShowTabsFullscreen); void FlashTaskbar(); void SetTaskbarProgress(const size_t state, const size_t progress); @@ -112,6 +113,7 @@ class IslandWindow : bool _borderless{ false }; bool _alwaysOnTop{ false }; bool _fullscreen{ false }; + bool _showTabsFullscreen{ false }; bool _fWasMaximizedBeforeFullscreen{ false }; RECT _rcWindowBeforeFullscreen{}; RECT _rcWorkBeforeFullscreen{}; @@ -123,6 +125,7 @@ class IslandWindow : virtual void _SetIsBorderless(const bool borderlessEnabled); virtual void _SetIsFullscreen(const bool fullscreenEnabled); + void _RestoreFullscreenPosition(const RECT& rcWork); void _SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork); diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp index 8d4982269bb..76be837b2b3 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp @@ -1137,7 +1137,7 @@ void NonClientIslandWindow::_SetIsBorderless(const bool borderlessEnabled) // Method Description: // - Enable or disable fullscreen mode. When entering fullscreen mode, we'll -// need to manually hide the entire titlebar. +// need to check whether to hide the titlebar. // - See also IslandWindow::_SetIsFullscreen, which does additional work. // Arguments: // - fullscreenEnabled: If true, we're entering fullscreen mode. If false, we're leaving. @@ -1146,10 +1146,7 @@ void NonClientIslandWindow::_SetIsBorderless(const bool borderlessEnabled) void NonClientIslandWindow::_SetIsFullscreen(const bool fullscreenEnabled) { IslandWindow::_SetIsFullscreen(fullscreenEnabled); - if (_titlebar) - { - _titlebar.Visibility(_IsTitlebarVisible() ? Visibility::Visible : Visibility::Collapsed); - } + _UpdateTitlebarVisibility(); // GH#4224 - When the auto-hide taskbar setting is enabled, then we don't // always get another window message to trigger us to remove the drag bar. // So, make sure to update the size of the drag region here, so that it @@ -1157,16 +1154,42 @@ void NonClientIslandWindow::_SetIsFullscreen(const bool fullscreenEnabled) _ResizeDragBarWindow(); } +void NonClientIslandWindow::SetShowTabsFullscreen(const bool newShowTabsFullscreen) +{ + IslandWindow::SetShowTabsFullscreen(newShowTabsFullscreen); + + // don't waste time recalculating UI elements if we're not + // in fullscreen state - this setting doesn't affect other + // window states + if (_fullscreen) + { + _UpdateTitlebarVisibility(); + } +} + +void NonClientIslandWindow::_UpdateTitlebarVisibility() +{ + if (!_titlebar) + { + return; + } + + const auto showTitlebar = _IsTitlebarVisible(); + _titlebar.Visibility(showTitlebar ? Visibility::Visible : Visibility::Collapsed); + _titlebar.FullscreenChanged(_fullscreen); +} + // Method Description: -// - Returns true if the titlebar is visible. For things like fullscreen mode, -// borderless mode (aka "focus mode"), this will return false. +// - Returns true if the titlebar is visible. For borderless mode (aka "focus mode"), +// this will return false. For fullscreen, this will return false unless the user +// has enabled fullscreen tabs. // Arguments: // - // Return Value: -// - true iff the titlebar is visible +// - true if the titlebar is visible bool NonClientIslandWindow::_IsTitlebarVisible() const { - return !(_fullscreen || _borderless); + return !_borderless && (!_fullscreen || _showTabsFullscreen); } void NonClientIslandWindow::SetTitlebarBackground(winrt::Windows::UI::Xaml::Media::Brush brush) diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h index bf9c815237c..22a3bb283ac 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h @@ -51,6 +51,7 @@ class NonClientIslandWindow : public IslandWindow void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) override; void SetTitlebarBackground(winrt::Windows::UI::Xaml::Media::Brush brush); + void SetShowTabsFullscreen(const bool newShowTabsFullscreen) override; virtual void UseMica(const bool newValue, const double titlebarOpacity) override; @@ -97,6 +98,7 @@ class NonClientIslandWindow : public IslandWindow void _UpdateFrameMargins() const noexcept; void _UpdateMaximizedState(); void _UpdateIslandPosition(const UINT windowWidth, const UINT windowHeight); + void _UpdateTitlebarVisibility(); struct Revokers {