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

Restore the ability for alt+tab to restore the Terminal after minimizing with taskbar #13624

Merged
1 commit merged into from
Aug 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/cascadia/WindowsTerminal/IslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,10 +844,20 @@ void IslandWindow::SetAlwaysOnTop(const bool alwaysOnTop)
// - <none>
void IslandWindow::ShowWindowChanged(const bool showOrHide)
{
const auto hwnd = GetHandle();
if (hwnd)
if (const auto hwnd = GetHandle())
{
PostMessage(hwnd, WM_SYSCOMMAND, showOrHide ? SC_RESTORE : SC_MINIMIZE, 0);
// IMPORTANT!
//
// ONLY "restore" if already minimized. If the window is maximized or
// snapped, a restore will restore-down the window instead.
if (showOrHide == true && ::IsIconic(hwnd))
Copy link
Member

Choose a reason for hiding this comment

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

Ah ok. So the only difference here is the IsIconic() check. Got it.

{
::PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
}
else if (showOrHide == false)
{
::PostMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
}
}

Expand Down
49 changes: 26 additions & 23 deletions src/interactivity/base/InteractivityFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,15 @@ void InteractivityFactory::SetPseudoWindowCallback(std::function<void(bool)> fun
// It can be fun to toggle WM_QUERYOPEN but DefWindowProc returns TRUE.
case WM_SIZE:
{
// Curiously, at least on Windows 10 (and rarely on Windows 11), if you
// minimize the Terminal by clicking on the taskbar, then alt-tab to try
// and restore the window, the Taskbar will decide to call
// SwitchToWindow on us, the invisible, owned window of the main window.
// When that happens, we'll get a WM_SIZE(SIZE_RESTORED, lParam=0). The
// main window will NOT get a SwitchToWindow called. If we don't
// actually inform the hosting process about this, then the main HWND
// might stay hidden. Refer to GH#13589

if (wParam == SIZE_RESTORED)
{
_WritePseudoWindowCallback(true);
Expand All @@ -447,23 +456,23 @@ void InteractivityFactory::SetPseudoWindowCallback(std::function<void(bool)> fun
}
break;
}
// case WM_WINDOWPOSCHANGING:
// As long as user32 didn't eat the `ShowWindow` call because the window state requested
// matches the existing WS_VISIBLE state of the HWND... we should hear from it in WM_WINDOWPOSCHANGING.
// WM_WINDOWPOSCHANGING can tell us a bunch through the flags fields.
// We can also check IsIconic/IsZoomed on the HWND during the message
// and we could suppress the change to prevent things from happening.
// case WM_WINDOWPOSCHANGING:
// As long as user32 didn't eat the `ShowWindow` call because the window state requested
// matches the existing WS_VISIBLE state of the HWND... we should hear from it in WM_WINDOWPOSCHANGING.
// WM_WINDOWPOSCHANGING can tell us a bunch through the flags fields.
// We can also check IsIconic/IsZoomed on the HWND during the message
// and we could suppress the change to prevent things from happening.
// case WM_SYSCOMMAND:
// WM_SYSCOMMAND will not come through. Don't try.
// WM_SYSCOMMAND will not come through. Don't try.
// WM_SHOWWINDOW does come through on some of the messages.
case WM_SHOWWINDOW:
// WM_SHOWWINDOW comes through on some of the messages.
{
if (0 == lParam) // Someone explicitly called ShowWindow on us.
{
if (0 == lParam) // Someone explicitly called ShowWindow on us.
{
_WritePseudoWindowCallback((bool)wParam);
}
_WritePseudoWindowCallback((bool)wParam);
}
}
}
// If we get this far, call the default window proc
return DefWindowProcW(hWnd, Message, wParam, lParam);
}
Expand All @@ -478,18 +487,12 @@ void InteractivityFactory::SetPseudoWindowCallback(std::function<void(bool)> fun
// - <none>
void InteractivityFactory::_WritePseudoWindowCallback(bool showOrHide)
{
// BODGY
//
// GH#13158 - At least temporarily, only allow the PTY to HIDE the terminal
// window. There seem to be many issues with this so far, and the quickest
// route to mitigate them seems to be limiting the interaction here to
// allowing ConPTY to minimize the terminal only. This will still allow
// applications to hide the Terminal via GetConsoleWindow(), but should
// broadly prevent any other impact of this feature.
// IMPORTANT!
//
// Should we need to restore this functionality in the future, we should
// only do so with great caution.
if (_pseudoWindowMessageCallback && showOrHide == false)
// A hosting terminal window should only "restore" itself in response to
// this message, if it's already minimized. If the window is maximized a
// restore will restore-down the window instead.
if (_pseudoWindowMessageCallback)
{
_pseudoWindowMessageCallback(showOrHide);
}
Expand Down