Skip to content

Commit

Permalink
Add support for fullscreen launchMode (microsoft#6060)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request

Adds `"launchMode": "fullscreen"`, which does what it says on the box.

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

## Detailed Description of the Pull Request / Additional comments

It's important to let the winow get created, _then_ fullscreen it, because otherwise, when the user exits fullscreen, the window is sized to like, 0x0 or something, and that's just annoying.
  • Loading branch information
zadjii-msft authored and jelster committed May 28, 2020
1 parent 904ca64 commit 0d8bb2c
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 56 deletions.
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/AppLogic.idl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace TerminalApp
{
DefaultMode,
MaximizedMode,
FullscreenMode,
};

[default_interface] runtimeclass AppLogic : IF7Listener
Expand Down
7 changes: 7 additions & 0 deletions src/cascadia/TerminalApp/GlobalAppSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static constexpr std::string_view ConfirmCloseAllKey{ "confirmCloseAllTabs" };
static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" };
static constexpr std::wstring_view DefaultLaunchModeValue{ L"default" };
static constexpr std::wstring_view MaximizedLaunchModeValue{ L"maximized" };
static constexpr std::wstring_view FullscreenLaunchModeValue{ L"fullscreen" };
static constexpr std::wstring_view LightThemeValue{ L"light" };
static constexpr std::wstring_view DarkThemeValue{ L"dark" };
static constexpr std::wstring_view SystemThemeValue{ L"system" };
Expand Down Expand Up @@ -473,6 +474,10 @@ LaunchMode GlobalAppSettings::_ParseLaunchMode(const std::wstring& launchModeStr
{
return LaunchMode::MaximizedMode;
}
else if (launchModeString == FullscreenLaunchModeValue)
{
return LaunchMode::FullscreenMode;
}

return LaunchMode::DefaultMode;
}
Expand All @@ -490,6 +495,8 @@ std::wstring_view GlobalAppSettings::_SerializeLaunchMode(const LaunchMode launc
{
case LaunchMode::MaximizedMode:
return MaximizedLaunchModeValue;
case LaunchMode::FullscreenMode:
return FullscreenLaunchModeValue;
default:
return DefaultLaunchModeValue;
}
Expand Down
30 changes: 26 additions & 4 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ namespace winrt::TerminalApp::implementation
if (_appArgs.GetStartupActions().empty())
{
_OpenNewTab(nullptr);
_startupState = StartupState::Initialized;
_InitializedHandlers(*this, nullptr);

_CompleteInitialization();
}
else
{
Expand Down Expand Up @@ -222,9 +222,31 @@ namespace winrt::TerminalApp::implementation
{
_actionDispatch->DoAction(action);
}
_startupState = StartupState::Initialized;
_InitializedHandlers(*this, nullptr);

_CompleteInitialization();
}
}

// Method Description:
// - Perform and steps that need to be done once our initial state is all
// set up. This includes entering fullscreen mode and firing our
// Initialized event.
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::_CompleteInitialization()
{
// GH#288 - When we finish initialization, if the user wanted us
// 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.
if (_settings->GlobalSettings().GetLaunchMode() == winrt::TerminalApp::LaunchMode::FullscreenMode)
{
_ToggleFullscreen();
}
_startupState = StartupState::Initialized;
_InitializedHandlers(*this, nullptr);
}

// Method Description:
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ namespace winrt::TerminalApp::implementation
void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor);
void _ClearNewTabButtonColor();

void _CompleteInitialization();

#pragma region ActionHandlers
// These are all defined in AppActionHandlers.cpp
void _HandleOpenNewTabDropdown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
Expand Down
100 changes: 49 additions & 51 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,61 +239,59 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Ter

long adjustedHeight = 0;
long adjustedWidth = 0;
if (launchMode == winrt::TerminalApp::LaunchMode::DefaultMode)

// Find nearest monitor.
HMONITOR hmon = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);

// Get nearest monitor information
MONITORINFO monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hmon, &monitorInfo);

// This API guarantees that dpix and dpiy will be equal, but neither is an
// optional parameter so give two UINTs.
UINT dpix = USER_DEFAULT_SCREEN_DPI;
UINT dpiy = USER_DEFAULT_SCREEN_DPI;
// If this fails, we'll use the default of 96.
GetDpiForMonitor(hmon, MDT_EFFECTIVE_DPI, &dpix, &dpiy);

