Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the window name _quake special #9785

Merged
11 commits merged into from Apr 26, 2021
14 changes: 12 additions & 2 deletions src/cascadia/TerminalApp/AppLogic.cpp
Expand Up @@ -286,11 +286,16 @@ namespace winrt::TerminalApp::implementation
// that the window size is _first_ set up as something sensible, so
// leaving fullscreen returns to a reasonable size.
const auto launchMode = this->GetLaunchMode();
if (launchMode == LaunchMode::FullscreenMode)
if (IsQuakeWindow())
{
_root->ToggleFocusMode();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ToggleFocusMode and not something like EnableFocusMode or SetFocusMode(true)? QM will always be in focus mode right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frankly, I hadn't written _SetFocusMode yet when I added this line 😋

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, but that's a private member on TerminalPage... meh, I just didn't feel like adding another method that'll only have one usage right here

}
else if (launchMode == LaunchMode::FullscreenMode)
{
_root->ToggleFullscreen();
}
else if (launchMode == LaunchMode::FocusMode || launchMode == LaunchMode::MaximizedFocusMode)
else if (launchMode == LaunchMode::FocusMode ||
launchMode == LaunchMode::MaximizedFocusMode)
{
_root->ToggleFocusMode();
}
Expand Down Expand Up @@ -1419,4 +1424,9 @@ namespace winrt::TerminalApp::implementation
}
}

bool AppLogic::IsQuakeWindow() const
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
{
return _root->IsQuakeWindow();
}

}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.h
Expand Up @@ -66,6 +66,7 @@ namespace winrt::TerminalApp::implementation
void WindowName(const winrt::hstring& name);
uint64_t WindowId();
void WindowId(const uint64_t& id);
bool IsQuakeWindow() const;

Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi);
bool CenterOnLaunch();
Expand Down Expand Up @@ -158,6 +159,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
FORWARDED_TYPED_EVENT(IsQuakeWindowChanged, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IsQuakeWindowChanged);

#ifdef UNIT_TESTING
friend class TerminalAppLocalTests::CommandlineTest;
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.idl
Expand Up @@ -52,6 +52,7 @@ namespace TerminalApp
String WindowName;
UInt64 WindowId;
void RenameFailed();
Boolean IsQuakeWindow();

Windows.Foundation.Size GetLaunchDimensions(UInt32 dpi);
Boolean CenterOnLaunch { get; };
Expand Down Expand Up @@ -85,5 +86,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
}
}
17 changes: 11 additions & 6 deletions src/cascadia/TerminalApp/TabManagement.cpp
Expand Up @@ -272,12 +272,17 @@ namespace winrt::TerminalApp::implementation
(_tabs.Size() > 1) ||
_settings.GlobalSettings().AlwaysShowTabs());

// collapse/show the tabs themselves
_tabView.Visibility(isVisible ? Visibility::Visible : Visibility::Collapsed);

// collapse/show the row that the tabs are in.
// NaN is the special value XAML uses for "Auto" sizing.
_tabRow.Height(isVisible ? NAN : 0);
if (_tabView)
{
// collapse/show the tabs themselves
_tabView.Visibility(isVisible ? Visibility::Visible : Visibility::Collapsed);
}
if (_tabRow)
{
// collapse/show the row that the tabs are in.
// NaN is the special value XAML uses for "Auto" sizing.
_tabRow.Height(isVisible ? NAN : 0);
}
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}

// Method Description:
Expand Down
32 changes: 28 additions & 4 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Expand Up @@ -2049,9 +2049,17 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalPage::ToggleFocusMode()
{
_isInFocusMode = !_isInFocusMode;
_UpdateTabView();
_FocusModeChangedHandlers(*this, nullptr);
_SetFocusMode(!_isInFocusMode);
}

void TerminalPage::_SetFocusMode(const bool inFocusMode)
{
if (inFocusMode != FocusMode())
{
_isInFocusMode = inFocusMode || IsQuakeWindow();
_UpdateTabView();
_FocusModeChangedHandlers(*this, nullptr);
}
}

// Method Description:
Expand Down Expand Up @@ -2260,7 +2268,7 @@ namespace winrt::TerminalApp::implementation

