When the window is summoned and is already active, minimize it. (#9963)
This adds a `toggleVisibility` parameter to `globalSummon`. * When `true` (default): when you press the global summon keybinding, and the window is currently the foreground window, we'll minimize the window. * When `false`, we'll just do nothing. ## References * Original thread: #653 * Spec: #9274 * megathread: #8888 ## PR Checklist * [x] Checks a box in #8888 * [x] closes https://github.com/microsoft/terminal/projects/5#card-59030814 * [x] I work here * [ ] No tests for this one. * [ ] yes yes eventually I'll come back on the docs ## Detailed Description of the Pull Request / Additional comments I've got nothing extra to add here. This one's pretty simple. I'm only targeting #9954 since that one laid so much foundation to build on, with the `SummonBehavior` ## Validation Steps Performed Played with this for a while, and it's amazing.
This commit is contained in:
parent
65b22b9abb
commit
30d2d2c76d
|
@ -47,6 +47,7 @@ ICustom
|
|||
IDialog
|
||||
IDirect
|
||||
IExplorer
|
||||
IFACEMETHOD
|
||||
IFile
|
||||
IInheritable
|
||||
IMap
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Peasant_Summon",
|
||||
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
||||
TraceLoggingUInt64(localCopy->MoveToCurrentDesktop(), "MoveToCurrentDesktop", "true if we should move to the current desktop"),
|
||||
TraceLoggingUInt64(localCopy.MoveToCurrentDesktop(), "MoveToCurrentDesktop", "true if we should move to the current desktop"),
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||
|
||||
_SummonRequestedHandlers(*this, localCopy);
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace Microsoft.Terminal.Remoting
|
|||
[default_interface] runtimeclass SummonWindowBehavior {
|
||||
SummonWindowBehavior();
|
||||
Boolean MoveToCurrentDesktop;
|
||||
Boolean ToggleVisibility;
|
||||
// Other options:
|
||||
// * CurrentMonitor
|
||||
}
|
||||
|
|
|
@ -22,10 +22,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
public:
|
||||
SummonWindowBehavior() = default;
|
||||
WINRT_PROPERTY(bool, MoveToCurrentDesktop, true);
|
||||
WINRT_PROPERTY(bool, ToggleVisibility, true);
|
||||
|
||||
public:
|
||||
SummonWindowBehavior(const Remoting::SummonWindowBehavior& other) :
|
||||
_MoveToCurrentDesktop{ other.MoveToCurrentDesktop() } {};
|
||||
_MoveToCurrentDesktop{ other.MoveToCurrentDesktop() },
|
||||
_ToggleVisibility{ other.ToggleVisibility() } {};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1045,9 +1045,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
GlobalSummonArgs() = default;
|
||||
WINRT_PROPERTY(winrt::hstring, Name, L"");
|
||||
WINRT_PROPERTY(Model::DesktopBehavior, Desktop, Model::DesktopBehavior::ToCurrent);
|
||||
WINRT_PROPERTY(bool, ToggleVisibility, true);
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
static constexpr std::string_view DesktopKey{ "desktop" };
|
||||
static constexpr std::string_view ToggleVisibilityKey{ "toggleVisibility" };
|
||||
|
||||
public:
|
||||
hstring GenerateName() const;
|
||||
|
@ -1057,7 +1059,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
if (auto otherAsUs = other.try_as<GlobalSummonArgs>())
|
||||
{
|
||||
return otherAsUs->_Name == _Name &&
|
||||
otherAsUs->_Desktop == _Desktop;
|
||||
otherAsUs->_Desktop == _Desktop &&
|
||||
otherAsUs->_ToggleVisibility == _ToggleVisibility;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
@ -1067,6 +1070,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
auto args = winrt::make_self<GlobalSummonArgs>();
|
||||
JsonUtils::GetValueForKey(json, NameKey, args->_Name);
|
||||
JsonUtils::GetValueForKey(json, DesktopKey, args->_Desktop);
|
||||
JsonUtils::GetValueForKey(json, ToggleVisibilityKey, args->_ToggleVisibility);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
|
@ -1074,6 +1078,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
auto copy{ winrt::make_self<GlobalSummonArgs>() };
|
||||
copy->_Name = _Name;
|
||||
copy->_Desktop = _Desktop;
|
||||
copy->_ToggleVisibility = _ToggleVisibility;
|
||||
return *copy;
|
||||
}
|
||||
// SPECIAL! This deserializer creates a GlobalSummonArgs with the
|
||||
|
|
|
@ -264,5 +264,6 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
{
|
||||
String Name { get; };
|
||||
DesktopBehavior Desktop { get; };
|
||||
Boolean ToggleVisibility { get; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,17 +38,20 @@ namespace RemotingUnitTests
|
|||
{
|
||||
struct MockDesktopManager : implements<MockDesktopManager, IVirtualDesktopManager>
|
||||
{
|
||||
HRESULT GetWindowDesktopId(HWND /*topLevelWindow*/, GUID* /*desktopId*/)
|
||||
IFACEMETHOD(GetWindowDesktopId)
|
||||
(HWND /*topLevelWindow*/, GUID* /*desktopId*/)
|
||||
{
|
||||
VERIFY_IS_TRUE(false, L"We shouldn't need GetWindowDesktopId in the tests.");
|
||||
return E_FAIL;
|
||||
}
|
||||
HRESULT MoveWindowToDesktop(HWND /*topLevelWindow*/, REFGUID /*desktopId*/)
|
||||
IFACEMETHOD(MoveWindowToDesktop)
|
||||
(HWND /*topLevelWindow*/, REFGUID /*desktopId*/)
|
||||
{
|
||||
VERIFY_IS_TRUE(false, L"We shouldn't need GetWindowDesktopId in the tests.");
|
||||
return E_FAIL;
|
||||
}
|
||||
HRESULT IsWindowOnCurrentVirtualDesktop(HWND topLevelWindow, BOOL* onCurrentDesktop)
|
||||
IFACEMETHOD(IsWindowOnCurrentVirtualDesktop)
|
||||
(HWND topLevelWindow, BOOL* onCurrentDesktop)
|
||||
{
|
||||
if (pfnIsWindowOnCurrentVirtualDesktop)
|
||||
{
|
||||
|
|
|
@ -591,7 +591,7 @@ void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*se
|
|||
{
|
||||
// Summon the window whenever we dispatch a commandline to it. This will
|
||||
// make it obvious when a new tab/pane is created in a window.
|
||||
_window->SummonWindow();
|
||||
_window->SummonWindow(false);
|
||||
_logic.ExecuteCommandline(args.Commandline(), args.CurrentDirectory());
|
||||
}
|
||||
|
||||
|
@ -692,6 +692,7 @@ void AppHost::_GlobalHotkeyPressed(const long hotkeyIndex)
|
|||
// desktop:onCurrent - MoveToCurrentDesktop=false, OnCurrentDesktop=true
|
||||
args.OnCurrentDesktop(summonArgs.Desktop() == Settings::Model::DesktopBehavior::OnCurrent);
|
||||
args.SummonBehavior().MoveToCurrentDesktop(summonArgs.Desktop() == Settings::Model::DesktopBehavior::ToCurrent);
|
||||
args.SummonBehavior().ToggleVisibility(summonArgs.ToggleVisibility());
|
||||
|
||||
_windowManager.SummonWindow(args);
|
||||
if (args.FoundMatch())
|
||||
|
@ -774,7 +775,7 @@ bool AppHost::_LazyLoadDesktopManager()
|
|||
void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const Remoting::SummonWindowBehavior& args)
|
||||
{
|
||||
_window->SummonWindow();
|
||||
_window->SummonWindow(args.ToggleVisibility());
|
||||
|
||||
if (args != nullptr && args.MoveToCurrentDesktop())
|
||||
{
|
||||
|
|
|
@ -999,6 +999,33 @@ void IslandWindow::SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal
|
|||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Summon the window, or possibly dismiss it. If toggleVisibility is true,
|
||||
// then we'll dismiss (minimize) the window if it's currently active.
|
||||
// Otherwise, we'll always just try to activate the window.
|
||||
// Arguments:
|
||||
// - toggleVisibility: controls how we should behave when already in the foreground.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget IslandWindow::SummonWindow(const bool toggleVisibility)
|
||||
{
|
||||
// On the foreground thread:
|
||||
co_await winrt::resume_foreground(_rootGrid.Dispatcher());
|
||||
|
||||
// * If the user doesn't want to toggleVisibility, then just always try to
|
||||
// activate.
|
||||
// * If the user does want to toggleVisibility, then dismiss the window if
|
||||
// we're the current foreground window.
|
||||
if (toggleVisibility && GetForegroundWindow() == _window.get())
|
||||
{
|
||||
_globalDismissWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
_globalActivateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Force activate this window. This method will bring us to the foreground and
|
||||
// activate us. If the window is minimized, it will restore the window. If the
|
||||
|
@ -1007,11 +1034,8 @@ void IslandWindow::SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal
|
|||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget IslandWindow::SummonWindow()
|
||||
void IslandWindow::_globalActivateWindow()
|
||||
{
|
||||
// On the foreground thread:
|
||||
co_await winrt::resume_foreground(_rootGrid.Dispatcher());
|
||||
|
||||
// From: https://stackoverflow.com/a/59659421
|
||||
// > The trick is to make windows ‘think’ that our process and the target
|
||||
// > window (hwnd) are related by attaching the threads (using
|
||||
|
@ -1039,6 +1063,18 @@ winrt::fire_and_forget IslandWindow::SummonWindow()
|
|||
LOG_LAST_ERROR_IF_NULL(SetActiveWindow(_window.get()));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Minimize the window. This is called when the window is summoned, but is
|
||||
// already active
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void IslandWindow::_globalDismissWindow()
|
||||
{
|
||||
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_MINIMIZE));
|
||||
}
|
||||
|
||||
bool IslandWindow::IsQuakeWindow() const noexcept
|
||||
{
|
||||
return _isQuakeWindow;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
void UnsetHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);
|
||||
void SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);
|
||||
|
||||
winrt::fire_and_forget SummonWindow();
|
||||
winrt::fire_and_forget SummonWindow(const bool toggleVisibility);
|
||||
|
||||
bool IsQuakeWindow() const noexcept;
|
||||
void IsQuakeWindow(bool isQuakeWindow) noexcept;
|
||||
|
@ -93,6 +93,9 @@ protected:
|
|||
void _OnGetMinMaxInfo(const WPARAM wParam, const LPARAM lParam);
|
||||
long _calculateTotalSize(const bool isWidth, const long clientSize, const long nonClientSize);
|
||||
|
||||
void _globalActivateWindow();
|
||||
void _globalDismissWindow();
|
||||
|
||||
bool _isQuakeWindow{ false };
|
||||
void _enterQuakeMode();
|
||||
|
||||
|
|
Loading…
Reference in New Issue