Add support for focus mode (#6804)

## Summary of the Pull Request

Add support for "focus" mode, which only displays the actual terminal content, no tabs or titlebar. The edges of the window are draggable to resize, but the window can't be moved in borderless mode.

The window looks _slightly_ different bewteen different values for `showTabsInTitlebar`, because switching between the `NonClientIslandWindow` and the `IslandWindow` is _hard_.

`showTabsInTitlebar` | Preview
-- | --
`true` | ![image](https://user-images.githubusercontent.com/18356694/86639069-f5090080-bf9d-11ea-8b29-fb1e479a078d.png)
`false` | ![image](https://user-images.githubusercontent.com/18356694/86639094-fafee180-bf9d-11ea-8fc0-6804234a5113.png)

## PR Checklist
* [x] Closes #2238 
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

* **KNOWN ISSUE**: Upon resizing the NCIW, the top frame margin disappears, making that border disappear entirely. 6356aaf has a bunch of WIP work for me trying to fix that, but I couldn't get it quite right.

## Validation Steps Performed
* Toggled between focus and fullscreen a _bunch_ in both modes.
This commit is contained in:
Mike Griese 2020-07-13 12:40:20 -05:00 committed by GitHub
parent 89c4ebaafe
commit 1c8e83d52d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 222 additions and 32 deletions

View File

@ -2133,6 +2133,7 @@ SIGDN
SINGLEFLAG
SINGLETHREADED
siup
SIZEBOX
sizeof
SIZESCROLL
SKIPFONT

View File

@ -54,6 +54,7 @@
"scrollUpPage",
"splitPane",
"switchToTab",
"toggleFocusMode",
"toggleFullscreen",
"toggleRetroEffect",
"find",

View File

@ -29,6 +29,7 @@ static constexpr std::string_view ResizePaneKey{ "resizePane" };
static constexpr std::string_view MoveFocusKey{ "moveFocus" };
static constexpr std::string_view FindKey{ "find" };
static constexpr std::string_view ToggleRetroEffectKey{ "toggleRetroEffect" };
static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" };
static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" };
static constexpr std::string_view SetTabColorKey{ "setTabColor" };
static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" };
@ -73,6 +74,7 @@ namespace winrt::TerminalApp::implementation
{ MoveFocusKey, ShortcutAction::MoveFocus },
{ OpenSettingsKey, ShortcutAction::OpenSettings },
{ ToggleRetroEffectKey, ShortcutAction::ToggleRetroEffect },
{ ToggleFocusModeKey, ShortcutAction::ToggleFocusMode },
{ ToggleFullscreenKey, ShortcutAction::ToggleFullscreen },
{ SplitPaneKey, ShortcutAction::SplitPane },
{ SetTabColorKey, ShortcutAction::SetTabColor },
@ -252,6 +254,7 @@ namespace winrt::TerminalApp::implementation
{ ShortcutAction::MoveFocus, RS_(L"MoveFocusCommandKey") },
{ ShortcutAction::OpenSettings, RS_(L"OpenSettingsCommandKey") },
{ ShortcutAction::ToggleRetroEffect, RS_(L"ToggleRetroEffectCommandKey") },
{ ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") },
{ ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") },
{ ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") },
{ ShortcutAction::Invalid, L"" },

View File

@ -239,6 +239,13 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}
void TerminalPage::_HandleToggleFocusMode(const IInspectable& /*sender*/,
const TerminalApp::ActionEventArgs& args)
{
ToggleFocusMode();
args.Handled(true);
}
void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
const TerminalApp::ActionEventArgs& args)
{

View File

@ -104,6 +104,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(SetTitleBarContent, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement, _root, SetTitleBarContent);
FORWARDED_TYPED_EVENT(TitleChanged, winrt::Windows::Foundation::IInspectable, winrt::hstring, _root, TitleChanged);
FORWARDED_TYPED_EVENT(LastTabClosed, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs, _root, LastTabClosed);
FORWARDED_TYPED_EVENT(ToggleFocusMode, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFocusModeEventArgs, _root, ToggleFocusMode);
FORWARDED_TYPED_EVENT(ToggleFullscreen, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFullscreenEventArgs, _root, ToggleFullscreen);
};
}

View File

@ -59,5 +59,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.ElementTheme> RequestedThemeChanged;
event Windows.Foundation.TypedEventHandler<Object, ToggleFullscreenEventArgs> ToggleFullscreen;
event Windows.Foundation.TypedEventHandler<Object, ToggleFocusModeEventArgs> ToggleFocusMode;
}
}

View File

@ -380,6 +380,10 @@
<data name="CloseWindowCommandKey" xml:space="preserve">
<value>Close window</value>
</data>
<data name="ToggleFocusModeCommandKey" xml:space="preserve">
<value>Toggle focus mode</value>
<comment>"Focus mode" is a mode with minimal UI elements, for a distraction-free experience</comment>
</data>
<data name="ToggleFullscreenCommandKey" xml:space="preserve">
<value>Toggle fullscreen</value>
</data>

View File

@ -159,6 +159,11 @@ namespace winrt::TerminalApp::implementation
_ToggleRetroEffectHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ToggleFocusMode:
{
_ToggleFocusModeHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ToggleFullscreen:
{
_ToggleFullscreenHandlers(*this, *eventArgs);

View File

@ -47,6 +47,7 @@ namespace winrt::TerminalApp::implementation
TYPED_EVENT(Find, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(MoveFocus, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ToggleRetroEffect, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ToggleFocusMode, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ToggleFullscreen, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ToggleCommandPalette, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(SetTabColor, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);

View File

@ -32,6 +32,7 @@ namespace TerminalApp
MoveFocus,
Find,
ToggleRetroEffect,
ToggleFocusMode,
ToggleFullscreen,
SetTabColor,
OpenTabColorPicker,
@ -75,6 +76,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> Find;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> MoveFocus;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleRetroEffect;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleFocusMode;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleFullscreen;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleCommandPalette;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> SetTabColor;

View File

@ -850,6 +850,7 @@ namespace winrt::TerminalApp::implementation
_actionDispatch->Find({ this, &TerminalPage::_HandleFind });
_actionDispatch->ResetFontSize({ this, &TerminalPage::_HandleResetFontSize });
_actionDispatch->ToggleRetroEffect({ this, &TerminalPage::_HandleToggleRetroEffect });
_actionDispatch->ToggleFocusMode({ this, &TerminalPage::_HandleToggleFocusMode });
_actionDispatch->ToggleFullscreen({ this, &TerminalPage::_HandleToggleFullscreen });
_actionDispatch->ToggleCommandPalette({ this, &TerminalPage::_HandleToggleCommandPalette });
_actionDispatch->SetTabColor({ this, &TerminalPage::_HandleSetTabColor });
@ -911,7 +912,7 @@ namespace winrt::TerminalApp::implementation
// 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 bool isVisible = (!_isFullscreen) &&
const bool isVisible = (!_isFullscreen && !_isInFocusMode) &&
(_settings->GlobalSettings().ShowTabsInTitlebar() ||
(_tabs.Size() > 1) ||
_settings->GlobalSettings().AlwaysShowTabs());
@ -1966,6 +1967,22 @@ namespace winrt::TerminalApp::implementation
termControl.CreateSearchBoxControl();
}
// Method Description:
// - Toggles borderless mode. Hides the tab row, and raises our
// ToggleFocusMode event.
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::ToggleFocusMode()
{
_toggleFocusModeHandlers(*this, nullptr);
_isInFocusMode = !_isInFocusMode;
_UpdateTabView();
}
// Method Description:
// - Toggles fullscreen mode. Hides the tab row, and raises our
// ToggleFullscreen event.
@ -2176,5 +2193,6 @@ namespace winrt::TerminalApp::implementation
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, SetTitleBarContent, _setTitleBarContentHandlers, winrt::Windows::Foundation::IInspectable, UIElement);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, ToggleFocusMode, _toggleFocusModeHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFocusModeEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, ToggleFullscreen, _toggleFullscreenHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFullscreenEventArgs);
}

View File

@ -49,6 +49,7 @@ namespace winrt::TerminalApp::implementation
void CloseWindow();
void ToggleFocusMode();
void ToggleFullscreen();
void SetStartupActions(std::deque<winrt::TerminalApp::ActionAndArgs>& actions);
@ -60,6 +61,7 @@ namespace winrt::TerminalApp::implementation
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTitleBarContent, _setTitleBarContentHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(ToggleFocusMode, _toggleFocusModeHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFocusModeEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(ToggleFullscreen, _toggleFullscreenHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFullscreenEventArgs);
TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);
@ -83,6 +85,7 @@ namespace winrt::TerminalApp::implementation
winrt::com_ptr<Tab> _GetStrongTabImpl(const uint32_t index) const;
winrt::com_ptr<Tab> _GetStrongTabImpl(const ::winrt::TerminalApp::Tab& tab) const;
bool _isInFocusMode{ false };
bool _isFullscreen{ false };
bool _rearranging;
@ -206,6 +209,7 @@ namespace winrt::TerminalApp::implementation
void _HandleFind(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleResetFontSize(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleToggleRetroEffect(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleToggleFocusMode(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleToggleFullscreen(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleSetTabColor(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleOpenTabColorPicker(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);

View File

@ -5,6 +5,7 @@ namespace TerminalApp
{
delegate void LastTabClosedEventArgs();
delegate void ToggleFullscreenEventArgs();
delegate void ToggleFocusModeEventArgs();
interface IDialogPresenter
{
@ -28,6 +29,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<Object, ToggleFullscreenEventArgs> ToggleFullscreen;
event Windows.Foundation.TypedEventHandler<Object, ToggleFocusModeEventArgs> ToggleFocusMode;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.RoutedEventArgs> Initialized;
}
}

View File

@ -277,6 +277,7 @@
{ "command": "closeWindow", "keys": "alt+f4" },
{ "command": "toggleFullscreen", "keys": "alt+enter" },
{ "command": "toggleFullscreen", "keys": "f11" },
{ "command": "toggleFocusMode" },
{ "command": "openNewTabDropdown", "keys": "ctrl+shift+space" },
{ "command": "openSettings", "keys": "ctrl+," },
{ "command": { "action": "openSettings", "target": "defaultsFile" }, "keys": "ctrl+alt+," },

View File

@ -157,6 +157,7 @@ void AppHost::Initialize()
_logic.RequestedThemeChanged({ this, &AppHost::_UpdateTheme });
_logic.ToggleFullscreen({ this, &AppHost::_ToggleFullscreen });
_logic.ToggleFocusMode({ this, &AppHost::_ToggleFocusMode });
_logic.Create();
@ -352,6 +353,12 @@ void AppHost::_UpdateTheme(const winrt::Windows::Foundation::IInspectable&, cons
_window->OnApplicationThemeChanged(arg);
}
void AppHost::_ToggleFocusMode(const winrt::Windows::Foundation::IInspectable&,
const winrt::TerminalApp::ToggleFocusModeEventArgs&)
{
_window->ToggleFocusMode();
}
void AppHost::_ToggleFullscreen(const winrt::Windows::Foundation::IInspectable&,
const winrt::TerminalApp::ToggleFullscreenEventArgs&)
{

View File

@ -33,6 +33,8 @@ private:
const winrt::Windows::UI::Xaml::UIElement& arg);
void _UpdateTheme(const winrt::Windows::Foundation::IInspectable&,
const winrt::Windows::UI::Xaml::ElementTheme& arg);
void _ToggleFocusMode(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::TerminalApp::ToggleFocusModeEventArgs& arg);
void _ToggleFullscreen(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::TerminalApp::ToggleFullscreenEventArgs& arg);
void _WindowMouseWheeled(const til::point coord, const int32_t delta);

View File

@ -441,6 +441,17 @@ void IslandWindow::OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::Ele
::InvalidateRect(_window.get(), nullptr, false);
}
// Method Description:
// - Toggles our focus mode state. See _SetIsBorderless for more details.
// Arguments:
// - <none>
// Return Value:
// - <none>
void IslandWindow::ToggleFocusMode()
{
_SetIsBorderless(!_borderless);
}
// Method Description:
// - Toggles our fullscreen state. See _SetIsFullscreen for more details.
// Arguments:
@ -471,16 +482,106 @@ void _SetWindowLongWHelper(const HWND hWnd, const int nIndex, const LONG dwNewLo
}
}
// Method Description:
// - This is a helper to figure out what the window styles should be, given the
// current state of flags like borderless mode and fullscreen mode.
// Arguments:
// - <none>
// Return Value:
// - a LONG with the appropriate flags set for our current window mode, to be used with GWL_STYLE
LONG IslandWindow::_getDesiredWindowStyle() const
{
auto windowStyle = GetWindowLongW(GetHandle(), GWL_STYLE);
// If we're both fullscreen and borderless, fullscreen mode takes precedence.
if (_fullscreen)
{
// When moving to fullscreen, remove WS_OVERLAPPEDWINDOW, which specifies
// styles for non-fullscreen windows (e.g. caption bar), and add the
// WS_POPUP style to allow us to size ourselves to the monitor size.
// Do the reverse when restoring from fullscreen.
// Doing these modifications to that window will cause a vista-style
// window frame to briefly appear when entering and exiting fullscreen.
WI_ClearFlag(windowStyle, WS_BORDER);
WI_ClearFlag(windowStyle, WS_SIZEBOX);
WI_ClearAllFlags(windowStyle, WS_OVERLAPPEDWINDOW);
WI_SetFlag(windowStyle, WS_POPUP);
return windowStyle;
}
else if (_borderless)
{
// When moving to borderless, remove WS_OVERLAPPEDWINDOW, which
// specifies styles for non-fullscreen windows (e.g. caption bar), and
// add the WS_BORDER and WS_SIZEBOX styles. This allows us to still have
// a small resizing frame, but without a full titlebar, nor caption
// buttons.
WI_ClearAllFlags(windowStyle, WS_OVERLAPPEDWINDOW);
WI_ClearFlag(windowStyle, WS_POPUP);
WI_SetFlag(windowStyle, WS_BORDER);
WI_SetFlag(windowStyle, WS_SIZEBOX);
return windowStyle;
}
// Here, we're not in either fullscreen or borderless mode. Return to
// WS_OVERLAPPEDWINDOW.
WI_ClearFlag(windowStyle, WS_POPUP);
WI_ClearFlag(windowStyle, WS_BORDER);
WI_ClearFlag(windowStyle, WS_SIZEBOX);
WI_SetAllFlags(windowStyle, WS_OVERLAPPEDWINDOW);
return windowStyle;
}
// Method Description:
// - Enable or disable focus mode. When entering focus mode, we'll
// need to manually hide the entire titlebar.
// - When we're entering focus we need to do some additional modification
// of our window styles. However, the NonClientIslandWindow very explicitly
// _doesn't_ need to do these steps.
// Arguments:
// - borderlessEnabled: If true, we're entering focus mode. If false, we're leaving.
// Return Value:
// - <none>
void IslandWindow::_SetIsBorderless(const bool borderlessEnabled)
{
_borderless = borderlessEnabled;
HWND const hWnd = GetHandle();
// First, modify regular window styles as appropriate
auto windowStyle = _getDesiredWindowStyle();
_SetWindowLongWHelper(hWnd, GWL_STYLE, windowStyle);
// Now modify extended window styles as appropriate
// When moving to fullscreen, remove the window edge style to avoid an
// ugly border when not focused.
auto exWindowStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
WI_UpdateFlag(exWindowStyle, WS_EX_WINDOWEDGE, !_fullscreen);
_SetWindowLongWHelper(hWnd, GWL_EXSTYLE, exWindowStyle);
// Resize the window, with SWP_FRAMECHANGED, to trigger user32 to
// recalculate the non/client areas
const til::rectangle windowPos{ GetWindowRect() };
SetWindowPos(GetHandle(),
HWND_TOP,
windowPos.left<int>(),
windowPos.top<int>(),
windowPos.width<int>(),
windowPos.height<int>(),
SWP_SHOWWINDOW | SWP_FRAMECHANGED);
}
// Method Description:
// - Controls setting us into or out of fullscreen mode. Largely taken from
// Window::SetIsFullscreen in conhost.
// - When entering fullscreen mode, we'll save the current window size and
// location, and expand to take the entire monitor size. When leaving, we'll
// use that saved size to restore back to.
// - When we're entering fullscreen we need to do some additional modification
// of our window styles. However, the NonClientIslandWindow very explicitly
// _doesn't_ need to do these steps. Subclasses should override
// _ShouldUpdateStylesOnFullscreen to disable setting these window styles.
// Arguments:
// - fullscreenEnabled true if we should enable fullscreen mode, false to disable.
// Return Value:
@ -496,25 +597,7 @@ void IslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
HWND const hWnd = GetHandle();
// First, modify regular window styles as appropriate
auto windowStyle = GetWindowLongW(hWnd, GWL_STYLE);
// When moving to fullscreen, remove WS_OVERLAPPEDWINDOW, which specifies
// styles for non-fullscreen windows (e.g. caption bar), and add the
// WS_POPUP style to allow us to size ourselves to the monitor size.
// Do the reverse when restoring from fullscreen.
// Doing these modifications to that window will cause a vista-style
// window frame to briefly appear when entering and exiting fullscreen.
if (_fullscreen)
{
WI_ClearAllFlags(windowStyle, WS_OVERLAPPEDWINDOW);
WI_SetFlag(windowStyle, WS_POPUP);
}
else
{
WI_ClearFlag(windowStyle, WS_POPUP);
WI_SetAllFlags(windowStyle, WS_OVERLAPPEDWINDOW);
}
auto windowStyle = _getDesiredWindowStyle();
_SetWindowLongWHelper(hWnd, GWL_STYLE, windowStyle);
// Now modify extended window styles as appropriate
@ -524,6 +607,8 @@ void IslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
WI_UpdateFlag(exWindowStyle, WS_EX_WINDOWEDGE, !_fullscreen);
_SetWindowLongWHelper(hWnd, GWL_EXSTYLE, exWindowStyle);
// When entering/exiting fullscreen mode, we also need to backup/restore the
// current window size, and resize the window to match the new state.
_BackupWindowSizes(oldIsInFullscreen);
_ApplyWindowSize();
}

View File

@ -32,6 +32,7 @@ public:
void SetCreateCallback(std::function<void(const HWND, const RECT, winrt::TerminalApp::LaunchMode& launchMode)> pfn) noexcept;
void SetSnapDimensionCallback(std::function<float(bool widthOrHeight, float dimension)> pfn) noexcept;
void ToggleFocusMode();
void ToggleFullscreen();
#pragma endregion
@ -60,14 +61,18 @@ protected:
void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept;
[[nodiscard]] LRESULT _OnSizing(const WPARAM wParam, const LPARAM lParam);
bool _borderless{ false };
bool _fullscreen{ false };
RECT _fullscreenWindowSize;
RECT _nonFullscreenWindowSize;
virtual void _SetIsBorderless(const bool borderlessEnabled);
virtual void _SetIsFullscreen(const bool fullscreenEnabled);
void _BackupWindowSizes(const bool currentIsInFullscreen);
void _ApplyWindowSize();
LONG _getDesiredWindowStyle() const;
private:
// This minimum width allows for width the tabs fit
static constexpr long minimumWidth = 460L;

View File

@ -263,9 +263,10 @@ void NonClientIslandWindow::SetTitlebarContent(winrt::Windows::UI::Xaml::UIEleme
// - the height of the border above the title bar or 0 if it's disabled
int NonClientIslandWindow::_GetTopBorderHeight() const noexcept
{
if (_isMaximized || _fullscreen)
// No border when maximized, or when the titlebar is invisible (by being in
// fullscreen or focus mode).
if (_isMaximized || (!_IsTitlebarVisible()))
{
// no border when maximized
return 0;
}
@ -811,6 +812,46 @@ void NonClientIslandWindow::OnApplicationThemeChanged(const ElementTheme& reques
_theme = requestedTheme;
}
// Method Description:
// - Enable or disable borderless mode. When entering borderless mode, we'll
// need to manually hide the entire titlebar.
// - See also IslandWindow::_SetIsBorderless, which does similar, but different work.
// Arguments:
// - borderlessEnabled: If true, we're entering borderless mode. If false, we're leaving.
// Return Value:
// - <none>
void NonClientIslandWindow::_SetIsBorderless(const bool borderlessEnabled)
{
_borderless = borderlessEnabled;
// Explicitly _don't_ call IslandWindow::_SetIsBorderless. That version will
// change the window styles appropriately for the window with the default
// titlebar, but for the tabs-in-titlebar mode, we can just get rid of the
// title bar entirely.
if (_titlebar)
{
_titlebar.Visibility(_IsTitlebarVisible() ? Visibility::Visible : Visibility::Collapsed);
}
// 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
// _definitely_ goes away.
_ResizeDragBarWindow();
// Resize the window, with SWP_FRAMECHANGED, to trigger user32 to
// recalculate the non/client areas
const til::rectangle windowPos{ GetWindowRect() };
SetWindowPos(GetHandle(),
HWND_TOP,
windowPos.left<int>(),
windowPos.top<int>(),
windowPos.width<int>(),
windowPos.height<int>(),
SWP_SHOWWINDOW | SWP_FRAMECHANGED);
}
// Method Description:
// - Enable or disable fullscreen mode. When entering fullscreen mode, we'll
// need to manually hide the entire titlebar.
@ -824,7 +865,7 @@ void NonClientIslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
IslandWindow::_SetIsFullscreen(fullscreenEnabled);
if (_titlebar)
{
_titlebar.Visibility(!fullscreenEnabled ? Visibility::Visible : Visibility::Collapsed);
_titlebar.Visibility(_IsTitlebarVisible() ? Visibility::Visible : Visibility::Collapsed);
}
// 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.
@ -835,16 +876,14 @@ void NonClientIslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
// Method Description:
// - Returns true if the titlebar is visible. For things like fullscreen mode,
// borderless mode, this will return false.
// borderless mode (aka "focus mode"), this will return false.
// Arguments:
// - <none>
// Return Value:
// - true iff the titlebar is visible
bool NonClientIslandWindow::_IsTitlebarVisible() const
{
// TODO:GH#2238 - When we add support for titlebar-less mode, this should be
// updated to include that mode.
return !_fullscreen;
return !(_fullscreen || _borderless);
}
// Method Description:

View File

@ -79,7 +79,8 @@ private:
void _OnMaximizeChange() noexcept;
void _OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable sender, winrt::Windows::UI::Xaml::SizeChangedEventArgs eventArgs);
void _SetIsFullscreen(const bool fFullscreenEnabled) override;
void _SetIsBorderless(const bool borderlessEnabled) override;
void _SetIsFullscreen(const bool fullscreenEnabled) override;
bool _IsTitlebarVisible() const;
void _UpdateFrameMargins() const noexcept;