// We need to check if the top left point of the titlebar of the window is within any screen
RECT offScreenTestRect;
offScreenTestRect.left = proposedRect.left;
offScreenTestRect.top = proposedRect.top;
offScreenTestRect.right = offScreenTestRect.left + 1;
offScreenTestRect.bottom = offScreenTestRect.top + 1;

bool isTitlebarIntersectWithMonitors = false;
EnumDisplayMonitors(
nullptr, &offScreenTestRect, [](HMONITOR, HDC, LPRECT, LPARAM lParam) -> BOOL {
auto intersectWithMonitor = reinterpret_cast<bool*>(lParam);
*intersectWithMonitor = true;
// Continue the enumeration
return FALSE;
},
reinterpret_cast<LPARAM>(&isTitlebarIntersectWithMonitors));

if (!isTitlebarIntersectWithMonitors)
{
// Find nearest monitor.
HMONITOR hmon = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);

// Get nearest monitor information
MONITORINFO monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hmon, &monitorInfo);

// This API guarantees that dpix and dpiy will be equal, but neither is an
// optional parameter so give two UINTs.
UINT dpix = USER_DEFAULT_SCREEN_DPI;
UINT dpiy = USER_DEFAULT_SCREEN_DPI;
// If this fails, we'll use the default of 96.
GetDpiForMonitor(hmon, MDT_EFFECTIVE_DPI, &dpix, &dpiy);

// We need to check if the top left point of the titlebar of the window is within any screen
RECT offScreenTestRect;
offScreenTestRect.left = proposedRect.left;
offScreenTestRect.top = proposedRect.top;
offScreenTestRect.right = offScreenTestRect.left + 1;
offScreenTestRect.bottom = offScreenTestRect.top + 1;

bool isTitlebarIntersectWithMonitors = false;
EnumDisplayMonitors(
nullptr, &offScreenTestRect, [](HMONITOR, HDC, LPRECT, LPARAM lParam) -> BOOL {
auto intersectWithMonitor = reinterpret_cast<bool*>(lParam);
*intersectWithMonitor = true;
// Continue the enumeration
return FALSE;
},
reinterpret_cast<LPARAM>(&isTitlebarIntersectWithMonitors));

if (!isTitlebarIntersectWithMonitors)
{
// If the title bar is out-of-screen, we set the initial position to
// the top left corner of the nearest monitor
proposedRect.left = monitorInfo.rcWork.left;
proposedRect.top = monitorInfo.rcWork.top;
}
// If the title bar is out-of-screen, we set the initial position to
// the top left corner of the nearest monitor
proposedRect.left = monitorInfo.rcWork.left;
proposedRect.top = monitorInfo.rcWork.top;
}

auto initialSize = _logic.GetLaunchDimensions(dpix);
auto initialSize = _logic.GetLaunchDimensions(dpix);

const short islandWidth = Utils::ClampToShortMax(
static_cast<long>(ceil(initialSize.X)), 1);
const short islandHeight = Utils::ClampToShortMax(
static_cast<long>(ceil(initialSize.Y)), 1);
const short islandWidth = Utils::ClampToShortMax(
static_cast<long>(ceil(initialSize.X)), 1);
const short islandHeight = Utils::ClampToShortMax(
static_cast<long>(ceil(initialSize.Y)), 1);

// Get the size of a window we'd need to host that client rect. This will
// add the titlebar space.
const auto nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
adjustedWidth = islandWidth + nonClientSize.cx;
adjustedHeight = islandHeight + nonClientSize.cy;
}
// Get the size of a window we'd need to host that client rect. This will
// add the titlebar space.
const auto nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
adjustedWidth = islandWidth + nonClientSize.cx;
adjustedHeight = islandHeight + nonClientSize.cy;

const COORD origin{ gsl::narrow<short>(proposedRect.left),
gsl::narrow<short>(proposedRect.top) };
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/WindowsTerminal/IslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
}

ShowWindow(_window.get(), nCmdShow);

UpdateWindow(_window.get());
}

Expand Down
5 changes: 4 additions & 1 deletion src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,10 @@ void NonClientIslandWindow::OnApplicationThemeChanged(const ElementTheme& reques
void NonClientIslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
{
IslandWindow::_SetIsFullscreen(fullscreenEnabled);
_titlebar.Visibility(!fullscreenEnabled ? Visibility::Visible : Visibility::Collapsed);
if (_titlebar)
{
_titlebar.Visibility(!fullscreenEnabled ? 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
Expand Down

0 comments on commit 0d8bb2c

Please sign in to comment.