bool TerminalPage::FocusMode() const
{
return _isInFocusMode;
return _isInFocusMode || IsQuakeWindow();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit weird to me. If QM is always in FM, why do we need to make this change at all? Shouldn't _isInFocusMode be updated to be true when in QM, and false when out of it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea that's weird


bool TerminalPage::Fullscreen() const
Expand Down Expand Up @@ -2596,10 +2604,21 @@ namespace winrt::TerminalApp::implementation
}
void TerminalPage::WindowName(const winrt::hstring& value)
{
const bool oldIsQuakeMode = IsQuakeWindow();
if (_WindowName != value)
{
_WindowName = value;
_PropertyChangedHandlers(*this, WUX::Data::PropertyChangedEventArgs{ L"WindowNameForDisplay" });

// If we're entering quake mode, or leaving it
if (IsQuakeWindow() != oldIsQuakeMode)
{
// If we're entering QM from ~FM, then this will enter FM
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
// If we're entering QM from FM, then this will do nothing
// If we're leaving QM (we're already in FM), then this will do nothing
_SetFocusMode(_isInFocusMode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A continuation of my confusion from above, why not do ToggleFocusMode?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meh, this one gets to be more explicit in what it's trying to do because it's already inside the TerminalPage. Technically, yes, ToggleFocusMode would work, by setting it to false, but then staying in focus mode anyways, but ¯\_(ツ)_/¯

_IsQuakeWindowChangedHandlers(*this, nullptr);
}
}
}

Expand Down Expand Up @@ -2735,4 +2754,9 @@ namespace winrt::TerminalApp::implementation
WindowRenamer().IsOpen(false);
}
}

bool TerminalPage::IsQuakeWindow() const
{
return WindowName() == L"_quake";
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}
}
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Expand Up @@ -107,6 +107,7 @@ namespace winrt::TerminalApp::implementation
void WindowId(const uint64_t& value);
winrt::hstring WindowIdForDisplay() const noexcept;
winrt::hstring WindowNameForDisplay() const noexcept;
bool IsQuakeWindow() const;

WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);

Expand All @@ -122,6 +123,7 @@ namespace winrt::TerminalApp::implementation
TYPED_EVENT(Initialized, IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);
TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable);
TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs);
TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable);

private:
friend struct TerminalPageT<TerminalPage>; // for Xaml to bind events
Expand Down Expand Up @@ -330,6 +332,8 @@ namespace winrt::TerminalApp::implementation

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

void _SetFocusMode(const bool inFocusMode);

#pragma region ActionHandlers
// These are all defined in AppActionHandlers.cpp
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.idl
Expand Up @@ -33,6 +33,7 @@ namespace TerminalApp
String WindowNameForDisplay { get; };
String WindowIdForDisplay { get; };
void RenameFailed();
Boolean IsQuakeWindow();

// We cannot use the default XAML APIs because we want to make sure
// that there's only one application-global dialog visible at a time,
Expand All @@ -54,5 +55,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
}
}
80 changes: 54 additions & 26 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Expand Up @@ -57,6 +57,8 @@ AppHost::AppHost() noexcept :
_window = std::make_unique<IslandWindow>();
}

_window->IsQuakeWindow(_logic.IsQuakeWindow());
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

// Tell the window to callback to us when it's about to handle a WM_CREATE
auto pfn = std::bind(&AppHost::_HandleCreateWindow,
this,
Expand Down Expand Up @@ -242,7 +244,6 @@ void AppHost::Initialize()
_logic.FullscreenChanged({ this, &AppHost::_FullscreenChanged });
_logic.FocusModeChanged({ this, &AppHost::_FocusModeChanged });
_logic.AlwaysOnTopChanged({ this, &AppHost::_AlwaysOnTopChanged });
_logic.RaiseVisualBell({ this, &AppHost::_RaiseVisualBell });
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

_logic.Create();

Expand All @@ -251,6 +252,7 @@ void AppHost::Initialize()
_logic.SetTaskbarProgress({ this, &AppHost::SetTaskbarProgress });
_logic.IdentifyWindowsRequested({ this, &AppHost::_IdentifyWindowsRequested });
_logic.RenameWindowRequested({ this, &AppHost::_RenameWindowRequested });
_logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged });

_window->UpdateTitle(_logic.Title());

Expand Down Expand Up @@ -379,39 +381,59 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode

// 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 dimensions{ Utils::ClampToShortMax(adjustedWidth, 1),
Utils::ClampToShortMax(adjustedHeight, 1) };
const til::size nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
adjustedWidth = islandWidth + nonClientSize.width<long>();
adjustedHeight = islandHeight + nonClientSize.height<long>();

til::size dimensions{ Utils::ClampToShortMax(adjustedWidth, 1),
Utils::ClampToShortMax(adjustedHeight, 1) };

// Find nearest monitor for the position that we've actually settled on
HMONITOR hMonNearest = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
MONITORINFO nearestMonitorInfo;
nearestMonitorInfo.cbSize = sizeof(MONITORINFO);
// Get monitor dimensions:
GetMonitorInfo(hMonNearest, &nearestMonitorInfo);
const til::size desktopDimensions{ gsl::narrow<short>(nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left),
gsl::narrow<short>(nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top) };

til::point origin{ ::base::saturated_cast<ptrdiff_t>(proposedRect.left),
::base::saturated_cast<ptrdiff_t>(proposedRect.top) };
if (centerOnLaunch)
{
// Find nearest monitor for the position that we've actually settled on
HMONITOR hMonNearest = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
MONITORINFO nearestMonitorInfo;
nearestMonitorInfo.cbSize = sizeof(MONITORINFO);
// Get monitor dimensions:
GetMonitorInfo(hMonNearest, &nearestMonitorInfo);
const COORD desktopDimensions{ gsl::narrow<short>(nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left),
gsl::narrow<short>(nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top) };
// Move our proposed location into the center of that specific monitor.
proposedRect.left = nearestMonitorInfo.rcWork.left +
((desktopDimensions.X / 2) - (dimensions.X / 2));
proposedRect.top = nearestMonitorInfo.rcWork.top +
((desktopDimensions.Y / 2) - (dimensions.Y / 2));
origin = til::point{
nearestMonitorInfo.rcWork.left + ((desktopDimensions.width() / 2) - (dimensions.width() / 2)),
nearestMonitorInfo.rcWork.top + ((desktopDimensions.height() / 2) - (dimensions.height() / 2))
};
}

if (_logic.IsQuakeWindow())
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
{
// If we just use rcWork by itself, we'll fail to account for the invisible
// space reserved for the resize handles. So retrieve that size here.
const til::size ncSize{ _window->GetTotalNonClientExclusiveSize(dpix) };
const til::size availableSpace = desktopDimensions + nonClientSize;

origin = til::point{
nearestMonitorInfo.rcWork.left - (nonClientSize.width() / 2),
nearestMonitorInfo.rcWork.top
};
dimensions = til::size{
availableSpace.width(),
availableSpace.height() / 2
};
launchMode = LaunchMode::FocusMode;
}
const COORD origin{ gsl::narrow<short>(proposedRect.left),
gsl::narrow<short>(proposedRect.top) };

const auto newPos = Viewport::FromDimensions(origin, dimensions);
const til::rectangle newRect{ origin, dimensions };
// const auto newPos = Viewport::FromDimensions(origin, dimensions);
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
bool succeeded = SetWindowPos(hwnd,
nullptr,
newPos.Left(),
newPos.Top(),
newPos.Width(),
newPos.Height(),
newRect.left<int>(),
newRect.top<int>(),
newRect.width<int>(),
newRect.height<int>(),
SWP_NOACTIVATE | SWP_NOZORDER);

// Refresh the dpi of HWND because the dpi where the window will launch may be different
Expand Down Expand Up @@ -674,3 +696,9 @@ winrt::fire_and_forget AppHost::_RenameWindowRequested(const winrt::Windows::Fou
}
}
}

void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&,
const winrt::Windows::Foundation::IInspectable&)
{
_window->IsQuakeWindow(_logic.IsQuakeWindow());
}
3 changes: 3 additions & 0 deletions src/cascadia/WindowsTerminal/AppHost.h
Expand Up @@ -59,4 +59,7 @@ class AppHost
const winrt::TerminalApp::RenameWindowRequestedArgs args);

GUID _CurrentDesktopGuid();

void _IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
};