From 150efbb01f2ad9c089c6e7064f90b5148c5fadc5 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 20 May 2021 00:02:43 -0700 Subject: [PATCH 01/57] initial --- src/cascadia/TerminalApp/TerminalPage.cpp | 23 +++++++++++++++++++ src/cascadia/TerminalApp/TerminalPage.h | 2 ++ src/cascadia/WindowsTerminal/AppHost.cpp | 20 ++++++++++++++++ src/cascadia/WindowsTerminal/AppHost.h | 2 ++ src/cascadia/WindowsTerminal/IslandWindow.cpp | 20 ++++++++++++++++ src/cascadia/WindowsTerminal/IslandWindow.h | 1 + 6 files changed, 68 insertions(+) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 7f728e5ad94..144579bfd16 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -59,9 +59,32 @@ namespace winrt::TerminalApp::implementation HRESULT TerminalPage::Initialize(HWND hwnd) { _hostingHwnd = hwnd; + + TestNotifyIconFunction(); + return S_OK; } + void TerminalPage::TestNotifyIconFunction() + { + if (_hostingHwnd) + { + NOTIFYICONDATA nid{}; + + nid.hWnd = _hostingHwnd.value(); + nid.uID = 1; + nid.uCallbackMessage = WM_APP + 1; + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP; + + // Add the icon to the tray + Shell_NotifyIcon(NIM_ADD, &nid); + + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); + } + } + // Function Description: // - Recursively check our commands to see if there's a keybinding for // exactly their action. If there is, label that command with the text diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 794fd0e1568..7a32e4217fd 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -341,6 +341,8 @@ namespace winrt::TerminalApp::implementation void _SetFocusMode(const bool inFocusMode); + void TestNotifyIconFunction(); + #pragma region ActionHandlers // These are all defined in AppActionHandlers.cpp #define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action); diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 6e4e24bdaa8..7b665325d03 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -77,6 +77,7 @@ AppHost::AppHost() noexcept : _window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled }); _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); + _window->NotifyIconPressed({ this, &AppHost::_NotifyIconPressed }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -917,3 +918,22 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab { _window->IsQuakeWindow(_logic.IsQuakeWindow()); } + +void AppHost::_NotifyIconPressed() +{ + // No name provided means show the MRU window. + Remoting::SummonWindowSelectionArgs args{}; + + // For now, just show the window where it originally was. + args.OnCurrentDesktop(true); + args.SummonBehavior().MoveToCurrentDesktop(false); + args.SummonBehavior().ToggleVisibility(false); + args.SummonBehavior().DropdownDuration(0); + args.SummonBehavior().ToMonitor(Remoting::MonitorBehavior::ToCurrent); + + _windowManager.SummonWindow(args); + if (args.FoundMatch()) + { + // Excellent, the window was found. We have nothing else to do here. + } +} diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 712b757ef52..b3423267570 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -81,4 +81,6 @@ class AppHost void _IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); + + void _NotifyIconPressed(); }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index ee2271e99cc..f2c609d73d5 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -506,6 +506,26 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize case WM_THEMECHANGED: UpdateWindowIconForActiveMetrics(_window.get()); return 0; + // TODO: Give this a better name, something like WT_NOTIFYICON + // WM_APP to 0xBFFF is available for use for apps. + case WM_APP + 1: + { + switch (LOWORD(lparam)) + { + case NIN_SELECT: + { + _NotifyIconPressedHandlers(); + break; + } + case WM_CONTEXTMENU: + { + // TODO: show the context menu + // Build it with ways to open specific windows + break; + } + } + break; + } } // TODO: handle messages here... diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 470e8ecac79..43abcfebe02 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -51,6 +51,7 @@ class IslandWindow : WINRT_CALLBACK(MouseScrolled, winrt::delegate); WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); + WINRT_CALLBACK(NotifyIconPressed, winrt::delegate); protected: void ForceResize() From 87238e108e74b0dd6ba7921729f33eecbfcc956a Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 20 May 2021 12:11:32 -0700 Subject: [PATCH 02/57] give it a fresh look --- src/cascadia/TerminalApp/TerminalPage.cpp | 12 ------ src/cascadia/WindowsTerminal/AppHost.cpp | 46 ++++++++++++++++++++--- src/cascadia/WindowsTerminal/AppHost.h | 4 +- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 144579bfd16..a7174bd5f58 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -69,19 +69,7 @@ namespace winrt::TerminalApp::implementation { if (_hostingHwnd) { - NOTIFYICONDATA nid{}; - nid.hWnd = _hostingHwnd.value(); - nid.uID = 1; - nid.uCallbackMessage = WM_APP + 1; - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); - nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP; - - // Add the icon to the tray - Shell_NotifyIcon(NIM_ADD, &nid); - - nid.uVersion = NOTIFYICON_VERSION_4; - Shell_NotifyIcon(NIM_SETVERSION, &nid); } } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 7b665325d03..8695cbc1ee3 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -77,7 +77,7 @@ AppHost::AppHost() noexcept : _window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled }); _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); - _window->NotifyIconPressed({ this, &AppHost::_NotifyIconPressed }); + _window->NotifyIconPressed({ this, &AppHost::_TrayIconPressed }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -640,6 +640,9 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { + // Look at me, I'm the captain now. + _UpdateTrayIcon(); + _setupGlobalHotkeys(); } @@ -919,7 +922,42 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab _window->IsQuakeWindow(_logic.IsQuakeWindow()); } -void AppHost::_NotifyIconPressed() +void AppHost::_UpdateTrayIcon() +{ + if (_TrayIconData) + { + auto nid = _TrayIconData.value(); + nid.hWnd = _window->GetHandle(); + Shell_NotifyIcon(NIM_MODIFY, &nid); + } + else + { + NOTIFYICONDATA nid{}; + + if (HMODULE hModule = GetModuleHandleW(nullptr)) + { + nid.hIcon = static_cast(LoadImageW(hModule, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); + } + + nid.hWnd = _window->GetHandle(); + nid.uID = 1; + nid.uCallbackMessage = WM_APP + 1; + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + + // Add the icon to the tray + // TODO: Only if there isn't already an Icon. + // If there is, we only need to update the HWND. + Shell_NotifyIcon(NIM_ADD, &nid); + + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); + + _TrayIconData = nid; + } +} + +void AppHost::_TrayIconPressed() { // No name provided means show the MRU window. Remoting::SummonWindowSelectionArgs args{}; @@ -932,8 +970,4 @@ void AppHost::_NotifyIconPressed() args.SummonBehavior().ToMonitor(Remoting::MonitorBehavior::ToCurrent); _windowManager.SummonWindow(args); - if (args.FoundMatch()) - { - // Excellent, the window was found. We have nothing else to do here. - } } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index b3423267570..c2743f10efa 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -82,5 +82,7 @@ class AppHost void _IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); - void _NotifyIconPressed(); + void _UpdateTrayIcon(); + void _TrayIconPressed(); + std::optional _TrayIconData; }; From b3ae922b7ff29aeea688fd610943f5c6ee71292f Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 20 May 2021 15:32:54 -0700 Subject: [PATCH 03/57] scaffolding for MinimizeToTray action --- src/cascadia/TerminalApp/AppActionHandlers.cpp | 7 +++++++ src/cascadia/TerminalApp/AppLogic.h | 1 + src/cascadia/TerminalApp/AppLogic.idl | 1 + src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalApp/TerminalPage.idl | 1 + src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp | 3 +++ .../TerminalSettingsModel/AllShortcutActions.h | 3 ++- src/cascadia/WindowsTerminal/AppHost.cpp | 11 +++++++++-- src/cascadia/WindowsTerminal/AppHost.h | 4 +++- src/cascadia/WindowsTerminal/IslandWindow.cpp | 8 ++++---- src/cascadia/WindowsTerminal/IslandWindow.h | 2 +- 11 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 04c037f27ed..e4a5aa9004c 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -790,4 +790,11 @@ namespace winrt::TerminalApp::implementation // if it wasn't bound at all. args.Handled(false); } + + void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + _MinimizeToTrayRequestedHandlers(*this, nullptr); + args.Handled(true); + } } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index c86b543005b..797526d877d 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -163,6 +163,7 @@ namespace winrt::TerminalApp::implementation 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); + FORWARDED_TYPED_EVENT(MinimizeToTrayRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, MinimizeToTrayRequested); #ifdef UNIT_TESTING friend class TerminalAppLocalTests::CommandlineTest; diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index fec67c970c3..aa53a5d03ab 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -90,5 +90,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler RenameWindowRequested; event Windows.Foundation.TypedEventHandler SettingsChanged; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; + event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 7a32e4217fd..f9e73e786e4 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -124,6 +124,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable); TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); + TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable); private: friend struct TerminalPageT; // for Xaml to bind events diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index f1c1e55fc15..a491ae054e8 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -56,5 +56,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler IdentifyWindowsRequested; event Windows.Foundation.TypedEventHandler RenameWindowRequested; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; + event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index a7508374df3..bf9ab5582bb 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -59,6 +59,7 @@ static constexpr std::string_view RenameWindowKey{ "renameWindow" }; static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" }; static constexpr std::string_view GlobalSummonKey{ "globalSummon" }; static constexpr std::string_view QuakeModeKey{ "quakeMode" }; +static constexpr std::string_view MinimizeToTrayKey{ "minimizeToTray" }; static constexpr std::string_view ActionKey{ "action" }; @@ -131,6 +132,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { OpenWindowRenamerKey, ShortcutAction::OpenWindowRenamer }, { GlobalSummonKey, ShortcutAction::GlobalSummon }, { QuakeModeKey, ShortcutAction::QuakeMode }, + { MinimizeToTrayKey, ShortcutAction::MinimizeToTray }, }; using ParseResult = std::tuple>; @@ -337,6 +339,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::OpenWindowRenamer, RS_(L"OpenWindowRenamerCommandKey") }, { ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") }, + { ShortcutAction::MinimizeToTray, L"" } }; }(); diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index bc710a756b9..d42a1288b01 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -74,4 +74,5 @@ ON_ALL_ACTIONS(RenameWindow) \ ON_ALL_ACTIONS(OpenWindowRenamer) \ ON_ALL_ACTIONS(GlobalSummon) \ - ON_ALL_ACTIONS(QuakeMode) + ON_ALL_ACTIONS(QuakeMode) \ + ON_ALL_ACTIONS(MinimizeToTray) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 8695cbc1ee3..89b4fe6970a 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -77,7 +77,7 @@ AppHost::AppHost() noexcept : _window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled }); _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); - _window->NotifyIconPressed({ this, &AppHost::_TrayIconPressed }); + _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -267,6 +267,7 @@ void AppHost::Initialize() _logic.RenameWindowRequested({ this, &AppHost::_RenameWindowRequested }); _logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged }); _logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged }); + _logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested }); _window->UpdateTitle(_logic.Title()); @@ -957,7 +958,7 @@ void AppHost::_UpdateTrayIcon() } } -void AppHost::_TrayIconPressed() +void AppHost::_HandleTrayIconPressed() { // No name provided means show the MRU window. Remoting::SummonWindowSelectionArgs args{}; @@ -971,3 +972,9 @@ void AppHost::_TrayIconPressed() _windowManager.SummonWindow(args); } + +void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable sender, + const winrt::Windows::Foundation::IInspectable args) +{ + +} diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index c2743f10efa..01ad76a3967 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -83,6 +83,8 @@ class AppHost const winrt::Windows::Foundation::IInspectable& args); void _UpdateTrayIcon(); - void _TrayIconPressed(); + void _HandleTrayIconPressed(); + void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable sender, + const winrt::Windows::Foundation::IInspectable args); std::optional _TrayIconData; }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index f2c609d73d5..274a0fe6922 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -507,20 +507,20 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize UpdateWindowIconForActiveMetrics(_window.get()); return 0; // TODO: Give this a better name, something like WT_NOTIFYICON - // WM_APP to 0xBFFF is available for use for apps. + // WM_APP to 0xBFFF is available for use for apps apparently. case WM_APP + 1: { switch (LOWORD(lparam)) { case NIN_SELECT: + case NIN_KEYSELECT: { - _NotifyIconPressedHandlers(); + _NotifyTrayIconPressedHandlers(); break; } case WM_CONTEXTMENU: { - // TODO: show the context menu - // Build it with ways to open specific windows + // TODO: show the context menu - buncho options to open specific windows? break; } } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 43abcfebe02..5df4f1369a6 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -51,7 +51,7 @@ class IslandWindow : WINRT_CALLBACK(MouseScrolled, winrt::delegate); WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); - WINRT_CALLBACK(NotifyIconPressed, winrt::delegate); + WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); protected: void ForceResize() From 7964b5a0a732ef365da18e715f451372eca3709d Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 24 May 2021 15:40:47 -0700 Subject: [PATCH 04/57] scoping to quek only --- .../TerminalApp/AppActionHandlers.cpp | 7 -- src/cascadia/TerminalApp/AppLogic.h | 2 - src/cascadia/TerminalApp/AppLogic.idl | 1 - src/cascadia/TerminalApp/TerminalPage.h | 1 - src/cascadia/TerminalApp/TerminalPage.idl | 1 - .../TerminalSettingsModel/ActionAndArgs.cpp | 3 - .../AllShortcutActions.h | 3 +- src/cascadia/WindowsTerminal/AppHost.cpp | 69 +++++++------------ src/cascadia/WindowsTerminal/AppHost.h | 4 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 3 + src/cascadia/WindowsTerminal/IslandWindow.h | 1 + src/cascadia/WindowsTerminal/icon.cpp | 19 +++-- src/cascadia/WindowsTerminal/icon.h | 1 + 13 files changed, 42 insertions(+), 73 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index e4a5aa9004c..04c037f27ed 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -790,11 +790,4 @@ namespace winrt::TerminalApp::implementation // if it wasn't bound at all. args.Handled(false); } - - void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, - const ActionEventArgs& args) - { - _MinimizeToTrayRequestedHandlers(*this, nullptr); - args.Handled(true); - } } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 797526d877d..d443e528e2b 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -163,8 +163,6 @@ namespace winrt::TerminalApp::implementation 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); - FORWARDED_TYPED_EVENT(MinimizeToTrayRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, MinimizeToTrayRequested); - #ifdef UNIT_TESTING friend class TerminalAppLocalTests::CommandlineTest; #endif diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index aa53a5d03ab..fec67c970c3 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -90,6 +90,5 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler RenameWindowRequested; event Windows.Foundation.TypedEventHandler SettingsChanged; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; - event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index f9e73e786e4..7a32e4217fd 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -124,7 +124,6 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable); TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); - TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable); private: friend struct TerminalPageT; // for Xaml to bind events diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index a491ae054e8..f1c1e55fc15 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -56,6 +56,5 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler IdentifyWindowsRequested; event Windows.Foundation.TypedEventHandler RenameWindowRequested; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; - event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index bf9ab5582bb..a7508374df3 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -59,7 +59,6 @@ static constexpr std::string_view RenameWindowKey{ "renameWindow" }; static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" }; static constexpr std::string_view GlobalSummonKey{ "globalSummon" }; static constexpr std::string_view QuakeModeKey{ "quakeMode" }; -static constexpr std::string_view MinimizeToTrayKey{ "minimizeToTray" }; static constexpr std::string_view ActionKey{ "action" }; @@ -132,7 +131,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { OpenWindowRenamerKey, ShortcutAction::OpenWindowRenamer }, { GlobalSummonKey, ShortcutAction::GlobalSummon }, { QuakeModeKey, ShortcutAction::QuakeMode }, - { MinimizeToTrayKey, ShortcutAction::MinimizeToTray }, }; using ParseResult = std::tuple>; @@ -339,7 +337,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::OpenWindowRenamer, RS_(L"OpenWindowRenamerCommandKey") }, { ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") }, - { ShortcutAction::MinimizeToTray, L"" } }; }(); diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index d42a1288b01..bc710a756b9 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -74,5 +74,4 @@ ON_ALL_ACTIONS(RenameWindow) \ ON_ALL_ACTIONS(OpenWindowRenamer) \ ON_ALL_ACTIONS(GlobalSummon) \ - ON_ALL_ACTIONS(QuakeMode) \ - ON_ALL_ACTIONS(MinimizeToTray) + ON_ALL_ACTIONS(QuakeMode) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 89b4fe6970a..73b4ad875ca 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -9,6 +9,7 @@ #include "../WinRTUtils/inc/WtExeUtils.h" #include "resource.h" #include "VirtualDesktopUtils.h" +#include "icon.h" using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Composition; @@ -78,6 +79,7 @@ AppHost::AppHost() noexcept : _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); + _window->NotifyWindowMinimized({ this, &AppHost::_HandleWindowMinimized }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -267,7 +269,6 @@ void AppHost::Initialize() _logic.RenameWindowRequested({ this, &AppHost::_RenameWindowRequested }); _logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged }); _logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged }); - _logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested }); _window->UpdateTitle(_logic.Title()); @@ -641,9 +642,6 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { - // Look at me, I'm the captain now. - _UpdateTrayIcon(); - _setupGlobalHotkeys(); } @@ -925,56 +923,35 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab void AppHost::_UpdateTrayIcon() { - if (_TrayIconData) - { - auto nid = _TrayIconData.value(); - nid.hWnd = _window->GetHandle(); - Shell_NotifyIcon(NIM_MODIFY, &nid); - } - else - { - NOTIFYICONDATA nid{}; - - if (HMODULE hModule = GetModuleHandleW(nullptr)) - { - nid.hIcon = static_cast(LoadImageW(hModule, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); - } + NOTIFYICONDATA nid{}; - nid.hWnd = _window->GetHandle(); - nid.uID = 1; - nid.uCallbackMessage = WM_APP + 1; - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); - nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + // This HWND will receive the callbacks sent by the tray icon. + nid.hWnd = _window->GetHandle(); - // Add the icon to the tray - // TODO: Only if there isn't already an Icon. - // If there is, we only need to update the HWND. - Shell_NotifyIcon(NIM_ADD, &nid); + nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); + nid.uID = 1; + nid.uCallbackMessage = WM_APP + 1; + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + Shell_NotifyIcon(NIM_ADD, &nid); - nid.uVersion = NOTIFYICON_VERSION_4; - Shell_NotifyIcon(NIM_SETVERSION, &nid); - - _TrayIconData = nid; - } + // NIM_ADD won't set the version even if uVersion is set in the nid. + // We have to perform a NIM_SETVERSION call separately. + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); } void AppHost::_HandleTrayIconPressed() { - // No name provided means show the MRU window. - Remoting::SummonWindowSelectionArgs args{}; - - // For now, just show the window where it originally was. - args.OnCurrentDesktop(true); - args.SummonBehavior().MoveToCurrentDesktop(false); - args.SummonBehavior().ToggleVisibility(false); - args.SummonBehavior().DropdownDuration(0); - args.SummonBehavior().ToMonitor(Remoting::MonitorBehavior::ToCurrent); - - _windowManager.SummonWindow(args); + _window->SummonWindow({}); } -void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable sender, - const winrt::Windows::Foundation::IInspectable args) +void AppHost::_HandleWindowMinimized() { - + // Scoping "minimize to tray" to just the quake window. + // Broader support will come in later. + if (_logic.IsQuakeWindow()) + { + _UpdateTrayIcon(); + } } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 01ad76a3967..9efb31061f8 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -84,7 +84,5 @@ class AppHost void _UpdateTrayIcon(); void _HandleTrayIconPressed(); - void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable sender, - const winrt::Windows::Foundation::IInspectable args); - std::optional _TrayIconData; + void _HandleWindowMinimized(); }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 274a0fe6922..60987586e4d 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -452,6 +452,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize { if (wparam == SIZE_MINIMIZED && _isQuakeWindow) { + _NotifyWindowMinimizedHandlers(); ShowWindow(GetHandle(), SW_HIDE); return 0; } @@ -1295,6 +1296,8 @@ void IslandWindow::_globalDismissWindow(const uint32_t dropdownDuration) { ShowWindow(_window.get(), SW_MINIMIZE); } + + _NotifyWindowMinimizedHandlers(); } // Method Description: diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 5df4f1369a6..9b4f8247a6b 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -52,6 +52,7 @@ class IslandWindow : WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); + WINRT_CALLBACK(NotifyWindowMinimized, winrt::delegate); protected: void ForceResize() diff --git a/src/cascadia/WindowsTerminal/icon.cpp b/src/cascadia/WindowsTerminal/icon.cpp index ca194de06f9..01000cd6634 100644 --- a/src/cascadia/WindowsTerminal/icon.cpp +++ b/src/cascadia/WindowsTerminal/icon.cpp @@ -27,22 +27,27 @@ static int _GetActiveAppIconResource() return iconResource; } -void UpdateWindowIconForActiveMetrics(HWND window) +HANDLE GetActiveAppIconHandle(int size) { auto iconResource{ MAKEINTRESOURCEW(_GetActiveAppIconResource()) }; + auto smXIcon = size == ICON_SMALL ? SM_CXSMICON : SM_CXICON; + auto smYIcon = size == ICON_SMALL ? SM_CYSMICON : SM_CYICON; + // These handles are loaded with LR_SHARED, so they are safe to "leak". - HANDLE smallIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) }; - LOG_LAST_ERROR_IF_NULL(smallIcon); + HANDLE hIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(smXIcon), GetSystemMetrics(smYIcon), LR_SHARED) }; + LOG_LAST_ERROR_IF_NULL(hIcon); - HANDLE largeIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_SHARED) }; - LOG_LAST_ERROR_IF_NULL(largeIcon); + return hIcon; +} - if (smallIcon) +void UpdateWindowIconForActiveMetrics(HWND window) +{ + if (auto smallIcon = GetActiveAppIconHandle(ICON_SMALL)) { SendMessageW(window, WM_SETICON, ICON_SMALL, reinterpret_cast(smallIcon)); } - if (largeIcon) + else if (auto largeIcon = GetActiveAppIconHandle(ICON_BIG)) { SendMessageW(window, WM_SETICON, ICON_BIG, reinterpret_cast(largeIcon)); } diff --git a/src/cascadia/WindowsTerminal/icon.h b/src/cascadia/WindowsTerminal/icon.h index 5e418fc284e..ed4fb5587f6 100644 --- a/src/cascadia/WindowsTerminal/icon.h +++ b/src/cascadia/WindowsTerminal/icon.h @@ -3,4 +3,5 @@ #pragma once +HANDLE GetActiveAppIconHandle(const int size); void UpdateWindowIconForActiveMetrics(HWND window); From eee447cdcc6e521735146cfba0a6914aa359787a Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 24 May 2021 18:50:28 -0700 Subject: [PATCH 05/57] cleanup --- src/cascadia/TerminalApp/AppLogic.h | 1 + src/cascadia/TerminalApp/TerminalPage.cpp | 11 ------ src/cascadia/TerminalApp/TerminalPage.h | 2 -- src/cascadia/WindowsTerminal/AppHost.cpp | 35 ++++++++++--------- src/cascadia/WindowsTerminal/IslandWindow.cpp | 9 +---- 5 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index d443e528e2b..c86b543005b 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -163,6 +163,7 @@ namespace winrt::TerminalApp::implementation 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; #endif diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index a7174bd5f58..7f728e5ad94 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -59,20 +59,9 @@ namespace winrt::TerminalApp::implementation HRESULT TerminalPage::Initialize(HWND hwnd) { _hostingHwnd = hwnd; - - TestNotifyIconFunction(); - return S_OK; } - void TerminalPage::TestNotifyIconFunction() - { - if (_hostingHwnd) - { - - } - } - // Function Description: // - Recursively check our commands to see if there's a keybinding for // exactly their action. If there is, label that command with the text diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 7a32e4217fd..794fd0e1568 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -341,8 +341,6 @@ namespace winrt::TerminalApp::implementation void _SetFocusMode(const bool inFocusMode); - void TestNotifyIconFunction(); - #pragma region ActionHandlers // These are all defined in AppActionHandlers.cpp #define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action); diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 73b4ad875ca..834fd6d4f67 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -93,7 +93,6 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { // destruction order is important for proper teardown here - _window = nullptr; _app.Close(); _app = nullptr; @@ -921,6 +920,25 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab _window->IsQuakeWindow(_logic.IsQuakeWindow()); } +void AppHost::_HandleTrayIconPressed() +{ + // TODO: + // Scoping "minimize to tray" to only the quake window, and so + // we can just summon ourselves. When we allow any window to be + // minimized, this could bring up the quake or MRU or all windows. + _window->SummonWindow({}); +} + +void AppHost::_HandleWindowMinimized() +{ + // TODO: + // Scoping "minimize to tray" to only the quake window. + if (_logic.IsQuakeWindow()) + { + _UpdateTrayIcon(); + } +} + void AppHost::_UpdateTrayIcon() { NOTIFYICONDATA nid{}; @@ -940,18 +958,3 @@ void AppHost::_UpdateTrayIcon() nid.uVersion = NOTIFYICON_VERSION_4; Shell_NotifyIcon(NIM_SETVERSION, &nid); } - -void AppHost::_HandleTrayIconPressed() -{ - _window->SummonWindow({}); -} - -void AppHost::_HandleWindowMinimized() -{ - // Scoping "minimize to tray" to just the quake window. - // Broader support will come in later. - if (_logic.IsQuakeWindow()) - { - _UpdateTrayIcon(); - } -} diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 60987586e4d..001d4155484 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -507,8 +507,6 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize case WM_THEMECHANGED: UpdateWindowIconForActiveMetrics(_window.get()); return 0; - // TODO: Give this a better name, something like WT_NOTIFYICON - // WM_APP to 0xBFFF is available for use for apps apparently. case WM_APP + 1: { switch (LOWORD(lparam)) @@ -517,12 +515,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize case NIN_KEYSELECT: { _NotifyTrayIconPressedHandlers(); - break; - } - case WM_CONTEXTMENU: - { - // TODO: show the context menu - buncho options to open specific windows? - break; + return 0; } } break; From a83686a66ad6de2f2cf94dd02a806ae989c84b35 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 24 May 2021 19:13:38 -0700 Subject: [PATCH 06/57] using the correct term --- src/cascadia/WindowsTerminal/AppHost.cpp | 5 +++-- src/cascadia/WindowsTerminal/AppHost.h | 2 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 4 +--- src/cascadia/WindowsTerminal/IslandWindow.h | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 834fd6d4f67..66cb79e7579 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -79,7 +79,7 @@ AppHost::AppHost() noexcept : _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); - _window->NotifyWindowMinimized({ this, &AppHost::_HandleWindowMinimized }); + _window->NotifyWindowHidden({ this, &AppHost::_HandleWindowHidden }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -93,6 +93,7 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { // destruction order is important for proper teardown here + _window = nullptr; _app.Close(); _app = nullptr; @@ -929,7 +930,7 @@ void AppHost::_HandleTrayIconPressed() _window->SummonWindow({}); } -void AppHost::_HandleWindowMinimized() +void AppHost::_HandleWindowHidden() { // TODO: // Scoping "minimize to tray" to only the quake window. diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 9efb31061f8..2262d7d0517 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -84,5 +84,5 @@ class AppHost void _UpdateTrayIcon(); void _HandleTrayIconPressed(); - void _HandleWindowMinimized(); + void _HandleWindowHidden(); }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 001d4155484..f6585a5a3cb 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -452,7 +452,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize { if (wparam == SIZE_MINIMIZED && _isQuakeWindow) { - _NotifyWindowMinimizedHandlers(); + _NotifyWindowHiddenHandlers(); ShowWindow(GetHandle(), SW_HIDE); return 0; } @@ -1289,8 +1289,6 @@ void IslandWindow::_globalDismissWindow(const uint32_t dropdownDuration) { ShowWindow(_window.get(), SW_MINIMIZE); } - - _NotifyWindowMinimizedHandlers(); } // Method Description: diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 9b4f8247a6b..24975738e70 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -52,7 +52,7 @@ class IslandWindow : WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); - WINRT_CALLBACK(NotifyWindowMinimized, winrt::delegate); + WINRT_CALLBACK(NotifyWindowHidden, winrt::delegate); protected: void ForceResize() From e8462e0156a35c0d270eb846239c4ecc138577ae Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 24 May 2021 23:48:27 -0700 Subject: [PATCH 07/57] not sure if necessary, but try not to add every single time --- src/cascadia/WindowsTerminal/AppHost.cpp | 51 +++++++++++++++--------- src/cascadia/WindowsTerminal/AppHost.h | 2 + 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 66cb79e7579..2d017ebecad 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -924,16 +924,17 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab void AppHost::_HandleTrayIconPressed() { // TODO: - // Scoping "minimize to tray" to only the quake window, and so - // we can just summon ourselves. When we allow any window to be - // minimized, this could bring up the quake or MRU or all windows. - _window->SummonWindow({}); + // Currently scoping "minimize to tray" to only the quake + // window, which means that only when a quake window is + // hidden will the icon appear. + if (_logic.IsQuakeWindow()) + { + _window->SummonWindow({}); + } } void AppHost::_HandleWindowHidden() { - // TODO: - // Scoping "minimize to tray" to only the quake window. if (_logic.IsQuakeWindow()) { _UpdateTrayIcon(); @@ -942,20 +943,32 @@ void AppHost::_HandleWindowHidden() void AppHost::_UpdateTrayIcon() { - NOTIFYICONDATA nid{}; + if (!_trayIconData) + { + NOTIFYICONDATA nid{}; + + // This HWND will receive the callbacks sent by the tray icon. + nid.hWnd = _window->GetHandle(); - // This HWND will receive the callbacks sent by the tray icon. - nid.hWnd = _window->GetHandle(); + nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); + nid.uID = 1; + nid.uCallbackMessage = WM_APP + 1; + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + Shell_NotifyIcon(NIM_ADD, &nid); - nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); - nid.uID = 1; - nid.uCallbackMessage = WM_APP + 1; - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); - nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; - Shell_NotifyIcon(NIM_ADD, &nid); + // NIM_ADD won't set the version even if uVersion is set in the nid. + // We have to perform a NIM_SETVERSION call separately. + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); + + _trayIconData = nid; + } + else + { + auto nid = _trayIconData.value(); + nid.hWnd = _window->GetHandle(); + Shell_NotifyIcon(NIM_MODIFY, &nid); + } - // NIM_ADD won't set the version even if uVersion is set in the nid. - // We have to perform a NIM_SETVERSION call separately. - nid.uVersion = NOTIFYICON_VERSION_4; - Shell_NotifyIcon(NIM_SETVERSION, &nid); } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 2262d7d0517..2af38ffa0e6 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -85,4 +85,6 @@ class AppHost void _UpdateTrayIcon(); void _HandleTrayIconPressed(); void _HandleWindowHidden(); + + std::optional _trayIconData; }; From b2b76ca62a703236c5ac7a0af6a4237818a02177 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 25 May 2021 09:49:12 -0700 Subject: [PATCH 08/57] remove when no longer quake --- src/cascadia/WindowsTerminal/AppHost.cpp | 39 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 2d017ebecad..961043e0c24 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -918,15 +918,24 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { + if (_window->IsQuakeWindow() && !_logic.IsQuakeWindow()) + { + // If we're exiting quake mode, we should make our + // tray icon disappear. + if (_trayIconData) + { + Shell_NotifyIcon(NIM_DELETE, &_trayIconData.value()); + _trayIconData.reset(); + } + } + _window->IsQuakeWindow(_logic.IsQuakeWindow()); } void AppHost::_HandleTrayIconPressed() { - // TODO: - // Currently scoping "minimize to tray" to only the quake - // window, which means that only when a quake window is - // hidden will the icon appear. + // Currently scoping "minimize to tray" to only + // the quake window. if (_logic.IsQuakeWindow()) { _window->SummonWindow({}); @@ -941,6 +950,14 @@ void AppHost::_HandleWindowHidden() } } +// Method Description: +// - Creates and adds an icon to the notification tray. +// Updates the current tray icon with the current window's +// HWND if an icon already exists. +// Arguments: +// - +// Return Value: +// - void AppHost::_UpdateTrayIcon() { if (!_trayIconData) @@ -950,15 +967,23 @@ void AppHost::_UpdateTrayIcon() // This HWND will receive the callbacks sent by the tray icon. nid.hWnd = _window->GetHandle(); - nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); + // App-defined identifier of the icon. The HWND and ID are used + // to identify which icon to operate on when calling Shell_NotifyIcon. + // Multiple icons can be associated with one HWND, but here we're only + // going to be showing one so the ID doesn't really matter. nid.uID = 1; + nid.uCallbackMessage = WM_APP + 1; + + nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &nid); - // NIM_ADD won't set the version even if uVersion is set in the nid. - // We have to perform a NIM_SETVERSION call separately. + // For whatever reason, the NIM_ADD call doesn't seem to set the version + // properly, resulting in us being unable to receive the expected notification + // events. We actually have to make a separate NIM_SETVERSION call for it to + // work properly. nid.uVersion = NOTIFYICON_VERSION_4; Shell_NotifyIcon(NIM_SETVERSION, &nid); From ce22c0c45e81850e3e1bf2e62101e10c909ad1ea Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 26 May 2021 10:31:48 -0700 Subject: [PATCH 09/57] pr comments, spelling --- .github/actions/spelling/allow/apis.txt | 7 ++++ src/cascadia/WindowsTerminal/AppHost.cpp | 34 ++++++------------- src/cascadia/WindowsTerminal/AppHost.h | 1 - src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 +- src/cascadia/WindowsTerminal/IslandWindow.h | 2 ++ 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index d4aa706a022..f25f217736a 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -64,6 +64,7 @@ ITab ITaskbar IUri IVirtual +KEYSELECT LCID llabs llu @@ -75,12 +76,16 @@ MULTIPLEUSE NCHITTEST NCLBUTTONDBLCLK NCRBUTTONDBLCLK +NIF +NIN NOAGGREGATION NOASYNC NOCHANGEDIR NOPROGRESS NOREDIRECTIONBITMAP NOREPEAT +NOTIFYICON +NOTIFYICONDATA ntprivapi oaidl ocidl @@ -100,9 +105,11 @@ RSHIFT schandle semver serializer +SETVERSION SHELLEXECUTEINFOW shobjidl SHOWMINIMIZED +SHOWTIP SINGLEUSE SIZENS smoothstep diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 961043e0c24..f04bdc81028 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -60,9 +60,6 @@ AppHost::AppHost() noexcept : _window = std::make_unique(); } - // Update our own internal state tracking if we're in quake mode or not. - _IsQuakeWindowChanged(nullptr, nullptr); - // Tell the window to callback to us when it's about to handle a WM_CREATE auto pfn = std::bind(&AppHost::_HandleCreateWindow, this, @@ -79,10 +76,12 @@ AppHost::AppHost() noexcept : _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); - _window->NotifyWindowHidden({ this, &AppHost::_HandleWindowHidden }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); + // Update our own internal state tracking if we're in quake mode or not. + _IsQuakeWindowChanged(nullptr, nullptr); + _windowManager.BecameMonarch({ this, &AppHost::_BecomeMonarch }); if (_windowManager.IsMonarch()) { @@ -928,6 +927,10 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab _trayIconData.reset(); } } + else if (!_window->IsQuakeWindow() && _logic.IsQuakeWindow()) + { + _UpdateTrayIcon(); + } _window->IsQuakeWindow(_logic.IsQuakeWindow()); } @@ -938,22 +941,14 @@ void AppHost::_HandleTrayIconPressed() // the quake window. if (_logic.IsQuakeWindow()) { - _window->SummonWindow({}); - } -} - -void AppHost::_HandleWindowHidden() -{ - if (_logic.IsQuakeWindow()) - { - _UpdateTrayIcon(); + const Remoting::SummonWindowBehavior summonArgs{}; + summonArgs.DropdownDuration(200); + _window->SummonWindow(summonArgs); } } // Method Description: // - Creates and adds an icon to the notification tray. -// Updates the current tray icon with the current window's -// HWND if an icon already exists. // Arguments: // - // Return Value: @@ -973,7 +968,7 @@ void AppHost::_UpdateTrayIcon() // going to be showing one so the ID doesn't really matter. nid.uID = 1; - nid.uCallbackMessage = WM_APP + 1; + nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); @@ -989,11 +984,4 @@ void AppHost::_UpdateTrayIcon() _trayIconData = nid; } - else - { - auto nid = _trayIconData.value(); - nid.hWnd = _window->GetHandle(); - Shell_NotifyIcon(NIM_MODIFY, &nid); - } - } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 2af38ffa0e6..d398ade057f 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -84,7 +84,6 @@ class AppHost void _UpdateTrayIcon(); void _HandleTrayIconPressed(); - void _HandleWindowHidden(); std::optional _trayIconData; }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index f6585a5a3cb..90b20482947 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -507,7 +507,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize case WM_THEMECHANGED: UpdateWindowIconForActiveMetrics(_window.get()); return 0; - case WM_APP + 1: + case CM_NOTIFY_FROM_TRAY: { switch (LOWORD(lparam)) { diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 24975738e70..c9842ff6a12 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -6,6 +6,8 @@ #include #include "../../cascadia/inc/cppwinrt_utils.h" +#define CM_NOTIFY_FROM_TRAY (WM_APP + 1) + class IslandWindow : public BaseWindow { From 8fa47182dd678b4e367d00d5d5f51395e2924438 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 26 May 2021 10:45:44 -0700 Subject: [PATCH 10/57] ok ok ok fine --- .github/actions/spelling/expect/expect.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 4a19919cce9..f4caf39f57d 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -2777,6 +2777,7 @@ Xes xff XFile XFORM +xIcon XManifest XMath XMFLOAT @@ -2811,6 +2812,7 @@ YCast YCENTER YCount YDPI +yIcon yml YOffset YPosition From bdfef549c9d81fa25d9794d5ba743a66c3932dcb Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 28 May 2021 09:26:02 -0700 Subject: [PATCH 11/57] saving progress --- src/cascadia/WindowsTerminal/AppHost.cpp | 67 ++++++++++++------- src/cascadia/WindowsTerminal/AppHost.h | 1 + src/cascadia/WindowsTerminal/IslandWindow.cpp | 11 ++- src/cascadia/WindowsTerminal/IslandWindow.h | 2 +- .../WindowsTerminal/TrayIconManager.cpp | 0 .../WindowsTerminal/TrayIconManager.h | 0 .../WindowsTerminal/WindowsTerminal.vcxproj | 29 +------- 7 files changed, 59 insertions(+), 51 deletions(-) create mode 100644 src/cascadia/WindowsTerminal/TrayIconManager.cpp create mode 100644 src/cascadia/WindowsTerminal/TrayIconManager.h diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index f04bdc81028..d9d230fd2a0 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -76,6 +76,7 @@ AppHost::AppHost() noexcept : _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); + _window->NotifyShowTrayContextMenu({this, &AppHost::_CreateTrayContextMenu }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -641,6 +642,7 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { + _UpdateTrayIcon(); _setupGlobalHotkeys(); } @@ -917,38 +919,19 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { - if (_window->IsQuakeWindow() && !_logic.IsQuakeWindow()) - { - // If we're exiting quake mode, we should make our - // tray icon disappear. - if (_trayIconData) - { - Shell_NotifyIcon(NIM_DELETE, &_trayIconData.value()); - _trayIconData.reset(); - } - } - else if (!_window->IsQuakeWindow() && _logic.IsQuakeWindow()) - { - _UpdateTrayIcon(); - } - _window->IsQuakeWindow(_logic.IsQuakeWindow()); } void AppHost::_HandleTrayIconPressed() { - // Currently scoping "minimize to tray" to only - // the quake window. - if (_logic.IsQuakeWindow()) - { - const Remoting::SummonWindowBehavior summonArgs{}; - summonArgs.DropdownDuration(200); - _window->SummonWindow(summonArgs); - } + // No name in the args means summon the mru window. + _windowManager.SummonWindow({}); } // Method Description: // - Creates and adds an icon to the notification tray. +// If an icon already exists, update the HWND associated +// to the icon with this window's HWND. // Arguments: // - // Return Value: @@ -984,4 +967,42 @@ void AppHost::_UpdateTrayIcon() _trayIconData = nid; } + else + { + _trayIconData.value().hWnd = _window->GetHandle(); + Shell_NotifyIcon(NIM_MODIFY, &_trayIconData.value()); + } +} + +void AppHost::_CreateTrayContextMenu(const til::point coord) +{ + auto hmenu = CreatePopupMenu(); + if (hmenu) + { + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-menuinfo + MENUINFO mi{}; + mi.fMask = MIM_APPLYTOSUBMENUS | MIM_STYLE; + mi.dwStyle = MNS_NOCHECK | MNS_NOTIFYBYPOS; + SetMenuInfo(hmenu, &mi); + + // Just testing how to insert menu items + InsertMenu(hmenu, 0, MF_STRING, 0, L"Start"); + + // We'll need to set our window to the foreground before calling + // TrackPopupMenuEx or else the menu won't dismiss when clicking away. + SetForegroundWindow(_window->GetHandle()); + + UINT uFlags = TPM_RIGHTBUTTON; + if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) + { + uFlags |= TPM_RIGHTALIGN; + } + else + { + uFlags |= TPM_LEFTALIGN; + } + + TrackPopupMenuEx(hmenu, uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL); + DestroyMenu(hmenu); + } } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index d398ade057f..cfc10ccf1ad 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -84,6 +84,7 @@ class AppHost void _UpdateTrayIcon(); void _HandleTrayIconPressed(); + void _CreateTrayContextMenu(const til::point coord); std::optional _trayIconData; }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 90b20482947..c2ae7177ae1 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -452,7 +452,6 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize { if (wparam == SIZE_MINIMIZED && _isQuakeWindow) { - _NotifyWindowHiddenHandlers(); ShowWindow(GetHandle(), SW_HIDE); return 0; } @@ -517,9 +516,19 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize _NotifyTrayIconPressedHandlers(); return 0; } + case WM_CONTEXTMENU: + { + const til::point eventPoint{ GET_X_LPARAM(wparam), GET_Y_LPARAM(wparam) }; + _NotifyShowTrayContextMenuHandlers(eventPoint); + return 0; + } } break; } + case WM_COMMAND: + { + return 0; + } } // TODO: handle messages here... diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index c9842ff6a12..7bb8854770c 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -54,7 +54,7 @@ class IslandWindow : WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); - WINRT_CALLBACK(NotifyWindowHidden, winrt::delegate); + WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate); protected: void ForceResize() diff --git a/src/cascadia/WindowsTerminal/TrayIconManager.cpp b/src/cascadia/WindowsTerminal/TrayIconManager.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/cascadia/WindowsTerminal/TrayIconManager.h b/src/cascadia/WindowsTerminal/TrayIconManager.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index d0b116ff356..7bfc6ef23ff 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -1,7 +1,6 @@ - {CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B} Win32Proj @@ -19,16 +18,13 @@ Windows true - - true - $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories); @@ -78,14 +74,11 @@ - - - x86 $(Platform) - <_OpenConsoleVCLibToCopy Include="$(VCToolsRedistInstallDir)\$(ReasonablePlatform)\Microsoft.VC142.CRT\*.dll" /> - $(ProjectName) BuiltProjectOutputGroup @@ -173,5 +151,4 @@ - - + \ No newline at end of file From 5f8495879fa33a9683ca2a1849e57b9a8ef90757 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 28 May 2021 09:34:43 -0700 Subject: [PATCH 12/57] run it back --- src/cascadia/WindowsTerminal/AppHost.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index f04bdc81028..7902c86500a 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -60,6 +60,9 @@ AppHost::AppHost() noexcept : _window = std::make_unique(); } + // Update our own internal state tracking if we're in quake mode or not. + _IsQuakeWindowChanged(nullptr, nullptr); + // Tell the window to callback to us when it's about to handle a WM_CREATE auto pfn = std::bind(&AppHost::_HandleCreateWindow, this, @@ -79,8 +82,10 @@ AppHost::AppHost() noexcept : _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); - // Update our own internal state tracking if we're in quake mode or not. - _IsQuakeWindowChanged(nullptr, nullptr); + if (_window->IsQuakeWindow()) + { + _UpdateTrayIcon(); + } _windowManager.BecameMonarch({ this, &AppHost::_BecomeMonarch }); if (_windowManager.IsMonarch()) From f4325392be0fa6c332640334e11daa0b311c7aab Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 28 May 2021 09:52:33 -0700 Subject: [PATCH 13/57] add a hwnd check --- src/cascadia/WindowsTerminal/AppHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 7b95bfe8cef..0b978fcd16b 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -979,7 +979,7 @@ void AppHost::_HandleTrayIconPressed() // - void AppHost::_UpdateTrayIcon() { - if (!_trayIconData) + if (!_trayIconData && _window->GetHandle()) { NOTIFYICONDATA nid{}; From b90f0aaec55a8b545af0b5255bfddb7f17d29b5e Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 2 Jun 2021 16:06:49 -0700 Subject: [PATCH 14/57] remove this --- src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 5e162cd297a..3dd9e38ecb0 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -147,10 +147,5 @@ -<<<<<<< HEAD - - -======= ->>>>>>> dev/lelian/notifyicon/proto From f82cffa42f6bcccd65e2a8b4a91062cc5b877518 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 7 Jun 2021 15:30:15 -0700 Subject: [PATCH 15/57] smooth like butter --- src/cascadia/Remoting/Monarch.cpp | 10 +++ src/cascadia/Remoting/Monarch.h | 2 + src/cascadia/Remoting/Monarch.idl | 2 + src/cascadia/Remoting/Peasant.cpp | 6 ++ src/cascadia/Remoting/WindowManager.cpp | 7 +- src/cascadia/Remoting/WindowManager.h | 2 + src/cascadia/Remoting/WindowManager.idl | 1 + .../TerminalApp/AppActionHandlers.cpp | 7 ++ src/cascadia/TerminalApp/AppLogic.h | 1 + src/cascadia/TerminalApp/AppLogic.idl | 1 + src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalApp/TerminalPage.idl | 1 + .../TerminalSettingsModel/ActionAndArgs.cpp | 2 + .../AllShortcutActions.h | 3 +- .../Resources/en-US/Resources.resw | 3 + src/cascadia/WindowsTerminal/AppHost.cpp | 64 +++++++++++++------ src/cascadia/WindowsTerminal/AppHost.h | 8 ++- src/cascadia/WindowsTerminal/IslandWindow.cpp | 1 + src/cascadia/WindowsTerminal/IslandWindow.h | 1 + 19 files changed, 100 insertions(+), 23 deletions(-) diff --git a/src/cascadia/Remoting/Monarch.cpp b/src/cascadia/Remoting/Monarch.cpp index f65422d3f9d..3ad10db53a5 100644 --- a/src/cascadia/Remoting/Monarch.cpp +++ b/src/cascadia/Remoting/Monarch.cpp @@ -762,4 +762,14 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TraceLoggingKeyword(TIL_KEYWORD_TRACE)); } } + + Windows::Foundation::Collections::IMap Monarch::GetPeasantNames() + { + auto names = winrt::single_threaded_map(); + for (auto [key, value] : _peasants) + { + names.Insert(key, value.WindowName()); + } + return names; + } } diff --git a/src/cascadia/Remoting/Monarch.h b/src/cascadia/Remoting/Monarch.h index 9dc8fc77e8a..a77cebb90db 100644 --- a/src/cascadia/Remoting/Monarch.h +++ b/src/cascadia/Remoting/Monarch.h @@ -51,6 +51,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void HandleActivatePeasant(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args); void SummonWindow(const Remoting::SummonWindowSelectionArgs& args); + Windows::Foundation::Collections::IMap GetPeasantNames(); + TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); private: diff --git a/src/cascadia/Remoting/Monarch.idl b/src/cascadia/Remoting/Monarch.idl index d87d780b3b6..31e3bc8b3bb 100644 --- a/src/cascadia/Remoting/Monarch.idl +++ b/src/cascadia/Remoting/Monarch.idl @@ -40,6 +40,8 @@ namespace Microsoft.Terminal.Remoting void HandleActivatePeasant(WindowActivatedArgs args); void SummonWindow(SummonWindowSelectionArgs args); + Windows.Foundation.Collections.IMap GetPeasantNames(); + event Windows.Foundation.TypedEventHandler FindTargetWindowRequested; }; } diff --git a/src/cascadia/Remoting/Peasant.cpp b/src/cascadia/Remoting/Peasant.cpp index 58a71acba26..3c0d44f6a98 100644 --- a/src/cascadia/Remoting/Peasant.cpp +++ b/src/cascadia/Remoting/Peasant.cpp @@ -30,6 +30,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void Peasant::AssignID(uint64_t id) { _id = id; + + // Provide a default name if we're currently unnamed. + if (_WindowName.empty()) + { + _WindowName = fmt::format(L"Window {}", _id); + } } uint64_t Peasant::GetID() { diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index 88e0adbf071..da2b93d3a74 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -274,7 +274,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation p->AssignID(givenID.value()); } - // If the name wasn't specified, this will be an empty string. p->WindowName(givenName); _peasant = *p; @@ -509,4 +508,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation _monarch.SummonWindow(args); } + Windows::Foundation::Collections::IMap WindowManager::GetPeasantNames() + { + assert(_monarch); + return _monarch.GetPeasantNames(); + } + } diff --git a/src/cascadia/Remoting/WindowManager.h b/src/cascadia/Remoting/WindowManager.h index 0b87075f975..60c78b4c083 100644 --- a/src/cascadia/Remoting/WindowManager.h +++ b/src/cascadia/Remoting/WindowManager.h @@ -40,6 +40,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation bool IsMonarch(); void SummonWindow(const Remoting::SummonWindowSelectionArgs& args); + Windows::Foundation::Collections::IMap GetPeasantNames(); + TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); TYPED_EVENT(BecameMonarch, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); diff --git a/src/cascadia/Remoting/WindowManager.idl b/src/cascadia/Remoting/WindowManager.idl index 547b96f9aa5..2dd2239ea0d 100644 --- a/src/cascadia/Remoting/WindowManager.idl +++ b/src/cascadia/Remoting/WindowManager.idl @@ -12,6 +12,7 @@ namespace Microsoft.Terminal.Remoting IPeasant CurrentWindow(); Boolean IsMonarch { get; }; void SummonWindow(SummonWindowSelectionArgs args); + Windows.Foundation.Collections.IMap GetPeasantNames(); event Windows.Foundation.TypedEventHandler FindTargetWindowRequested; event Windows.Foundation.TypedEventHandler BecameMonarch; }; diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index d3d51c56af7..8db545379cf 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -815,4 +815,11 @@ namespace winrt::TerminalApp::implementation } } } + + void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + _MinimizeToTrayRequestedHandlers(*this, nullptr); + args.Handled(true); + } } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 50b7b95f09d..78d1f666fe8 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -166,6 +166,7 @@ namespace winrt::TerminalApp::implementation FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested); FORWARDED_TYPED_EVENT(IsQuakeWindowChanged, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IsQuakeWindowChanged); FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested); + FORWARDED_TYPED_EVENT(MinimizeToTrayRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, MinimizeToTrayRequested); #ifdef UNIT_TESTING friend class TerminalAppLocalTests::CommandlineTest; diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index bb334d26f47..63ac2ee45dd 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -93,5 +93,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler SettingsChanged; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; event Windows.Foundation.TypedEventHandler SummonWindowRequested; + event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 9de1ded9b74..712c9fffe3f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -125,6 +125,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); TYPED_EVENT(SummonWindowRequested, IInspectable, IInspectable); + TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable); private: friend struct TerminalPageT; // for Xaml to bind events diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 0d055782268..79d23adb7b9 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -57,5 +57,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler RenameWindowRequested; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; event Windows.Foundation.TypedEventHandler SummonWindowRequested; + event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index fd6334e768f..6e264a4aff4 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -61,6 +61,7 @@ static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" }; static constexpr std::string_view GlobalSummonKey{ "globalSummon" }; static constexpr std::string_view QuakeModeKey{ "quakeMode" }; static constexpr std::string_view FocusPaneKey{ "focusPane" }; +static constexpr std::string_view MinimizeToTrayKey{ "minimizeToTray" }; static constexpr std::string_view ActionKey{ "action" }; @@ -330,6 +331,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") }, { ShortcutAction::FocusPane, L"" }, // Intentionally omitted, must be generated by GenerateName + { ShortcutAction::MinimizeToTray, RS_(L"MinimizeToTrayCommandKey") }, }; }(); diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index 5cfaf187a2f..10eabf5da99 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -75,7 +75,8 @@ ON_ALL_ACTIONS(OpenWindowRenamer) \ ON_ALL_ACTIONS(GlobalSummon) \ ON_ALL_ACTIONS(QuakeMode) \ - ON_ALL_ACTIONS(FocusPane) + ON_ALL_ACTIONS(FocusPane) \ + ON_ALL_ACTIONS(MinimizeToTray) #define ALL_SHORTCUT_ACTIONS_WITH_ARGS \ ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \ diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index c85167ef33b..0c5d2ca6cd3 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -413,4 +413,7 @@ Windows Console Host Name describing the usage of the classic windows console as the terminal UI. (`conhost.exe`) + + Minimize window to tray + diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 1070b5ec0af..be9a386046c 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -79,15 +79,11 @@ AppHost::AppHost() noexcept : _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); - _window->NotifyShowTrayContextMenu({this, &AppHost::_CreateTrayContextMenu }); + _window->NotifyShowTrayContextMenu({this, &AppHost::_ShowTrayContextMenu }); + _window->NotifyTrayMenuItemSelected({this, &AppHost::_TrayMenuItemSelected }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); - if (_window->IsQuakeWindow()) - { - _UpdateTrayIcon(); - } - _windowManager.BecameMonarch({ this, &AppHost::_BecomeMonarch }); if (_windowManager.IsMonarch()) { @@ -275,6 +271,7 @@ void AppHost::Initialize() _logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged }); _logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged }); _logic.SummonWindowRequested({ this, &AppHost::_SummonWindowRequested }); + _logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested }); _window->UpdateTitle(_logic.Title()); @@ -649,6 +646,7 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s const winrt::Windows::Foundation::IInspectable& /*args*/) { _UpdateTrayIcon(); + _CreateTrayContextMenu(); _setupGlobalHotkeys(); // The monarch is just going to be THE listener for inbound connections. @@ -946,6 +944,12 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta _HandleSummon(sender, summonArgs); } +void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable&, + const winrt::Windows::Foundation::IInspectable&) +{ + ShowWindow(_window->GetHandle(), SW_HIDE); +} + void AppHost::_HandleTrayIconPressed() { // No name in the args means summon the mru window. @@ -998,20 +1002,11 @@ void AppHost::_UpdateTrayIcon() } } -void AppHost::_CreateTrayContextMenu(const til::point coord) +void AppHost::_ShowTrayContextMenu(const til::point coord) { - auto hmenu = CreatePopupMenu(); - if (hmenu) + _trayContextMenu = _CreateTrayContextMenu(); + if (_trayContextMenu) { - // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-menuinfo - MENUINFO mi{}; - mi.fMask = MIM_APPLYTOSUBMENUS | MIM_STYLE; - mi.dwStyle = MNS_NOCHECK | MNS_NOTIFYBYPOS; - SetMenuInfo(hmenu, &mi); - - // Just testing how to insert menu items - InsertMenu(hmenu, 0, MF_STRING, 0, L"Start"); - // We'll need to set our window to the foreground before calling // TrackPopupMenuEx or else the menu won't dismiss when clicking away. SetForegroundWindow(_window->GetHandle()); @@ -1026,7 +1021,36 @@ void AppHost::_CreateTrayContextMenu(const til::point coord) uFlags |= TPM_LEFTALIGN; } - TrackPopupMenuEx(hmenu, uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL); - DestroyMenu(hmenu); + TrackPopupMenuEx(_trayContextMenu.value(), uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL); + } +} + +HMENU AppHost::_CreateTrayContextMenu() +{ + auto hmenu = CreatePopupMenu(); + if (hmenu) + { + MENUINFO mi{}; + mi.fMask = MIM_STYLE; + mi.dwStyle = MNS_NOCHECK; + assert(SetMenuInfo(hmenu, &mi)); + + // Get all peasants' window names + for (auto [id, name] : _windowManager.GetPeasantNames()) + { + AppendMenu(hmenu, MF_STRING, id, name.c_str()); + } } + return hmenu; +} + +void AppHost::_TrayMenuItemSelected(const UINT menuItemID) +{ + // Grab the window name associated to the given context menu item ID. + WCHAR name[255]; + GetMenuString(_trayContextMenu.value(), menuItemID, name, 255, MF_BYCOMMAND); + + Remoting::SummonWindowSelectionArgs args{ name }; + args.SummonBehavior().ToggleVisibility(false); + _windowManager.SummonWindow(args); } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 8daa2fc7b08..1396b27ffbe 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -86,9 +86,15 @@ class AppHost void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); + void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable&); + void _UpdateTrayIcon(); void _HandleTrayIconPressed(); - void _CreateTrayContextMenu(const til::point coord); + void _ShowTrayContextMenu(const til::point coord); + HMENU _CreateTrayContextMenu(); + void _TrayMenuItemSelected(const UINT menuItemID); std::optional _trayIconData; + std::optional _trayContextMenu; }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 63e00b4b777..e8117f545c1 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -527,6 +527,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize } case WM_COMMAND: { + _NotifyTrayMenuItemSelectedHandlers(static_cast(wparam)); return 0; } } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index cb2997aff93..cef9ea79766 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -55,6 +55,7 @@ class IslandWindow : WINRT_CALLBACK(HotkeyPressed, winrt::delegate); WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate); + WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate); protected: void ForceResize() From 46af976f2ddd9cb6745d06a08d2f19b659e5d0c0 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 7 Jun 2021 16:43:55 -0700 Subject: [PATCH 16/57] bring out your dead --- src/cascadia/Remoting/Monarch.cpp | 22 +++++++++++++++++-- src/cascadia/WindowsTerminal/AppHost.cpp | 7 +++++- .../WindowsTerminal/TrayIconManager.cpp | 0 .../WindowsTerminal/TrayIconManager.h | 0 .../WindowsTerminal/WindowsTerminal.vcxproj | 2 +- 5 files changed, 27 insertions(+), 4 deletions(-) delete mode 100644 src/cascadia/WindowsTerminal/TrayIconManager.cpp delete mode 100644 src/cascadia/WindowsTerminal/TrayIconManager.h diff --git a/src/cascadia/Remoting/Monarch.cpp b/src/cascadia/Remoting/Monarch.cpp index 3ad10db53a5..be5bbb87a76 100644 --- a/src/cascadia/Remoting/Monarch.cpp +++ b/src/cascadia/Remoting/Monarch.cpp @@ -766,10 +766,28 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation Windows::Foundation::Collections::IMap Monarch::GetPeasantNames() { auto names = winrt::single_threaded_map(); - for (auto [key, value] : _peasants) + + std::vector peasantsToErase{}; + for (const auto& [id, p] : _peasants) { - names.Insert(key, value.WindowName()); + try + { + names.Insert(id, p.WindowName()); + } + catch (...) + { + LOG_CAUGHT_EXCEPTION(); + peasantsToErase.push_back(id); + } } + + // Remove the dead peasants we came across while iterating. + for (const auto& id : peasantsToErase) + { + _peasants.erase(id); + _clearOldMruEntries(id); + } + return names; } } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index be9a386046c..093dfc62ee6 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -94,6 +94,11 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { // destruction order is important for proper teardown here + if (_trayIconData) + { + Shell_NotifyIcon(NIM_DELETE, &_trayIconData.value()); + _trayIconData.reset(); + } _window = nullptr; _app.Close(); @@ -646,7 +651,6 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s const winrt::Windows::Foundation::IInspectable& /*args*/) { _UpdateTrayIcon(); - _CreateTrayContextMenu(); _setupGlobalHotkeys(); // The monarch is just going to be THE listener for inbound connections. @@ -1027,6 +1031,7 @@ void AppHost::_ShowTrayContextMenu(const til::point coord) HMENU AppHost::_CreateTrayContextMenu() { + assert(_windowManager.IsMonarch()); auto hmenu = CreatePopupMenu(); if (hmenu) { diff --git a/src/cascadia/WindowsTerminal/TrayIconManager.cpp b/src/cascadia/WindowsTerminal/TrayIconManager.cpp deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/cascadia/WindowsTerminal/TrayIconManager.h b/src/cascadia/WindowsTerminal/TrayIconManager.h deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 3dd9e38ecb0..179cad2c266 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -148,4 +148,4 @@ - + \ No newline at end of file From ef3230d930c22ddfe9f034305f8821172e7d16d5 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 8 Jun 2021 11:37:07 -0700 Subject: [PATCH 17/57] using menucommand instead --- src/cascadia/WindowsTerminal/AppHost.cpp | 31 +++++++++++++++---- src/cascadia/WindowsTerminal/AppHost.h | 2 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 093dfc62ee6..3d61c4035b7 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -973,6 +973,7 @@ void AppHost::_UpdateTrayIcon() if (!_trayIconData && _window->GetHandle()) { NOTIFYICONDATA nid{}; + nid.cbSize = sizeof(NOTIFYICONDATA); // This HWND will receive the callbacks sent by the tray icon. nid.hWnd = _window->GetHandle(); @@ -1031,29 +1032,47 @@ void AppHost::_ShowTrayContextMenu(const til::point coord) HMENU AppHost::_CreateTrayContextMenu() { - assert(_windowManager.IsMonarch()); auto hmenu = CreatePopupMenu(); if (hmenu) { MENUINFO mi{}; + mi.cbSize = sizeof(MENUINFO); mi.fMask = MIM_STYLE; - mi.dwStyle = MNS_NOCHECK; - assert(SetMenuInfo(hmenu, &mi)); + mi.dwStyle = MNS_NOTIFYBYPOS; + SetMenuInfo(hmenu, &mi); + + // TODO: Other useful options may include: + // - Summon All + // - Summon MRU (though that's technically already available with a left click) + // - Quit All + + // Add the quit all option. + // TODO: Localize this string and slap it in a variable. + AppendMenu(hmenu, MF_STRING, 0, L"Summon All Windows"); + AppendMenu(hmenu, MF_SEPARATOR, 0, L""); // Get all peasants' window names for (auto [id, name] : _windowManager.GetPeasantNames()) { + // Technically, the id doesn't matter here since we'll + // be referring to this menu item through its position + // in the context menu. AppendMenu(hmenu, MF_STRING, id, name.c_str()); } } return hmenu; } -void AppHost::_TrayMenuItemSelected(const UINT menuItemID) +void AppHost::_TrayMenuItemSelected(const UINT menuItemIndex) { - // Grab the window name associated to the given context menu item ID. + // Grab the window name associated to the given context menu item position. WCHAR name[255]; - GetMenuString(_trayContextMenu.value(), menuItemID, name, 255, MF_BYCOMMAND); + GetMenuString(_trayContextMenu.value(), menuItemIndex, name, 255, MF_BYPOSITION); + + if (menuItemIndex == 0) + { + + } Remoting::SummonWindowSelectionArgs args{ name }; args.SummonBehavior().ToggleVisibility(false); diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 1396b27ffbe..a6191f83fb8 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -93,7 +93,7 @@ class AppHost void _HandleTrayIconPressed(); void _ShowTrayContextMenu(const til::point coord); HMENU _CreateTrayContextMenu(); - void _TrayMenuItemSelected(const UINT menuItemID); + void _TrayMenuItemSelected(const UINT menuItemIndex); std::optional _trayIconData; std::optional _trayContextMenu; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index e8117f545c1..c6720c6a3e3 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -525,7 +525,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize } break; } - case WM_COMMAND: + case WM_MENUCOMMAND: { _NotifyTrayMenuItemSelectedHandlers(static_cast(wparam)); return 0; From 900609245f71e021bbb7dcdbdda32ff43bcc4f89 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 8 Jun 2021 11:44:57 -0700 Subject: [PATCH 18/57] bringing things in line --- src/cascadia/WindowsTerminal/AppHost.cpp | 15 +++-------- .../WindowsTerminal/WindowsTerminal.vcxproj | 26 +++++++++++++++++-- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 3d61c4035b7..74371d690f9 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1043,14 +1043,12 @@ HMENU AppHost::_CreateTrayContextMenu() // TODO: Other useful options may include: // - Summon All - // - Summon MRU (though that's technically already available with a left click) + // - Summon MRU or Monarch + // - Though that's technically already available with a left click + // but may be a reasonable request to also put it explicitly in the + // context menu // - Quit All - // Add the quit all option. - // TODO: Localize this string and slap it in a variable. - AppendMenu(hmenu, MF_STRING, 0, L"Summon All Windows"); - AppendMenu(hmenu, MF_SEPARATOR, 0, L""); - // Get all peasants' window names for (auto [id, name] : _windowManager.GetPeasantNames()) { @@ -1069,11 +1067,6 @@ void AppHost::_TrayMenuItemSelected(const UINT menuItemIndex) WCHAR name[255]; GetMenuString(_trayContextMenu.value(), menuItemIndex, name, 255, MF_BYPOSITION); - if (menuItemIndex == 0) - { - - } - Remoting::SummonWindowSelectionArgs args{ name }; args.SummonBehavior().ToggleVisibility(false); _windowManager.SummonWindow(args); diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 179cad2c266..e6157306c07 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -1,6 +1,7 @@ + {CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B} Win32Proj @@ -15,13 +16,16 @@ Windows true + + true + $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories); @@ -71,11 +75,14 @@ + + + x86 $(Platform) + <_OpenConsoleVCLibToCopy Include="$(VCToolsRedistInstallDir)\$(ReasonablePlatform)\Microsoft.VC142.CRT\*.dll" /> + $(ProjectName) BuiltProjectOutputGroup From 3aebbbdfc93b84d35ebbfc12fbe5c1e871594aca Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 8 Jun 2021 11:46:06 -0700 Subject: [PATCH 19/57] ok.... --- src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index e6157306c07..b92f8589fd1 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -170,4 +170,4 @@ - \ No newline at end of file + From e519aa4cee8718310502bd5454b96eed0dfe4427 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 8 Jun 2021 11:48:26 -0700 Subject: [PATCH 20/57] i missed you, spellchk --- .github/actions/spelling/allow/apis.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index ed541e40f1f..eb50ffc17d3 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -5,6 +5,7 @@ alignof bitfield bitfields BUILDNUMBER +BYPOSITION charconv CLASSNOTAVAILABLE cmdletbinding @@ -72,6 +73,8 @@ llu localtime lround LSHIFT +MENUCOMMAND +MENUINFO msappx MULTIPLEUSE NCHITTEST @@ -85,6 +88,7 @@ NOCHANGEDIR NOPROGRESS NOREDIRECTIONBITMAP NOREPEAT +NOTIFYBYPOS NOTIFYICON NOTIFYICONDATA ntprivapi From 03f138ff538f901bb526ad74ab1c04e02c0824b2 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 15 Jun 2021 09:59:59 -0700 Subject: [PATCH 21/57] pr comments, updates' --- src/cascadia/Remoting/Peasant.cpp | 4 +- .../Remoting/Resources/en-US/Resources.resw | 3 + src/cascadia/Remoting/WindowManager.cpp | 4 +- src/cascadia/WindowsTerminal/AppHost.cpp | 72 +++++++++---------- src/cascadia/WindowsTerminal/AppHost.h | 5 +- src/cascadia/WindowsTerminal/BaseWindow.h | 3 + src/cascadia/WindowsTerminal/IslandWindow.cpp | 12 +++- src/cascadia/WindowsTerminal/IslandWindow.h | 3 +- src/cascadia/WindowsTerminal/icon.cpp | 6 +- 9 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/cascadia/Remoting/Peasant.cpp b/src/cascadia/Remoting/Peasant.cpp index 3c0d44f6a98..c8cd0a93f89 100644 --- a/src/cascadia/Remoting/Peasant.cpp +++ b/src/cascadia/Remoting/Peasant.cpp @@ -8,6 +8,8 @@ #include "Peasant.g.cpp" #include "../../types/inc/utils.hpp" +#include + using namespace winrt; using namespace winrt::Microsoft::Terminal; using namespace winrt::Windows::Foundation; @@ -34,7 +36,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation // Provide a default name if we're currently unnamed. if (_WindowName.empty()) { - _WindowName = fmt::format(L"Window {}", _id); + _WindowName = fmt::format(L"{} {}", RS_(L"Window"), _id); } } uint64_t Peasant::GetID() diff --git a/src/cascadia/Remoting/Resources/en-US/Resources.resw b/src/cascadia/Remoting/Resources/en-US/Resources.resw index f4af46df557..a97f00087b0 100644 --- a/src/cascadia/Remoting/Resources/en-US/Resources.resw +++ b/src/cascadia/Remoting/Resources/en-US/Resources.resw @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Window + diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index da2b93d3a74..5331afafdde 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -274,6 +274,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation p->AssignID(givenID.value()); } + // If the name wasn't specified, this will be an empty string. p->WindowName(givenName); _peasant = *p; @@ -510,7 +511,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation Windows::Foundation::Collections::IMap WindowManager::GetPeasantNames() { - assert(_monarch); + // We should only get called when we're the monarch since the monarch + // is the only one that knows about all peasants. return _monarch.GetPeasantNames(); } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 74371d690f9..53c5241be77 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -81,6 +81,7 @@ AppHost::AppHost() noexcept : _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); _window->NotifyShowTrayContextMenu({this, &AppHost::_ShowTrayContextMenu }); _window->NotifyTrayMenuItemSelected({this, &AppHost::_TrayMenuItemSelected }); + _window->NotifyCreateTrayIcon({ this, &AppHost::_CreateTrayIcon }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -650,7 +651,7 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { - _UpdateTrayIcon(); + _CreateTrayIcon(); _setupGlobalHotkeys(); // The monarch is just going to be THE listener for inbound connections. @@ -968,49 +969,40 @@ void AppHost::_HandleTrayIconPressed() // - // Return Value: // - -void AppHost::_UpdateTrayIcon() +void AppHost::_CreateTrayIcon() { - if (!_trayIconData && _window->GetHandle()) - { - NOTIFYICONDATA nid{}; - nid.cbSize = sizeof(NOTIFYICONDATA); + NOTIFYICONDATA nid{}; + nid.cbSize = sizeof(NOTIFYICONDATA); - // This HWND will receive the callbacks sent by the tray icon. - nid.hWnd = _window->GetHandle(); + // This HWND will receive the callbacks sent by the tray icon. + nid.hWnd = _window->GetHandle(); - // App-defined identifier of the icon. The HWND and ID are used - // to identify which icon to operate on when calling Shell_NotifyIcon. - // Multiple icons can be associated with one HWND, but here we're only - // going to be showing one so the ID doesn't really matter. - nid.uID = 1; + // App-defined identifier of the icon. The HWND and ID are used + // to identify which icon to operate on when calling Shell_NotifyIcon. + // Multiple icons can be associated with one HWND, but here we're only + // going to be showing one so the ID doesn't really matter. + nid.uID = 1; - nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; + nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; - nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); - nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; - Shell_NotifyIcon(NIM_ADD, &nid); + nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + Shell_NotifyIcon(NIM_ADD, &nid); - // For whatever reason, the NIM_ADD call doesn't seem to set the version - // properly, resulting in us being unable to receive the expected notification - // events. We actually have to make a separate NIM_SETVERSION call for it to - // work properly. - nid.uVersion = NOTIFYICON_VERSION_4; - Shell_NotifyIcon(NIM_SETVERSION, &nid); + // For whatever reason, the NIM_ADD call doesn't seem to set the version + // properly, resulting in us being unable to receive the expected notification + // events. We actually have to make a separate NIM_SETVERSION call for it to + // work properly. + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); - _trayIconData = nid; - } - else - { - _trayIconData.value().hWnd = _window->GetHandle(); - Shell_NotifyIcon(NIM_MODIFY, &_trayIconData.value()); - } + _trayIconData = nid; } void AppHost::_ShowTrayContextMenu(const til::point coord) { - _trayContextMenu = _CreateTrayContextMenu(); - if (_trayContextMenu) + if (auto hmenu = _CreateTrayContextMenu()) { // We'll need to set our window to the foreground before calling // TrackPopupMenuEx or else the menu won't dismiss when clicking away. @@ -1026,7 +1018,7 @@ void AppHost::_ShowTrayContextMenu(const til::point coord) uFlags |= TPM_LEFTALIGN; } - TrackPopupMenuEx(_trayContextMenu.value(), uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL); + TrackPopupMenuEx(hmenu, uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL); } } @@ -1037,7 +1029,7 @@ HMENU AppHost::_CreateTrayContextMenu() { MENUINFO mi{}; mi.cbSize = sizeof(MENUINFO); - mi.fMask = MIM_STYLE; + mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS; mi.dwStyle = MNS_NOTIFYBYPOS; SetMenuInfo(hmenu, &mi); @@ -1048,24 +1040,26 @@ HMENU AppHost::_CreateTrayContextMenu() // but may be a reasonable request to also put it explicitly in the // context menu // - Quit All + // It also might be nice to add options to changing the left click + // behavior (e.g. mru window or all windows or quake window) // Get all peasants' window names - for (auto [id, name] : _windowManager.GetPeasantNames()) + for (const auto [id, name] : _windowManager.GetPeasantNames()) { // Technically, the id doesn't matter here since we'll // be referring to this menu item through its position // in the context menu. - AppendMenu(hmenu, MF_STRING, id, name.c_str()); + AppendMenu(hmenu, MF_STRING, (UINT_PTR)id, name.c_str()); } } return hmenu; } -void AppHost::_TrayMenuItemSelected(const UINT menuItemIndex) +void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { // Grab the window name associated to the given context menu item position. WCHAR name[255]; - GetMenuString(_trayContextMenu.value(), menuItemIndex, name, 255, MF_BYPOSITION); + GetMenuString(menu, menuItemIndex, name, 255, MF_BYPOSITION); Remoting::SummonWindowSelectionArgs args{ name }; args.SummonBehavior().ToggleVisibility(false); diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index a6191f83fb8..5fdda9a259e 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -89,12 +89,11 @@ class AppHost void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable&); - void _UpdateTrayIcon(); + void _CreateTrayIcon(); void _HandleTrayIconPressed(); void _ShowTrayContextMenu(const til::point coord); HMENU _CreateTrayContextMenu(); - void _TrayMenuItemSelected(const UINT menuItemIndex); + void _TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex); std::optional _trayIconData; - std::optional _trayContextMenu; }; diff --git a/src/cascadia/WindowsTerminal/BaseWindow.h b/src/cascadia/WindowsTerminal/BaseWindow.h index d1a8b86d775..fd6528f93ae 100644 --- a/src/cascadia/WindowsTerminal/BaseWindow.h +++ b/src/cascadia/WindowsTerminal/BaseWindow.h @@ -8,6 +8,9 @@ #include +#include +UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources") + template class BaseWindow { diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index c6720c6a3e3..c835dbff53f 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -21,6 +21,8 @@ using namespace ::Microsoft::Console::Types; #define XAML_HOSTING_WINDOW_CLASS_NAME L"CASCADIA_HOSTING_WINDOW_CLASS" +const UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated"); + IslandWindow::IslandWindow() noexcept : _interopWindowHandle{ nullptr }, _rootGrid{ nullptr }, @@ -527,11 +529,19 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize } case WM_MENUCOMMAND: { - _NotifyTrayMenuItemSelectedHandlers(static_cast(wparam)); + _NotifyTrayMenuItemSelectedHandlers((HMENU)lparam, (UINT)wparam); return 0; } } + // We'll want to receive this message when explorer.exe restarts + // so that we can re-add our icon to the tray. + if (message == WM_TASKBARCREATED) + { + _NotifyCreateTrayIconHandlers(); + return 0; + } + // TODO: handle messages here... return base_type::MessageHandler(message, wparam, lparam); } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index cef9ea79766..7448add4ccf 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -55,7 +55,8 @@ class IslandWindow : WINRT_CALLBACK(HotkeyPressed, winrt::delegate); WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate); - WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate); + WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate); + WINRT_CALLBACK(NotifyCreateTrayIcon, winrt::delegate); protected: void ForceResize() diff --git a/src/cascadia/WindowsTerminal/icon.cpp b/src/cascadia/WindowsTerminal/icon.cpp index 01000cd6634..4706894ad43 100644 --- a/src/cascadia/WindowsTerminal/icon.cpp +++ b/src/cascadia/WindowsTerminal/icon.cpp @@ -31,8 +31,8 @@ HANDLE GetActiveAppIconHandle(int size) { auto iconResource{ MAKEINTRESOURCEW(_GetActiveAppIconResource()) }; - auto smXIcon = size == ICON_SMALL ? SM_CXSMICON : SM_CXICON; - auto smYIcon = size == ICON_SMALL ? SM_CYSMICON : SM_CYICON; + const auto smXIcon = size == ICON_SMALL ? SM_CXSMICON : SM_CXICON; + const auto smYIcon = size == ICON_SMALL ? SM_CYSMICON : SM_CYICON; // These handles are loaded with LR_SHARED, so they are safe to "leak". HANDLE hIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(smXIcon), GetSystemMetrics(smYIcon), LR_SHARED) }; @@ -47,7 +47,7 @@ void UpdateWindowIconForActiveMetrics(HWND window) { SendMessageW(window, WM_SETICON, ICON_SMALL, reinterpret_cast(smallIcon)); } - else if (auto largeIcon = GetActiveAppIconHandle(ICON_BIG)) + if (auto largeIcon = GetActiveAppIconHandle(ICON_BIG)) { SendMessageW(window, WM_SETICON, ICON_BIG, reinterpret_cast(largeIcon)); } From cc1ec725d17be54d3723912061cc4141bc8ef3d2 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 15 Jun 2021 11:46:57 -0700 Subject: [PATCH 22/57] add the two settings --- src/cascadia/TerminalApp/AppLogic.cpp | 22 +++++++++++++++++++ src/cascadia/TerminalApp/AppLogic.h | 3 +++ src/cascadia/TerminalApp/AppLogic.idl | 3 +++ .../GlobalAppSettings.cpp | 10 +++++++++ .../TerminalSettingsModel/GlobalAppSettings.h | 2 ++ .../GlobalAppSettings.idl | 2 ++ .../TerminalSettingsModel/defaults.json | 2 ++ src/cascadia/WindowsTerminal/AppHost.cpp | 6 ++++- 8 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 449d19b6b74..250f3b87c48 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1472,4 +1472,26 @@ namespace winrt::TerminalApp::implementation return _root->IsQuakeWindow(); } + bool AppLogic::GetMinimizeToTray() + { + if (!_loadedInitialSettings) + { + // Load settings if we haven't already + LoadSettings(); + } + + return _settings.GlobalSettings().MinimizeToTray(); + } + + bool AppLogic::GetAlwaysShowTrayIcon() + { + if (!_loadedInitialSettings) + { + // Load settings if we haven't already + LoadSettings(); + } + + return _settings.GlobalSettings().AlwaysShowTrayIcon(); + } + } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 78d1f666fe8..0153cfa09f7 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -90,6 +90,9 @@ namespace winrt::TerminalApp::implementation size_t GetLastActiveControlTaskbarState(); size_t GetLastActiveControlTaskbarProgress(); + bool GetMinimizeToTray(); + bool GetAlwaysShowTrayIcon(); + winrt::Windows::Foundation::IAsyncOperation ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog); Windows::Foundation::Collections::IMapView GlobalHotkeys(); diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 63ac2ee45dd..0b935aa5371 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -71,6 +71,9 @@ namespace TerminalApp UInt64 GetLastActiveControlTaskbarState(); UInt64 GetLastActiveControlTaskbarProgress(); + Boolean GetMinimizeToTray(); + Boolean GetAlwaysShowTrayIcon(); + FindTargetWindowResult FindTargetWindow(String[] args); Windows.Foundation.Collections.IMapView GlobalHotkeys(); diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp index 39c370228d0..465238260da 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp @@ -47,6 +47,8 @@ static constexpr std::string_view StartupActionsKey{ "startupActions" }; static constexpr std::string_view FocusFollowMouseKey{ "focusFollowMouse" }; static constexpr std::string_view WindowingBehaviorKey{ "windowingBehavior" }; static constexpr std::string_view TrimBlockSelectionKey{ "trimBlockSelection" }; +static constexpr std::string_view AlwaysShowTrayIconKey{ "alwaysShowTrayIcon" }; +static constexpr std::string_view MinimizeToTrayKey{ "minimizeToTray" }; static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" }; @@ -127,6 +129,8 @@ winrt::com_ptr GlobalAppSettings::Copy() const globals->_WindowingBehavior = _WindowingBehavior; globals->_TrimBlockSelection = _TrimBlockSelection; globals->_DetectURLs = _DetectURLs; + globals->_MinimizeToTray = _MinimizeToTray; + globals->_AlwaysShowTrayIcon = _AlwaysShowTrayIcon; globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile; globals->_validDefaultProfile = _validDefaultProfile; @@ -315,6 +319,10 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(json, DetectURLsKey, _DetectURLs); + JsonUtils::GetValueForKey(json, MinimizeToTrayKey, _MinimizeToTray); + + JsonUtils::GetValueForKey(json, AlwaysShowTrayIconKey, _AlwaysShowTrayIcon); + // This is a helper lambda to get the keybindings and commands out of both // and array of objects. We'll use this twice, once on the legacy // `keybindings` key, and again on the newer `bindings` key. @@ -409,6 +417,8 @@ Json::Value GlobalAppSettings::ToJson() const JsonUtils::SetValueForKey(json, WindowingBehaviorKey, _WindowingBehavior); JsonUtils::SetValueForKey(json, TrimBlockSelectionKey, _TrimBlockSelection); JsonUtils::SetValueForKey(json, DetectURLsKey, _DetectURLs); + JsonUtils::SetValueForKey(json, MinimizeToTrayKey, _MinimizeToTray); + JsonUtils::SetValueForKey(json, AlwaysShowTrayIconKey, _AlwaysShowTrayIcon); // clang-format on json[JsonKey(ActionsKey)] = _actionMap->ToJson(); diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h index f93bcd0e3bf..58c5c6429ce 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h @@ -91,6 +91,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::GlobalAppSettings, Model::WindowingMode, WindowingBehavior, Model::WindowingMode::UseNew); INHERITABLE_SETTING(Model::GlobalAppSettings, bool, TrimBlockSelection, false); INHERITABLE_SETTING(Model::GlobalAppSettings, bool, DetectURLs, true); + INHERITABLE_SETTING(Model::GlobalAppSettings, bool, MinimizeToTray, false); + INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysShowTrayIcon, false); private: guid _defaultProfile; diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl index 9f3c8c745e0..fcf5172bfba 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl @@ -69,6 +69,8 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_SETTING(WindowingMode, WindowingBehavior); INHERITABLE_SETTING(Boolean, TrimBlockSelection); INHERITABLE_SETTING(Boolean, DetectURLs); + INHERITABLE_SETTING(Boolean, MinimizeToTray); + INHERITABLE_SETTING(Boolean, AlwaysShowTrayIcon); Windows.Foundation.Collections.IMapView ColorSchemes(); void AddColorScheme(ColorScheme scheme); diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 84f52f287b2..45b38f0a63c 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -29,6 +29,8 @@ "disableAnimations": false, "startupActions": "", "focusFollowMouse": false, + "minimizeToTray": false, + "alwaysShowTrayIcon": false, "profiles": [ diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 53c5241be77..a5f5c478b84 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -651,7 +651,11 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { - _CreateTrayIcon(); + if (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray()) + { + _CreateTrayIcon(); + } + _setupGlobalHotkeys(); // The monarch is just going to be THE listener for inbound connections. From 07467bc221a9c0e2e7f108a79565f5b58f87fb90 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 15 Jun 2021 12:34:19 -0700 Subject: [PATCH 23/57] formatting? --- .github/actions/spelling/allow/apis.txt | 2 + src/cascadia/WindowsTerminal/AppHost.cpp | 93 +++++++++++-------- src/cascadia/WindowsTerminal/AppHost.h | 5 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 14 +++ src/cascadia/WindowsTerminal/IslandWindow.h | 5 + 5 files changed, 80 insertions(+), 39 deletions(-) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index eb50ffc17d3..a2c3897c628 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -2,6 +2,7 @@ ACCEPTFILES ACCESSDENIED alignas alignof +APPLYTOSUBMENUS bitfield bitfields BUILDNUMBER @@ -129,6 +130,7 @@ Stubless Subheader Subpage syscall +TASKBARCREATED TBPF THEMECHANGED tmp diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index a5f5c478b84..19390be7a11 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -79,9 +79,9 @@ AppHost::AppHost() noexcept : _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); - _window->NotifyShowTrayContextMenu({this, &AppHost::_ShowTrayContextMenu }); - _window->NotifyTrayMenuItemSelected({this, &AppHost::_TrayMenuItemSelected }); - _window->NotifyCreateTrayIcon({ this, &AppHost::_CreateTrayIcon }); + _window->NotifyShowTrayContextMenu({ this, &AppHost::_ShowTrayContextMenu }); + _window->NotifyTrayMenuItemSelected({ this, &AppHost::_TrayMenuItemSelected }); + _window->NotifyCreateTrayIcon({ this, &AppHost::_UpdateTrayIcon }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -95,12 +95,7 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { // destruction order is important for proper teardown here - if (_trayIconData) - { - Shell_NotifyIcon(NIM_DELETE, &_trayIconData.value()); - _trayIconData.reset(); - } - + _DestroyTrayIcon(); _window = nullptr; _app.Close(); _app = nullptr; @@ -651,11 +646,7 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { - if (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray()) - { - _CreateTrayIcon(); - } - + _UpdateTrayIcon(); _setupGlobalHotkeys(); // The monarch is just going to be THE listener for inbound connections. @@ -935,6 +926,13 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta const winrt::Windows::Foundation::IInspectable& /*args*/) { _setupGlobalHotkeys(); + + if (_windowManager.IsMonarch()) + { + _UpdateTrayIcon(); + } + + _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); } void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&, @@ -956,7 +954,7 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { - ShowWindow(_window->GetHandle(), SW_HIDE); + _window->HideWindow(); } void AppHost::_HandleTrayIconPressed() @@ -973,35 +971,47 @@ void AppHost::_HandleTrayIconPressed() // - // Return Value: // - -void AppHost::_CreateTrayIcon() +void AppHost::_UpdateTrayIcon() { - NOTIFYICONDATA nid{}; - nid.cbSize = sizeof(NOTIFYICONDATA); + if (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray()) + { + if (!_trayIconData) + { + NOTIFYICONDATA nid{}; + nid.cbSize = sizeof(NOTIFYICONDATA); - // This HWND will receive the callbacks sent by the tray icon. - nid.hWnd = _window->GetHandle(); + // This HWND will receive the callbacks sent by the tray icon. + nid.hWnd = _window->GetHandle(); - // App-defined identifier of the icon. The HWND and ID are used - // to identify which icon to operate on when calling Shell_NotifyIcon. - // Multiple icons can be associated with one HWND, but here we're only - // going to be showing one so the ID doesn't really matter. - nid.uID = 1; + // App-defined identifier of the icon. The HWND and ID are used + // to identify which icon to operate on when calling Shell_NotifyIcon. + // Multiple icons can be associated with one HWND, but here we're only + // going to be showing one so the ID doesn't really matter. + nid.uID = 1; - nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; + nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; - nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); - nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; - Shell_NotifyIcon(NIM_ADD, &nid); + nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + Shell_NotifyIcon(NIM_ADD, &nid); - // For whatever reason, the NIM_ADD call doesn't seem to set the version - // properly, resulting in us being unable to receive the expected notification - // events. We actually have to make a separate NIM_SETVERSION call for it to - // work properly. - nid.uVersion = NOTIFYICON_VERSION_4; - Shell_NotifyIcon(NIM_SETVERSION, &nid); + // For whatever reason, the NIM_ADD call doesn't seem to set the version + // properly, resulting in us being unable to receive the expected notification + // events. We actually have to make a separate NIM_SETVERSION call for it to + // work properly. + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); - _trayIconData = nid; + _trayIconData = nid; + } + } + else if (_trayIconData) + { + // We have a tray icon existing, but the now the new settings + // are telling us we don't want you so poof. + _DestroyTrayIcon(); + } } void AppHost::_ShowTrayContextMenu(const til::point coord) @@ -1069,3 +1079,12 @@ void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) args.SummonBehavior().ToggleVisibility(false); _windowManager.SummonWindow(args); } + +void AppHost::_DestroyTrayIcon() +{ + if (_trayIconData) + { + Shell_NotifyIcon(NIM_DELETE, &_trayIconData.value()); + _trayIconData.reset(); + } +} diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 5fdda9a259e..fc4dc2c489d 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -87,13 +87,14 @@ class AppHost const winrt::Windows::Foundation::IInspectable& args); void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender, - const winrt::Windows::Foundation::IInspectable&); + const winrt::Windows::Foundation::IInspectable&); - void _CreateTrayIcon(); + void _UpdateTrayIcon(); void _HandleTrayIconPressed(); void _ShowTrayContextMenu(const til::point coord); HMENU _CreateTrayContextMenu(); void _TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex); + void _DestroyTrayIcon(); std::optional _trayIconData; }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index c835dbff53f..19dcf0dfff3 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -564,6 +564,10 @@ void IslandWindow::OnResize(const UINT width, const UINT height) void IslandWindow::OnMinimize() { // TODO GH#1989 Stop rendering island content when the app is minimized. + if (_minimizeToTray) + { + HideWindow(); + } } // Method Description: @@ -1493,5 +1497,15 @@ void IslandWindow::_enterQuakeMode() SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE); } +void IslandWindow::HideWindow() +{ + ShowWindow(GetHandle(), SW_HIDE); +} + +void IslandWindow::SetMinimizeToTrayBehavior(bool minimizeToTray) noexcept +{ + _minimizeToTray = minimizeToTray; +} + DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DEFINE_EVENT(IslandWindow, WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 7448add4ccf..814d066f760 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -48,6 +48,9 @@ class IslandWindow : bool IsQuakeWindow() const noexcept; void IsQuakeWindow(bool isQuakeWindow) noexcept; + void HideWindow(); + void SetMinimizeToTrayBehavior(bool minimizeToTray) noexcept; + DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); WINRT_CALLBACK(MouseScrolled, winrt::delegate); @@ -119,6 +122,8 @@ class IslandWindow : void _summonWindowRoutineBody(winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior args); + bool _minimizeToTray{ false }; + private: // This minimum width allows for width the tabs fit static constexpr long minimumWidth = 460L; From 57c2117c0b686515bdf95c92ade813d5815e3412 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 10:30:23 -0700 Subject: [PATCH 24/57] creating enum for menu item action --- src/cascadia/WindowsTerminal/AppHost.cpp | 75 +++++++++++++------ src/cascadia/WindowsTerminal/AppHost.h | 1 + src/cascadia/WindowsTerminal/BaseWindow.h | 3 - .../WindowsTerminal/WindowsTerminal.vcxproj | 1 + src/cascadia/WindowsTerminal/icon.cpp | 12 +-- src/cascadia/WindowsTerminal/icon.h | 2 +- 6 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 19390be7a11..c0c9075b720 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -10,6 +10,9 @@ #include "resource.h" #include "VirtualDesktopUtils.h" #include "icon.h" +#include "TrayIconData.h" + +#include using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Composition; @@ -63,6 +66,8 @@ AppHost::AppHost() noexcept : // Update our own internal state tracking if we're in quake mode or not. _IsQuakeWindowChanged(nullptr, nullptr); + _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); + // Tell the window to callback to us when it's about to handle a WM_CREATE auto pfn = std::bind(&AppHost::_HandleCreateWindow, this, @@ -991,7 +996,7 @@ void AppHost::_UpdateTrayIcon() nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; - nid.hIcon = static_cast(GetActiveAppIconHandle(ICON_SMALL)); + nid.hIcon = static_cast(GetActiveAppIconHandle(true)); StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &nid); @@ -1047,37 +1052,61 @@ HMENU AppHost::_CreateTrayContextMenu() mi.dwStyle = MNS_NOTIFYBYPOS; SetMenuInfo(hmenu, &mi); - // TODO: Other useful options may include: - // - Summon All - // - Summon MRU or Monarch - // - Though that's technically already available with a left click - // but may be a reasonable request to also put it explicitly in the - // context menu - // - Quit All - // It also might be nice to add options to changing the left click - // behavior (e.g. mru window or all windows or quake window) - - // Get all peasants' window names - for (const auto [id, name] : _windowManager.GetPeasantNames()) + // Focus Current Terminal Window + AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, L"Focus Terminal"); + AppendMenu(hmenu, MF_SEPARATOR, 0, L""); + + // Submenu for Windows + if (auto windowSubmenu = _CreateWindowSubmenu()) { - // Technically, the id doesn't matter here since we'll - // be referring to this menu item through its position - // in the context menu. - AppendMenu(hmenu, MF_STRING, (UINT_PTR)id, name.c_str()); + AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows"); + AppendMenu(hmenu, MF_SEPARATOR, 0, L""); } + + AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::QuitAll, L"Close All Windows"); } return hmenu; } +HMENU AppHost::_CreateWindowSubmenu() +{ + if (auto hmenu = CreatePopupMenu()) + { + for (const auto [id, name] : _windowManager.GetPeasantNames()) + { + AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::SummonWindow, name.c_str()); + } + return hmenu; + } + return nullptr; +} + void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { - // Grab the window name associated to the given context menu item position. - WCHAR name[255]; - GetMenuString(menu, menuItemIndex, name, 255, MF_BYPOSITION); + auto action = (TrayMenuItemAction)GetMenuItemID(menu, menuItemIndex); + switch (action) + { + case TrayMenuItemAction::FocusTerminal: + { + _windowManager.SummonWindow({}); + break; + } + case TrayMenuItemAction::SummonWindow: + { + WCHAR name[255]; + GetMenuString(menu, menuItemIndex, name, 255, MF_BYPOSITION); - Remoting::SummonWindowSelectionArgs args{ name }; - args.SummonBehavior().ToggleVisibility(false); - _windowManager.SummonWindow(args); + Remoting::SummonWindowSelectionArgs args{ name }; + args.SummonBehavior().ToggleVisibility(false); + _windowManager.SummonWindow(args); + break; + } + case TrayMenuItemAction::QuitAll: + { + break; + } + + } } void AppHost::_DestroyTrayIcon() diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index fc4dc2c489d..e73dfc99496 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -93,6 +93,7 @@ class AppHost void _HandleTrayIconPressed(); void _ShowTrayContextMenu(const til::point coord); HMENU _CreateTrayContextMenu(); + HMENU _CreateWindowSubmenu(); void _TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex); void _DestroyTrayIcon(); diff --git a/src/cascadia/WindowsTerminal/BaseWindow.h b/src/cascadia/WindowsTerminal/BaseWindow.h index fd6528f93ae..d1a8b86d775 100644 --- a/src/cascadia/WindowsTerminal/BaseWindow.h +++ b/src/cascadia/WindowsTerminal/BaseWindow.h @@ -8,9 +8,6 @@ #include -#include -UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources") - template class BaseWindow { diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index b92f8589fd1..c9787d06606 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -46,6 +46,7 @@ + diff --git a/src/cascadia/WindowsTerminal/icon.cpp b/src/cascadia/WindowsTerminal/icon.cpp index 4706894ad43..687644aee32 100644 --- a/src/cascadia/WindowsTerminal/icon.cpp +++ b/src/cascadia/WindowsTerminal/icon.cpp @@ -27,12 +27,14 @@ static int _GetActiveAppIconResource() return iconResource; } -HANDLE GetActiveAppIconHandle(int size) +// There's only two possible sizes - ICON_SMALL and ICON_BIG. +// So, use true for smallIcon if you want small and false for big. +HANDLE GetActiveAppIconHandle(bool smallIcon) { auto iconResource{ MAKEINTRESOURCEW(_GetActiveAppIconResource()) }; - const auto smXIcon = size == ICON_SMALL ? SM_CXSMICON : SM_CXICON; - const auto smYIcon = size == ICON_SMALL ? SM_CYSMICON : SM_CYICON; + const auto smXIcon = smallIcon ? SM_CXSMICON : SM_CXICON; + const auto smYIcon = smallIcon ? SM_CYSMICON : SM_CYICON; // These handles are loaded with LR_SHARED, so they are safe to "leak". HANDLE hIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(smXIcon), GetSystemMetrics(smYIcon), LR_SHARED) }; @@ -43,11 +45,11 @@ HANDLE GetActiveAppIconHandle(int size) void UpdateWindowIconForActiveMetrics(HWND window) { - if (auto smallIcon = GetActiveAppIconHandle(ICON_SMALL)) + if (auto smallIcon = GetActiveAppIconHandle(true)) { SendMessageW(window, WM_SETICON, ICON_SMALL, reinterpret_cast(smallIcon)); } - if (auto largeIcon = GetActiveAppIconHandle(ICON_BIG)) + if (auto largeIcon = GetActiveAppIconHandle(false)) { SendMessageW(window, WM_SETICON, ICON_BIG, reinterpret_cast(largeIcon)); } diff --git a/src/cascadia/WindowsTerminal/icon.h b/src/cascadia/WindowsTerminal/icon.h index ed4fb5587f6..84be4e9c139 100644 --- a/src/cascadia/WindowsTerminal/icon.h +++ b/src/cascadia/WindowsTerminal/icon.h @@ -3,5 +3,5 @@ #pragma once -HANDLE GetActiveAppIconHandle(const int size); +HANDLE GetActiveAppIconHandle(bool smallIcon); void UpdateWindowIconForActiveMetrics(HWND window); From 30e01ba909fddf48f9b0a0dbf39334e314f3b8e4 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 10:40:51 -0700 Subject: [PATCH 25/57] fix focus terminal action --- src/cascadia/WindowsTerminal/AppHost.cpp | 7 +++++-- src/cascadia/WindowsTerminal/TrayIconData.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/cascadia/WindowsTerminal/TrayIconData.h diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index c0c9075b720..15601230dc1 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -965,7 +965,9 @@ void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspec void AppHost::_HandleTrayIconPressed() { // No name in the args means summon the mru window. - _windowManager.SummonWindow({}); + Remoting::SummonWindowSelectionArgs args{}; + args.SummonBehavior().ToggleVisibility(false); + _windowManager.SummonWindow(args); } // Method Description: @@ -1088,7 +1090,8 @@ void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { case TrayMenuItemAction::FocusTerminal: { - _windowManager.SummonWindow({}); + Remoting::SummonWindowSelectionArgs args{}; + args.SummonBehavior().ToggleVisibility(false); break; } case TrayMenuItemAction::SummonWindow: diff --git a/src/cascadia/WindowsTerminal/TrayIconData.h b/src/cascadia/WindowsTerminal/TrayIconData.h new file mode 100644 index 00000000000..145f93adc61 --- /dev/null +++ b/src/cascadia/WindowsTerminal/TrayIconData.h @@ -0,0 +1,10 @@ +#pragma once + +#include "pch.h" + +enum class TrayMenuItemAction +{ + FocusTerminal, + SummonWindow, + QuitAll +}; From 8347e5acf4f0022ea310523d396f60153dae093f Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 14:27:37 -0700 Subject: [PATCH 26/57] moving SummonWindow to use ID --- dep/wil | 2 +- src/cascadia/Remoting/Monarch.cpp | 24 +- src/cascadia/Remoting/Monarch.h | 2 +- src/cascadia/Remoting/Monarch.idl | 1 + src/cascadia/Remoting/Peasant.cpp | 7 +- src/cascadia/Remoting/Peasant.h | 2 +- .../Remoting/SummonWindowSelectionArgs.h | 2 + .../TerminalApp/AppActionHandlers.cpp | 6 +- .../UnitTests_Remoting/RemotingTests.cpp | 338 ++++++------------ src/cascadia/WindowsTerminal/AppHost.cpp | 49 ++- 10 files changed, 173 insertions(+), 260 deletions(-) diff --git a/dep/wil b/dep/wil index 2e225973d6c..3c00e7f1d8c 160000 --- a/dep/wil +++ b/dep/wil @@ -1 +1 @@ -Subproject commit 2e225973d6c2ecf17fb4d376ddbeedb6db7dd82f +Subproject commit 3c00e7f1d8cf9930bbb8e5be3ef0df65c84e8928 diff --git a/src/cascadia/Remoting/Monarch.cpp b/src/cascadia/Remoting/Monarch.cpp index be5bbb87a76..926f8ed3260 100644 --- a/src/cascadia/Remoting/Monarch.cpp +++ b/src/cascadia/Remoting/Monarch.cpp @@ -733,19 +733,27 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation { args.FoundMatch(false); uint64_t windowId = 0; - // If no name was provided, then just summon the MRU window. - if (searchedForName.empty()) + if (!args.WindowID()) { - // Use the value of the `desktop` arg to determine if we should - // limit to the current desktop (desktop:onCurrent) or not - // (desktop:any or desktop:toCurrent) - windowId = _getMostRecentPeasantID(args.OnCurrentDesktop(), false); + // If no name was provided, then just summon the MRU window. + if (searchedForName.empty()) + { + // Use the value of the `desktop` arg to determine if we should + // limit to the current desktop (desktop:onCurrent) or not + // (desktop:any or desktop:toCurrent) + windowId = _getMostRecentPeasantID(args.OnCurrentDesktop(), false); + } + else + { + // Try to find a peasant that currently has this name + windowId = _lookupPeasantIdForName(searchedForName); + } } else { - // Try to find a peasant that currently has this name - windowId = _lookupPeasantIdForName(searchedForName); + windowId = args.WindowID(); } + if (auto targetPeasant{ _getPeasant(windowId) }) { targetPeasant.Summon(args.SummonBehavior()); diff --git a/src/cascadia/Remoting/Monarch.h b/src/cascadia/Remoting/Monarch.h index a77cebb90db..088913ee02e 100644 --- a/src/cascadia/Remoting/Monarch.h +++ b/src/cascadia/Remoting/Monarch.h @@ -41,6 +41,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation struct Monarch : public MonarchT { Monarch(); + Monarch(const uint64_t testPID); ~Monarch(); uint64_t GetPID(); @@ -56,7 +57,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); private: - Monarch(const uint64_t testPID); uint64_t _ourPID; uint64_t _nextPeasantID{ 1 }; diff --git a/src/cascadia/Remoting/Monarch.idl b/src/cascadia/Remoting/Monarch.idl index 31e3bc8b3bb..b023b7765be 100644 --- a/src/cascadia/Remoting/Monarch.idl +++ b/src/cascadia/Remoting/Monarch.idl @@ -28,6 +28,7 @@ namespace Microsoft.Terminal.Remoting Boolean FoundMatch; SummonWindowBehavior SummonBehavior; + UInt64 WindowID; } diff --git a/src/cascadia/Remoting/Peasant.cpp b/src/cascadia/Remoting/Peasant.cpp index c8cd0a93f89..fb00bc8d757 100644 --- a/src/cascadia/Remoting/Peasant.cpp +++ b/src/cascadia/Remoting/Peasant.cpp @@ -32,13 +32,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void Peasant::AssignID(uint64_t id) { _id = id; - - // Provide a default name if we're currently unnamed. - if (_WindowName.empty()) - { - _WindowName = fmt::format(L"{} {}", RS_(L"Window"), _id); - } } + uint64_t Peasant::GetID() { return _id; diff --git a/src/cascadia/Remoting/Peasant.h b/src/cascadia/Remoting/Peasant.h index 7b5b44e8138..54e04601b56 100644 --- a/src/cascadia/Remoting/Peasant.h +++ b/src/cascadia/Remoting/Peasant.h @@ -16,6 +16,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation struct Peasant : public PeasantT { Peasant(); + Peasant(const uint64_t testPID); void AssignID(uint64_t id); uint64_t GetID(); @@ -42,7 +43,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior); private: - Peasant(const uint64_t testPID); uint64_t _ourPID; uint64_t _id{ 0 }; diff --git a/src/cascadia/Remoting/SummonWindowSelectionArgs.h b/src/cascadia/Remoting/SummonWindowSelectionArgs.h index 2696925efc1..8441e4ac814 100644 --- a/src/cascadia/Remoting/SummonWindowSelectionArgs.h +++ b/src/cascadia/Remoting/SummonWindowSelectionArgs.h @@ -34,6 +34,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation WINRT_PROPERTY(bool, FoundMatch, false); WINRT_PROPERTY(bool, OnCurrentDesktop, false); WINRT_PROPERTY(SummonWindowBehavior, SummonBehavior); + + WINRT_PROPERTY(uint64_t, WindowID); }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 8db545379cf..4ee38241432 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -819,7 +819,11 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, const ActionEventArgs& args) { - _MinimizeToTrayRequestedHandlers(*this, nullptr); + if (_settings.GlobalSettings().MinimizeToTray() || _settings.GlobalSettings().AlwaysShowTrayIcon()) + { + _MinimizeToTrayRequestedHandlers(*this, nullptr); + } + args.Handled(true); } } diff --git a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp index bf05e36e430..d8b79cbc712 100644 --- a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp +++ b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp @@ -174,8 +174,7 @@ namespace RemotingUnitTests return; } - com_ptr tombstone; - tombstone.attach(new DeadPeasant()); + auto tombstone = winrt::make_self(); m->_peasants[peasantID] = *tombstone; } @@ -216,7 +215,8 @@ namespace RemotingUnitTests Log::Comment(L"That's what we need for window process management, but for tests, it'll be more useful to fake the PIDs."); auto expectedFakePID = 1234u; - MAKE_MONARCH(m2, expectedFakePID); + //MAKE_MONARCH(m2, expectedFakePID); + auto m2 = winrt::make_self(expectedFakePID); VERIFY_IS_NOT_NULL(m2); VERIFY_ARE_EQUAL(expectedFakePID, @@ -235,7 +235,8 @@ namespace RemotingUnitTests Log::Comment(L"That's what we need for window process management, but for tests, it'll be more useful to fake the PIDs."); auto expectedFakePID = 2345u; - MAKE_PEASANT(p2, expectedFakePID); + //MAKE_PEASANT(p2, expectedFakePID); + auto p2 = winrt::make_self(expectedFakePID); VERIFY_IS_NOT_NULL(p2); VERIFY_ARE_EQUAL(expectedFakePID, @@ -257,7 +258,7 @@ namespace RemotingUnitTests com_ptr p2; VERIFY_IS_NULL(p2); - p2.attach(new Remoting::implementation::Peasant(expectedFakePID)); + p2 = winrt::make_self(expectedFakePID); VERIFY_IS_NOT_NULL(p2); VERIFY_ARE_EQUAL(expectedFakePID, @@ -271,14 +272,9 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); - - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); - - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto m0 = winrt::make_self(monarch0PID); + auto p1 = winrt::make_self(peasant1PID); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -300,14 +296,9 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); - - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); - - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto m0 = winrt::make_self(monarch0PID); + auto p1 = winrt::make_self(peasant1PID); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -338,17 +329,10 @@ namespace RemotingUnitTests const auto peasant2PID = 34567u; const auto monarch3PID = 45678u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); - - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); - - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); - - com_ptr m3; - m3.attach(new Remoting::implementation::Monarch(monarch3PID)); + auto m0 = winrt::make_self(monarch0PID); + auto p1 = winrt::make_self(peasant1PID); + auto p2 = winrt::make_self(peasant2PID); + auto m3 = winrt::make_self(monarch3PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -377,14 +361,9 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); - - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); - - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto m0 = winrt::make_self(monarch0PID); + auto p1 = winrt::make_self(peasant1PID); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -420,8 +399,7 @@ namespace RemotingUnitTests const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); @@ -434,8 +412,7 @@ namespace RemotingUnitTests Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); @@ -450,15 +427,13 @@ namespace RemotingUnitTests Log::Comment(L"Test proposing a commandline for a window that currently exists"); const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); @@ -480,15 +455,13 @@ namespace RemotingUnitTests Log::Comment(L"Test proposing a commandline for an invalid window ID, like -1"); const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); @@ -514,15 +487,13 @@ namespace RemotingUnitTests Log::Comment(L"Test proposing a commandline for the current window (ID=0)"); const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); p1->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) { @@ -552,8 +523,7 @@ namespace RemotingUnitTests Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); p2->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) { @@ -594,15 +564,13 @@ namespace RemotingUnitTests Log::Comment(L"Test proposing a commandline for an ID that doesn't have a current peasant"); const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); @@ -631,15 +599,13 @@ namespace RemotingUnitTests Log::Comment(L"Test proposing a commandline for a peasant that previously died"); const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); p1->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& /*cmdlineArgs*/) { @@ -649,8 +615,7 @@ namespace RemotingUnitTests Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); p2->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) { @@ -702,22 +667,19 @@ namespace RemotingUnitTests const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") }; const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); @@ -759,22 +721,19 @@ namespace RemotingUnitTests const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") }; const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); @@ -798,8 +757,7 @@ namespace RemotingUnitTests Log::Comment(L"Add a third peasant"); const auto peasant3PID = 45678u; - com_ptr p3; - p3.attach(new Remoting::implementation::Peasant(peasant3PID)); + auto p3 = winrt::make_self(peasant3PID); VERIFY_IS_NOT_NULL(p3); m0->AddPeasant(*p3); { @@ -836,22 +794,19 @@ namespace RemotingUnitTests const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") }; const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); @@ -875,8 +830,7 @@ namespace RemotingUnitTests Log::Comment(L"Add a third peasant"); const auto peasant3PID = 45678u; - com_ptr p3; - p3.attach(new Remoting::implementation::Peasant(peasant3PID)); + auto p3 = winrt::make_self(peasant3PID); VERIFY_IS_NOT_NULL(p3); m0->AddPeasant(*p3); { @@ -937,22 +891,19 @@ namespace RemotingUnitTests const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") }; const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); @@ -974,8 +925,7 @@ namespace RemotingUnitTests Log::Comment(L"Add a third peasant"); const auto peasant3PID = 45678u; - com_ptr p3; - p3.attach(new Remoting::implementation::Peasant(peasant3PID)); + auto p3 = winrt::make_self(peasant3PID); VERIFY_IS_NOT_NULL(p3); m0->AddPeasant(*p3); { @@ -1006,22 +956,19 @@ namespace RemotingUnitTests const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") }; const auto monarch0PID = 12345u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper); Log::Comment(L"Add a peasant"); const auto peasant1PID = 23456u; - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); VERIFY_IS_NOT_NULL(p1); m0->AddPeasant(*p1); Log::Comment(L"Add a second peasant"); const auto peasant2PID = 34567u; - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(p2); m0->AddPeasant(*p2); @@ -1066,14 +1013,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1165,14 +1109,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1214,17 +1155,13 @@ namespace RemotingUnitTests const auto peasant2PID = 34567u; const auto monarch3PID = 45678u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); - com_ptr m3; - m3.attach(new Remoting::implementation::Monarch(monarch3PID)); + auto m3 = winrt::make_self(monarch3PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1271,14 +1208,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1323,14 +1257,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1377,14 +1308,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1437,16 +1365,13 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); VERIFY_IS_NOT_NULL(m0); m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowByNameHelper); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1515,14 +1440,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1561,14 +1483,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1605,14 +1524,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1659,14 +1575,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1746,14 +1659,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1816,14 +1726,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1892,14 +1799,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -1992,17 +1896,13 @@ namespace RemotingUnitTests constexpr auto peasant2PID = 34567u; constexpr auto peasant3PID = 45678u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); - com_ptr p3; - p3.attach(new Remoting::implementation::Peasant(peasant3PID)); + auto p3 = winrt::make_self(peasant3PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -2069,8 +1969,7 @@ namespace RemotingUnitTests } Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop"); - winrt::com_ptr manager; - manager.attach(new MockDesktopManager()); + auto manager = winrt::make_self(); m0->_desktopManager = manager.try_as(); auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT { @@ -2255,17 +2154,13 @@ namespace RemotingUnitTests constexpr auto peasant2PID = 34567u; constexpr auto peasant3PID = 45678u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); - com_ptr p3; - p3.attach(new Remoting::implementation::Peasant(peasant3PID)); + auto p3 = winrt::make_self(peasant3PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -2332,8 +2227,7 @@ namespace RemotingUnitTests } Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop"); - winrt::com_ptr manager; - manager.attach(new MockDesktopManager()); +auto manager = winrt::make_self(); m0->_desktopManager = manager.try_as(); auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT { @@ -2408,17 +2302,13 @@ namespace RemotingUnitTests constexpr auto peasant2PID = 34567u; constexpr auto peasant3PID = 45678u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); - com_ptr p3; - p3.attach(new Remoting::implementation::Peasant(peasant3PID)); + auto p3 = winrt::make_self(peasant3PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); @@ -2485,8 +2375,7 @@ namespace RemotingUnitTests } Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop"); - winrt::com_ptr manager; - manager.attach(new MockDesktopManager()); + auto manager = winrt::make_self(); m0->_desktopManager = manager.try_as(); auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT { @@ -2541,14 +2430,11 @@ namespace RemotingUnitTests const auto peasant1PID = 23456u; const auto peasant2PID = 34567u; - com_ptr m0; - m0.attach(new Remoting::implementation::Monarch(monarch0PID)); + auto m0 = winrt::make_self(monarch0PID); - com_ptr p1; - p1.attach(new Remoting::implementation::Peasant(peasant1PID)); + auto p1 = winrt::make_self(peasant1PID); - com_ptr p2; - p2.attach(new Remoting::implementation::Peasant(peasant2PID)); + auto p2 = winrt::make_self(peasant2PID); VERIFY_IS_NOT_NULL(m0); VERIFY_IS_NOT_NULL(p1); diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 1da7fdd1c48..e4e48751d66 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1052,8 +1052,9 @@ HMENU AppHost::_CreateTrayContextMenu() { MENUINFO mi{}; mi.cbSize = sizeof(MENUINFO); - mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS; + mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS | MIM_MENUDATA; mi.dwStyle = MNS_NOTIFYBYPOS; + mi.dwMenuData = NULL; SetMenuInfo(hmenu, &mi); // Focus Current Terminal Window @@ -1063,6 +1064,13 @@ HMENU AppHost::_CreateTrayContextMenu() // Submenu for Windows if (auto windowSubmenu = _CreateWindowSubmenu()) { + MENUINFO smi{}; + smi.cbSize = sizeof(MENUINFO); + smi.fMask = MIM_MENUDATA; + smi.dwStyle = MNS_NOTIFYBYPOS; + smi.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; + SetMenuInfo(windowSubmenu, &smi); + AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows"); AppendMenu(hmenu, MF_SEPARATOR, 0, L""); } @@ -1078,7 +1086,13 @@ HMENU AppHost::_CreateWindowSubmenu() { for (const auto [id, name] : _windowManager.GetPeasantNames()) { - AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::SummonWindow, name.c_str()); + winrt::hstring displayText = name; + if (name.empty()) + { + displayText = fmt::format(L"Window ID {} - ", id); + } + + AppendMenu(hmenu, MF_STRING, id, displayText.c_str()); } return hmenu; } @@ -1087,6 +1101,23 @@ HMENU AppHost::_CreateWindowSubmenu() void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { + // Let's find out which menu/submenu we're lookin at. + MENUINFO mi{}; + mi.cbSize = sizeof(MENUINFO); + mi.fMask = MIM_MENUDATA; + GetMenuInfo(menu, &mi); + + if (mi.dwMenuData) + { + if ((TrayMenuItemAction)mi.dwMenuData == TrayMenuItemAction::SummonWindow) + { + Remoting::SummonWindowSelectionArgs args{}; + args.WindowID(GetMenuItemID(menu, menuItemIndex)); + args.SummonBehavior().ToggleVisibility(false); + _windowManager.SummonWindow(args); + } + } + auto action = (TrayMenuItemAction)GetMenuItemID(menu, menuItemIndex); switch (action) { @@ -1094,23 +1125,9 @@ void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { Remoting::SummonWindowSelectionArgs args{}; args.SummonBehavior().ToggleVisibility(false); - break; - } - case TrayMenuItemAction::SummonWindow: - { - WCHAR name[255]; - GetMenuString(menu, menuItemIndex, name, 255, MF_BYPOSITION); - - Remoting::SummonWindowSelectionArgs args{ name }; - args.SummonBehavior().ToggleVisibility(false); _windowManager.SummonWindow(args); break; } - case TrayMenuItemAction::QuitAll: - { - break; - } - } } From 63f8d6be7201c46f24d11f9980d8644a093acf11 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 14:43:01 -0700 Subject: [PATCH 27/57] cleanup --- src/cascadia/WindowsTerminal/AppHost.cpp | 7 ++----- src/cascadia/WindowsTerminal/TrayIconData.h | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index e4e48751d66..91a44758721 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1058,7 +1058,7 @@ HMENU AppHost::_CreateTrayContextMenu() SetMenuInfo(hmenu, &mi); // Focus Current Terminal Window - AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, L"Focus Terminal"); + AppendMenu(hmenu, MF_STRING, (UINT)TrayMenuItemAction::FocusTerminal, L"Focus Terminal"); AppendMenu(hmenu, MF_SEPARATOR, 0, L""); // Submenu for Windows @@ -1068,14 +1068,11 @@ HMENU AppHost::_CreateTrayContextMenu() smi.cbSize = sizeof(MENUINFO); smi.fMask = MIM_MENUDATA; smi.dwStyle = MNS_NOTIFYBYPOS; - smi.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; + smi.dwMenuData = (UINT)TrayMenuItemAction::SummonWindow; SetMenuInfo(windowSubmenu, &smi); AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows"); - AppendMenu(hmenu, MF_SEPARATOR, 0, L""); } - - AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::QuitAll, L"Close All Windows"); } return hmenu; } diff --git a/src/cascadia/WindowsTerminal/TrayIconData.h b/src/cascadia/WindowsTerminal/TrayIconData.h index 145f93adc61..3d73d8e0f07 100644 --- a/src/cascadia/WindowsTerminal/TrayIconData.h +++ b/src/cascadia/WindowsTerminal/TrayIconData.h @@ -5,6 +5,5 @@ enum class TrayMenuItemAction { FocusTerminal, - SummonWindow, - QuitAll + SummonWindow }; From be222d276902cc3cdfde7bb2ba92d9ff0d2d9b6e Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 14:46:20 -0700 Subject: [PATCH 28/57] removing unnecessaries --- src/cascadia/Remoting/Resources/en-US/Resources.resw | 5 +---- .../TerminalSettingsModel/Resources/en-US/Resources.resw | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/cascadia/Remoting/Resources/en-US/Resources.resw b/src/cascadia/Remoting/Resources/en-US/Resources.resw index a97f00087b0..4f24d55cd6b 100644 --- a/src/cascadia/Remoting/Resources/en-US/Resources.resw +++ b/src/cascadia/Remoting/Resources/en-US/Resources.resw @@ -117,7 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Window - - + \ No newline at end of file diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index 0c5d2ca6cd3..c85167ef33b 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -413,7 +413,4 @@ Windows Console Host Name describing the usage of the classic windows console as the terminal UI. (`conhost.exe`) - - Minimize window to tray - From f7cf496eea0f258a2c65f62cf02b290fcda96612 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 14:59:30 -0700 Subject: [PATCH 29/57] formatting --- src/cascadia/Remoting/Resources/en-US/Resources.resw | 2 +- src/cascadia/UnitTests_Remoting/RemotingTests.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/Remoting/Resources/en-US/Resources.resw b/src/cascadia/Remoting/Resources/en-US/Resources.resw index 4f24d55cd6b..f4af46df557 100644 --- a/src/cascadia/Remoting/Resources/en-US/Resources.resw +++ b/src/cascadia/Remoting/Resources/en-US/Resources.resw @@ -117,4 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - \ No newline at end of file + diff --git a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp index d8b79cbc712..54d732f1513 100644 --- a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp +++ b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp @@ -2227,7 +2227,7 @@ namespace RemotingUnitTests } Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop"); -auto manager = winrt::make_self(); + auto manager = winrt::make_self(); m0->_desktopManager = manager.try_as(); auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT { From 178a4b4ec1f9be660f4ccd4497e8ed4d3801c31c Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 15:00:32 -0700 Subject: [PATCH 30/57] please let this work --- dep/wil | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dep/wil b/dep/wil index 3c00e7f1d8c..2e225973d6c 160000 --- a/dep/wil +++ b/dep/wil @@ -1 +1 @@ -Subproject commit 3c00e7f1d8cf9930bbb8e5be3ef0df65c84e8928 +Subproject commit 2e225973d6c2ecf17fb4d376ddbeedb6db7dd82f From 49d8d3715e5caea440f544d8f4de5c4ca8c127f5 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 15:08:28 -0700 Subject: [PATCH 31/57] just let me be wrong --- .github/actions/spelling/allow/apis.txt | 1 + src/cascadia/WindowsTerminal/AppHost.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index 13a9ac4d7fe..3560e6a0838 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -78,6 +78,7 @@ localtime lround LSHIFT MENUCOMMAND +MENUDATA MENUINFO msappx MULTIPLEUSE diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 91a44758721..30dd6918a4c 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1064,12 +1064,12 @@ HMENU AppHost::_CreateTrayContextMenu() // Submenu for Windows if (auto windowSubmenu = _CreateWindowSubmenu()) { - MENUINFO smi{}; - smi.cbSize = sizeof(MENUINFO); - smi.fMask = MIM_MENUDATA; - smi.dwStyle = MNS_NOTIFYBYPOS; - smi.dwMenuData = (UINT)TrayMenuItemAction::SummonWindow; - SetMenuInfo(windowSubmenu, &smi); + MENUINFO submenuInfo{}; + submenuInfo.cbSize = sizeof(MENUINFO); + submenuInfo.fMask = MIM_MENUDATA; + submenuInfo.dwStyle = MNS_NOTIFYBYPOS; + submenuInfo.dwMenuData = (UINT)TrayMenuItemAction::SummonWindow; + SetMenuInfo(windowSubmenu, &submenuInfo); AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows"); } @@ -1098,7 +1098,7 @@ HMENU AppHost::_CreateWindowSubmenu() void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { - // Let's find out which menu/submenu we're lookin at. + // Let's find out which menu/submenu we're looking at. MENUINFO mi{}; mi.cbSize = sizeof(MENUINFO); mi.fMask = MIM_MENUDATA; From c70b11acb809fb8fdc3211a6a81fac281fa37bee Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 15:28:06 -0700 Subject: [PATCH 32/57] different casts --- src/cascadia/WindowsTerminal/AppHost.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 30dd6918a4c..01ac68057ab 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1058,7 +1058,7 @@ HMENU AppHost::_CreateTrayContextMenu() SetMenuInfo(hmenu, &mi); // Focus Current Terminal Window - AppendMenu(hmenu, MF_STRING, (UINT)TrayMenuItemAction::FocusTerminal, L"Focus Terminal"); + AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, L"Focus Terminal"); AppendMenu(hmenu, MF_SEPARATOR, 0, L""); // Submenu for Windows @@ -1068,7 +1068,7 @@ HMENU AppHost::_CreateTrayContextMenu() submenuInfo.cbSize = sizeof(MENUINFO); submenuInfo.fMask = MIM_MENUDATA; submenuInfo.dwStyle = MNS_NOTIFYBYPOS; - submenuInfo.dwMenuData = (UINT)TrayMenuItemAction::SummonWindow; + submenuInfo.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; SetMenuInfo(windowSubmenu, &submenuInfo); AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows"); From 5b10d2ee4dfcaa3959ebf71badd8e207d46bcf5a Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 16 Jun 2021 16:31:06 -0700 Subject: [PATCH 33/57] ezilacol --- .../TerminalApp/Resources/en-US/Resources.resw | 14 +++++++++++++- .../Resources/en-US/Resources.resw | 5 ++++- src/cascadia/WindowsTerminal/AppHost.cpp | 10 ++++++---- .../WindowsTerminal/WindowsTerminal.vcxproj | 5 +++++ src/cascadia/WindowsTerminal/main.cpp | 3 +++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 2e35662e354..5a9d03fc28c 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -637,4 +637,16 @@ Command Palette - \ No newline at end of file + + Windows Terminal + + + Focus Terminal + + + unnamed window + + + Windows + + diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index c85167ef33b..e703c6f5936 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -413,4 +413,7 @@ Windows Console Host Name describing the usage of the classic windows console as the terminal UI. (`conhost.exe`) - + + Minimize current window to tray + + \ No newline at end of file diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 01ac68057ab..e93167d78a2 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1001,7 +1001,7 @@ void AppHost::_UpdateTrayIcon() nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; nid.hIcon = static_cast(GetActiveAppIconHandle(true)); - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal"); + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), RS_(L"AppName").c_str()); nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &nid); @@ -1058,7 +1058,7 @@ HMENU AppHost::_CreateTrayContextMenu() SetMenuInfo(hmenu, &mi); // Focus Current Terminal Window - AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, L"Focus Terminal"); + AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, RS_(L"TrayIconFocusTerminal").c_str()); AppendMenu(hmenu, MF_SEPARATOR, 0, L""); // Submenu for Windows @@ -1071,7 +1071,7 @@ HMENU AppHost::_CreateTrayContextMenu() submenuInfo.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; SetMenuInfo(windowSubmenu, &submenuInfo); - AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows"); + AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, RS_(L"TrayIconWindowSubmenu").c_str()); } } return hmenu; @@ -1081,12 +1081,14 @@ HMENU AppHost::_CreateWindowSubmenu() { if (auto hmenu = CreatePopupMenu()) { + auto locWindow = RS_(L"WindowIdLabel"); + auto locUnnamed = RS_(L"TrayIconUnnamedWindow"); for (const auto [id, name] : _windowManager.GetPeasantNames()) { winrt::hstring displayText = name; if (name.empty()) { - displayText = fmt::format(L"Window ID {} - ", id); + displayText = fmt::format(L"{} {} - <{}>", locWindow, id, locUnnamed); } AppendMenu(hmenu, MF_STRING, id, displayText.c_str()); diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index c9787d06606..2104e09bcb4 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -82,6 +82,11 @@ + + + {CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE} + false + - + diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index f857c1f989c..9b52e990b6a 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -12,6 +12,7 @@ #include "icon.h" #include "TrayIconData.h" +#include #include using namespace winrt::Windows::UI; @@ -86,7 +87,6 @@ AppHost::AppHost() noexcept : _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); _window->NotifyShowTrayContextMenu({ this, &AppHost::_ShowTrayContextMenu }); _window->NotifyTrayMenuItemSelected({ this, &AppHost::_TrayMenuItemSelected }); - _window->NotifyCreateTrayIcon({ this, &AppHost::_UpdateTrayIcon }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -652,7 +652,9 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { + _window->NotifyCreateTrayIcon({ this, &AppHost::_UpdateTrayIcon }); _UpdateTrayIcon(); + _setupGlobalHotkeys(); // The monarch is just going to be THE listener for inbound connections. @@ -1017,8 +1019,15 @@ void AppHost::_UpdateTrayIcon() } else if (_trayIconData) { - // We have a tray icon existing, but the now the new settings - // are telling us we don't want you so poof. + // We currently have a tray icon, but after a settings change + // we shouldn't have one. In this case, we'll need to destroy our + // tray icon and show any hidden windows. + // For the sake of simplicity in this rare case, let's just summon + // all the windows. + if (_windowManager.IsMonarch()) + { + _windowManager.SummonAllWindows(); + } _DestroyTrayIcon(); } } @@ -1052,7 +1061,7 @@ void AppHost::_ShowTrayContextMenu(const til::point coord) uFlags |= TPM_LEFTALIGN; } - TrackPopupMenuEx(hmenu, uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL); + TrackPopupMenuEx(hmenu, uFlags, gsl::narrow(coord.x()), gsl::narrow(coord.y()), _window->GetHandle(), NULL); } } @@ -1075,7 +1084,7 @@ HMENU AppHost::_CreateTrayContextMenu() SetMenuInfo(hmenu, &mi); // Focus Current Terminal Window - AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, RS_(L"TrayIconFocusTerminal").c_str()); + AppendMenu(hmenu, MF_STRING, gsl::narrow(TrayMenuItemAction::FocusTerminal), RS_(L"TrayIconFocusTerminal").c_str()); AppendMenu(hmenu, MF_SEPARATOR, 0, L""); // Submenu for Windows @@ -1085,10 +1094,10 @@ HMENU AppHost::_CreateTrayContextMenu() submenuInfo.cbSize = sizeof(MENUINFO); submenuInfo.fMask = MIM_MENUDATA; submenuInfo.dwStyle = MNS_NOTIFYBYPOS; - submenuInfo.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; + submenuInfo.dwMenuData = gsl::narrow(TrayMenuItemAction::SummonWindow); SetMenuInfo(windowSubmenu, &submenuInfo); - AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, RS_(L"TrayIconWindowSubmenu").c_str()); + AppendMenu(hmenu, MF_POPUP, reinterpret_cast(windowSubmenu), RS_(L"TrayIconWindowSubmenu").c_str()); } } return hmenu; @@ -1105,8 +1114,8 @@ HMENU AppHost::_CreateWindowSubmenu() { if (auto hmenu = CreatePopupMenu()) { - auto locWindow = RS_(L"WindowIdLabel"); - auto locUnnamed = RS_(L"UnnamedWindowName"); + const auto locWindow = RS_(L"WindowIdLabel"); + const auto locUnnamed = RS_(L"UnnamedWindowName"); for (const auto [id, name] : _windowManager.GetPeasantNames()) { winrt::hstring displayText = name; @@ -1115,7 +1124,7 @@ HMENU AppHost::_CreateWindowSubmenu() displayText = fmt::format(L"{} {} - <{}>", locWindow, id, locUnnamed); } - AppendMenu(hmenu, MF_STRING, (UINT_PTR)id, displayText.c_str()); + AppendMenu(hmenu, MF_STRING, gsl::narrow(id), displayText.c_str()); } return hmenu; } @@ -1132,15 +1141,14 @@ HMENU AppHost::_CreateWindowSubmenu() // - void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { - // Let's find out which menu/submenu we're looking at. + // Check the menu's data for a specific action. MENUINFO mi{}; mi.cbSize = sizeof(MENUINFO); mi.fMask = MIM_MENUDATA; GetMenuInfo(menu, &mi); - if (mi.dwMenuData) { - if ((TrayMenuItemAction)mi.dwMenuData == TrayMenuItemAction::SummonWindow) + if (gsl::narrow(mi.dwMenuData) == TrayMenuItemAction::SummonWindow) { Remoting::SummonWindowSelectionArgs args{}; args.WindowID(GetMenuItemID(menu, menuItemIndex)); @@ -1149,7 +1157,8 @@ void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) } } - auto action = (TrayMenuItemAction)GetMenuItemID(menu, menuItemIndex); + // Now check the menu item itself for an action. + const auto action = gsl::narrow(GetMenuItemID(menu, menuItemIndex)); switch (action) { case TrayMenuItemAction::FocusTerminal: diff --git a/src/cascadia/WindowsTerminal/BaseWindow.h b/src/cascadia/WindowsTerminal/BaseWindow.h index d1a8b86d775..3d285ed972c 100644 --- a/src/cascadia/WindowsTerminal/BaseWindow.h +++ b/src/cascadia/WindowsTerminal/BaseWindow.h @@ -5,6 +5,7 @@ // Custom window messages #define CM_UPDATE_TITLE (WM_USER) +#define CM_NOTIFY_FROM_TRAY (WM_APP + 1) #include diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 814d066f760..b50591e477b 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -6,8 +6,6 @@ #include #include "../../cascadia/inc/cppwinrt_utils.h" -#define CM_NOTIFY_FROM_TRAY (WM_APP + 1) - class IslandWindow : public BaseWindow { diff --git a/src/cascadia/WindowsTerminal/TrayIconData.h b/src/cascadia/WindowsTerminal/TrayIconData.h index f0e6d8d77fc..23498e026ca 100644 --- a/src/cascadia/WindowsTerminal/TrayIconData.h +++ b/src/cascadia/WindowsTerminal/TrayIconData.h @@ -1,5 +1,7 @@ -#pragma once +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +#pragma once #include "pch.h" // This enumerates all the possible actions diff --git a/src/cascadia/WindowsTerminal/pch.h b/src/cascadia/WindowsTerminal/pch.h index a8befdf6106..ce71201a4b1 100644 --- a/src/cascadia/WindowsTerminal/pch.h +++ b/src/cascadia/WindowsTerminal/pch.h @@ -64,6 +64,7 @@ Module Name: #include #include #include +#include #include #include From 513145736373f95a102109ca5354748e6bfa0730 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 24 Jun 2021 14:24:53 -0700 Subject: [PATCH 38/57] in its own little room --- .../WinRTUtils/inc/ScopedResourceLoader.h | 17 ++ src/cascadia/WindowsTerminal/AppHost.cpp | 246 +++--------------- src/cascadia/WindowsTerminal/AppHost.h | 8 + src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 +- src/cascadia/WindowsTerminal/IslandWindow.h | 2 +- src/cascadia/WindowsTerminal/TrayIcon.cpp | 228 ++++++++++++++++ src/cascadia/WindowsTerminal/TrayIcon.h | 38 +++ src/cascadia/WindowsTerminal/TrayIconData.h | 13 - .../WindowsTerminal/WindowsTerminal.vcxproj | 32 +-- 9 files changed, 335 insertions(+), 251 deletions(-) create mode 100644 src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h create mode 100644 src/cascadia/WindowsTerminal/TrayIcon.cpp create mode 100644 src/cascadia/WindowsTerminal/TrayIcon.h delete mode 100644 src/cascadia/WindowsTerminal/TrayIconData.h diff --git a/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h b/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h new file mode 100644 index 00000000000..f7664115e4e --- /dev/null +++ b/src/cascadia/WinRTUtils/inc/ScopedResourceLoader.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +class ScopedResourceLoader +{ +public: + ScopedResourceLoader(const std::wstring_view resourceLocatorBase); + winrt::Windows::ApplicationModel::Resources::Core::ResourceMap GetResourceMap() const noexcept; + winrt::hstring GetLocalizedString(const std::wstring_view resourceName) const; + bool HasResourceWithName(const std::wstring_view resourceName) const; + +private: + winrt::Windows::ApplicationModel::Resources::Core::ResourceMap _resourceMap; + winrt::Windows::ApplicationModel::Resources::Core::ResourceContext _resourceContext; +}; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 9b52e990b6a..63a69860ce2 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -10,7 +10,6 @@ #include "resource.h" #include "VirtualDesktopUtils.h" #include "icon.h" -#include "TrayIconData.h" #include #include @@ -84,9 +83,6 @@ AppHost::AppHost() noexcept : _window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled }); _window->WindowActivated({ this, &AppHost::_WindowActivated }); _window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed }); - _window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed }); - _window->NotifyShowTrayContextMenu({ this, &AppHost::_ShowTrayContextMenu }); - _window->NotifyTrayMenuItemSelected({ this, &AppHost::_TrayMenuItemSelected }); _window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop()); _window->MakeWindow(); @@ -100,7 +96,11 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { // destruction order is important for proper teardown here - _DestroyTrayIcon(); + if (_windowManager.IsMonarch() && _trayIcon) + { + _DestroyTrayIcon(); + } + _window = nullptr; _app.Close(); _app = nullptr; @@ -652,8 +652,7 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { - _window->NotifyCreateTrayIcon({ this, &AppHost::_UpdateTrayIcon }); - _UpdateTrayIcon(); + _CreateTrayIcon(); _setupGlobalHotkeys(); @@ -935,9 +934,23 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta { _setupGlobalHotkeys(); + // If we're monarch, we need to check two particular settings for + // the tray icon - MinimizeToTray and AlwaysShowTrayIcon. If either + // one of them are true, we want to make sure there's a tray icon. + // If both are false, we want to remove our icon from the tray (if we had one). + // When we remove our icon from the tray, we'll also want to re-summon + // any hidden windows. if (_windowManager.IsMonarch()) { - _UpdateTrayIcon(); + if (!_trayIcon && (_logic.GetMinimizeToTray() || _logic.GetAlwaysShowTrayIcon())) + { + _CreateTrayIcon(); + } + else if (_trayIcon && !_logic.GetMinimizeToTray() && !_logic.GetAlwaysShowTrayIcon()) + { + _windowManager.SummonAllWindows(); + _DestroyTrayIcon(); + } } _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); @@ -966,209 +979,22 @@ void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspec _window->HideWindow(); } -void AppHost::_HandleTrayIconPressed() -{ - // No name in the args means summon the mru window. - Remoting::SummonWindowSelectionArgs args{}; - args.SummonBehavior().ToggleVisibility(false); - _windowManager.SummonWindow(args); -} - // Method Description: -// - Creates and adds an icon to the notification tray. -// If an icon already exists, update the HWND associated -// to the icon with this window's HWND. +// - Creates a Tray Icon and hooks up its handlers // Arguments: -// - -// Return Value: // - -void AppHost::_UpdateTrayIcon() -{ - if (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray()) - { - if (!_trayIconData) - { - NOTIFYICONDATA nid{}; - nid.cbSize = sizeof(NOTIFYICONDATA); - - // This HWND will receive the callbacks sent by the tray icon. - nid.hWnd = _window->GetHandle(); - - // App-defined identifier of the icon. The HWND and ID are used - // to identify which icon to operate on when calling Shell_NotifyIcon. - // Multiple icons can be associated with one HWND, but here we're only - // going to be showing one so the ID doesn't really matter. - nid.uID = 1; - - nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; - - nid.hIcon = static_cast(GetActiveAppIconHandle(true)); - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), RS_(L"AppName").c_str()); - nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; - Shell_NotifyIcon(NIM_ADD, &nid); - - // For whatever reason, the NIM_ADD call doesn't seem to set the version - // properly, resulting in us being unable to receive the expected notification - // events. We actually have to make a separate NIM_SETVERSION call for it to - // work properly. - nid.uVersion = NOTIFYICON_VERSION_4; - Shell_NotifyIcon(NIM_SETVERSION, &nid); - - _trayIconData = nid; - } - } - else if (_trayIconData) - { - // We currently have a tray icon, but after a settings change - // we shouldn't have one. In this case, we'll need to destroy our - // tray icon and show any hidden windows. - // For the sake of simplicity in this rare case, let's just summon - // all the windows. - if (_windowManager.IsMonarch()) - { - _windowManager.SummonAllWindows(); - } - _DestroyTrayIcon(); - } -} - -// Method Description: -// - This creates our context menu and displays it at the given -// screen coordinates. -// Arguments: -// - The coordinates where we should be showing the context menu. // Return Value: // - -void AppHost::_ShowTrayContextMenu(const til::point coord) +void AppHost::_CreateTrayIcon() { - if (auto hmenu = _CreateTrayContextMenu()) - { - // We'll need to set our window to the foreground before calling - // TrackPopupMenuEx or else the menu won't dismiss when clicking away. - SetForegroundWindow(_window->GetHandle()); - - // User can select menu items with the left and right buttons. - UINT uFlags = TPM_RIGHTBUTTON; + _trayIcon = std::make_unique(_window->GetHandle()); - // Nonzero if drop-down menus are right-aligned with the corresponding menu-bar item - // 0 if the menus are left-aligned. - if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) - { - uFlags |= TPM_RIGHTALIGN; - } - else - { - uFlags |= TPM_LEFTALIGN; - } - - TrackPopupMenuEx(hmenu, uFlags, gsl::narrow(coord.x()), gsl::narrow(coord.y()), _window->GetHandle(), NULL); - } -} - -// Method Description: -// - This creates the context menu for our tray icon. -// Arguments: -// - -// Return Value: -// - The handle to the newly created context menu. -HMENU AppHost::_CreateTrayContextMenu() -{ - auto hmenu = CreatePopupMenu(); - if (hmenu) - { - MENUINFO mi{}; - mi.cbSize = sizeof(MENUINFO); - mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS | MIM_MENUDATA; - mi.dwStyle = MNS_NOTIFYBYPOS; - mi.dwMenuData = NULL; - SetMenuInfo(hmenu, &mi); - - // Focus Current Terminal Window - AppendMenu(hmenu, MF_STRING, gsl::narrow(TrayMenuItemAction::FocusTerminal), RS_(L"TrayIconFocusTerminal").c_str()); - AppendMenu(hmenu, MF_SEPARATOR, 0, L""); - - // Submenu for Windows - if (auto windowSubmenu = _CreateWindowSubmenu()) - { - MENUINFO submenuInfo{}; - submenuInfo.cbSize = sizeof(MENUINFO); - submenuInfo.fMask = MIM_MENUDATA; - submenuInfo.dwStyle = MNS_NOTIFYBYPOS; - submenuInfo.dwMenuData = gsl::narrow(TrayMenuItemAction::SummonWindow); - SetMenuInfo(windowSubmenu, &submenuInfo); - - AppendMenu(hmenu, MF_POPUP, reinterpret_cast(windowSubmenu), RS_(L"TrayIconWindowSubmenu").c_str()); - } - } - return hmenu; -} - -// Method Description: -// - Create a menu with a menu item for each window available to summon. -// If a window is unnamed, we'll use its ID but still mention that it's unnamed. -// Arguments: -// - -// Return Value: -// - The handle to the newly created window submenu. -HMENU AppHost::_CreateWindowSubmenu() -{ - if (auto hmenu = CreatePopupMenu()) - { - const auto locWindow = RS_(L"WindowIdLabel"); - const auto locUnnamed = RS_(L"UnnamedWindowName"); - for (const auto [id, name] : _windowManager.GetPeasantNames()) - { - winrt::hstring displayText = name; - if (name.empty()) - { - displayText = fmt::format(L"{} {} - <{}>", locWindow, id, locUnnamed); - } - - AppendMenu(hmenu, MF_STRING, gsl::narrow(id), displayText.c_str()); - } - return hmenu; - } - return nullptr; -} - -// Method Description: -// - This is the handler for when one of the menu items are selected within -// the tray icon's context menu. -// Arguments: -// - menu: The handle to the menu that holds the menu item that was selected. -// - menuItemIndex: The index of the menu item within the given menu. -// Return Value: -// - -void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) -{ - // Check the menu's data for a specific action. - MENUINFO mi{}; - mi.cbSize = sizeof(MENUINFO); - mi.fMask = MIM_MENUDATA; - GetMenuInfo(menu, &mi); - if (mi.dwMenuData) - { - if (gsl::narrow(mi.dwMenuData) == TrayMenuItemAction::SummonWindow) - { - Remoting::SummonWindowSelectionArgs args{}; - args.WindowID(GetMenuItemID(menu, menuItemIndex)); - args.SummonBehavior().ToggleVisibility(false); - _windowManager.SummonWindow(args); - } - } - - // Now check the menu item itself for an action. - const auto action = gsl::narrow(GetMenuItemID(menu, menuItemIndex)); - switch (action) - { - case TrayMenuItemAction::FocusTerminal: - { - Remoting::SummonWindowSelectionArgs args{}; - args.SummonBehavior().ToggleVisibility(false); - _windowManager.SummonWindow(args); - break; - } - } + // Hookup the handlers, save the tokens for revoking if settings change. + _ReAddTrayIconToken = _window->NotifyReAddTrayIcon({ this, &AppHost::_CreateTrayIcon }); + _TrayIconPressedToken = _window->NotifyTrayIconPressed([this]() { _trayIcon->HandleTrayIconPressed(); }); + _ShowTrayContextMenuToken = _window->NotifyShowTrayContextMenu([this](til::point coord) { _trayIcon->ShowTrayContextMenu(coord, _windowManager.GetPeasantNames()); }); + _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU menuHandle, UINT menuItemIndex) { _trayIcon->TrayMenuItemSelected(menuHandle, menuItemIndex); }); + _trayIcon->SummonWindowRequested([this](auto& args) { _windowManager.SummonWindow(args); }); } // Method Description: @@ -1179,9 +1005,11 @@ void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) // - void AppHost::_DestroyTrayIcon() { - if (_trayIconData) - { - Shell_NotifyIcon(NIM_DELETE, &_trayIconData.value()); - _trayIconData.reset(); - } + _window->NotifyReAddTrayIcon(_ReAddTrayIconToken); + _window->NotifyTrayIconPressed(_TrayIconPressedToken); + _window->NotifyShowTrayContextMenu(_ShowTrayContextMenuToken); + _window->NotifyTrayMenuItemSelected(_TrayMenuItemSelectedToken); + + _trayIcon->DestroyTrayIcon(); + _trayIcon = nullptr; } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index e73dfc99496..82f858078ba 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -4,6 +4,7 @@ #include "pch.h" #include "NonClientIslandWindow.h" +#include "TrayIcon.h" class AppHost { @@ -98,4 +99,11 @@ class AppHost void _DestroyTrayIcon(); std::optional _trayIconData; + + void _CreateTrayIcon(); + std::unique_ptr _trayIcon; + winrt::event_token _ReAddTrayIconToken; + winrt::event_token _TrayIconPressedToken; + winrt::event_token _ShowTrayContextMenuToken; + winrt::event_token _TrayMenuItemSelectedToken; }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 19dcf0dfff3..e4badeaa856 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -538,7 +538,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize // so that we can re-add our icon to the tray. if (message == WM_TASKBARCREATED) { - _NotifyCreateTrayIconHandlers(); + _NotifyReAddTrayIconHandlers(); return 0; } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index b50591e477b..c962f787e1b 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -57,7 +57,7 @@ class IslandWindow : WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate); WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate); - WINRT_CALLBACK(NotifyCreateTrayIcon, winrt::delegate); + WINRT_CALLBACK(NotifyReAddTrayIcon, winrt::delegate); protected: void ForceResize() diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp new file mode 100644 index 00000000000..6af83b693e7 --- /dev/null +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -0,0 +1,228 @@ +#include "pch.h" +#include "icon.h" +#include "TrayIcon.h" + +#include + +using namespace winrt::Windows::Foundation::Collections; + +TrayIcon::TrayIcon(const HWND owningHwnd) : + _owningHwnd{ owningHwnd } +{ + CreateTrayIcon(); +} + +TrayIcon::~TrayIcon() +{ + DestroyTrayIcon(); +} + +// Method Description: +// - Creates and adds an icon to the notification tray. +// If an icon already exists, update the HWND associated +// to the icon with this window's HWND. +// Arguments: +// - +// Return Value: +// - +void TrayIcon::CreateTrayIcon() +{ + NOTIFYICONDATA nid{}; + nid.cbSize = sizeof(NOTIFYICONDATA); + + // This HWND will receive the callbacks sent by the tray icon. + nid.hWnd = _owningHwnd; + + // App-defined identifier of the icon. The HWND and ID are used + // to identify which icon to operate on when calling Shell_NotifyIcon. + // Multiple icons can be associated with one HWND, but here we're only + // going to be showing one so the ID doesn't really matter. + nid.uID = 1; + + nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; + + nid.hIcon = static_cast(GetActiveAppIconHandle(true)); + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), RS_(L"AppName").c_str()); + nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; + Shell_NotifyIcon(NIM_ADD, &nid); + + // For whatever reason, the NIM_ADD call doesn't seem to set the version + // properly, resulting in us being unable to receive the expected notification + // events. We actually have to make a separate NIM_SETVERSION call for it to + // work properly. + nid.uVersion = NOTIFYICON_VERSION_4; + Shell_NotifyIcon(NIM_SETVERSION, &nid); + + _trayIconData = nid; +} + + +// Method Description: +// - This creates our context menu and displays it at the given +// screen coordinates. +// Arguments: +// - The coordinates where we should be showing the context menu. +// Return Value: +// - +void TrayIcon::ShowTrayContextMenu(const til::point coord, + IMapView peasants) +{ + if (auto hmenu = _CreateTrayContextMenu()) + { + // Submenu for Windows + if (auto windowSubmenu = _CreateWindowSubmenu(peasants)) + { + MENUINFO submenuInfo{}; + submenuInfo.cbSize = sizeof(MENUINFO); + submenuInfo.fMask = MIM_MENUDATA; + submenuInfo.dwStyle = MNS_NOTIFYBYPOS; + submenuInfo.dwMenuData = gsl::narrow(TrayMenuItemAction::SummonWindow); + SetMenuInfo(windowSubmenu, &submenuInfo); + + AppendMenu(hmenu, MF_POPUP, reinterpret_cast(windowSubmenu), RS_(L"TrayIconWindowSubmenu").c_str()); + } + + // We'll need to set our window to the foreground before calling + // TrackPopupMenuEx or else the menu won't dismiss when clicking away. + SetForegroundWindow(_owningHwnd); + + // User can select menu items with the left and right buttons. + UINT uFlags = TPM_RIGHTBUTTON; + + // Nonzero if drop-down menus are right-aligned with the corresponding menu-bar item + // 0 if the menus are left-aligned. + if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) + { + uFlags |= TPM_RIGHTALIGN; + } + else + { + uFlags |= TPM_LEFTALIGN; + } + + TrackPopupMenuEx(hmenu, uFlags, gsl::narrow(coord.x()), gsl::narrow(coord.y()), _owningHwnd, NULL); + } +} + +// Method Description: +// - This creates the context menu for our tray icon. +// Arguments: +// - +// Return Value: +// - The handle to the newly created context menu. +HMENU TrayIcon::_CreateTrayContextMenu() +{ + auto hmenu = CreatePopupMenu(); + if (hmenu) + { + MENUINFO mi{}; + mi.cbSize = sizeof(MENUINFO); + mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS | MIM_MENUDATA; + mi.dwStyle = MNS_NOTIFYBYPOS; + mi.dwMenuData = NULL; + SetMenuInfo(hmenu, &mi); + + // Focus Current Terminal Window + AppendMenu(hmenu, MF_STRING, gsl::narrow(TrayMenuItemAction::FocusTerminal), RS_(L"TrayIconFocusTerminal").c_str()); + AppendMenu(hmenu, MF_SEPARATOR, 0, L""); + } + return hmenu; +} + +// Method Description: +// - Create a menu with a menu item for each window available to summon. +// If a window is unnamed, we'll use its ID but still mention that it's unnamed. +// Arguments: +// - +// Return Value: +// - The handle to the newly created window submenu. +HMENU TrayIcon::_CreateWindowSubmenu(IMapView peasants) +{ + if (auto hmenu = CreatePopupMenu()) + { + const auto locWindow = RS_(L"WindowIdLabel"); + const auto locUnnamed = RS_(L"UnnamedWindowName"); + for (const auto [id, name] : peasants) + { + winrt::hstring displayText = name; + if (name.empty()) + { + displayText = fmt::format(L"{} {} - <{}>", locWindow, id, locUnnamed); + } + + AppendMenu(hmenu, MF_STRING, gsl::narrow(id), displayText.c_str()); + } + return hmenu; + } + return nullptr; +} + +// Method Description: +// - This is the handler for when one of the menu items are selected within +// the tray icon's context menu. +// Arguments: +// - menu: The handle to the menu that holds the menu item that was selected. +// - menuItemIndex: The index of the menu item within the given menu. +// Return Value: +// - +void TrayIcon::TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) +{ + // Check the menu's data for a specific action. + MENUINFO mi{}; + mi.cbSize = sizeof(MENUINFO); + mi.fMask = MIM_MENUDATA; + GetMenuInfo(menu, &mi); + if (mi.dwMenuData) + { + if (gsl::narrow(mi.dwMenuData) == TrayMenuItemAction::SummonWindow) + { + winrt::Microsoft::Terminal::Remoting::SummonWindowSelectionArgs args{}; + args.WindowID(GetMenuItemID(menu, menuItemIndex)); + args.SummonBehavior().ToggleVisibility(false); + _SummonWindowRequestedHandlers(args); + return; + } + } + + // Now check the menu item itself for an action. + const auto action = gsl::narrow(GetMenuItemID(menu, menuItemIndex)); + switch (action) + { + case TrayMenuItemAction::FocusTerminal: + { + winrt::Microsoft::Terminal::Remoting::SummonWindowSelectionArgs args{}; + args.SummonBehavior().ToggleVisibility(false); + _SummonWindowRequestedHandlers(args); + break; + } + } +} + +void TrayIcon::TrayIconPressed() +{ + // No name in the args means summon the mru window. + winrt::Microsoft::Terminal::Remoting::SummonWindowSelectionArgs args{}; + args.SummonBehavior().ToggleVisibility(false); + _SummonWindowRequestedHandlers(args); +} + +// Method Description: +// - Deletes our tray icon if we have one. +// Arguments: +// - +// Return Value: +// - +void TrayIcon::DestroyTrayIcon() +{ + // We currently have a tray icon, but after a settings change + // we shouldn't have one. In this case, we'll need to destroy our + // tray icon and show any hidden windows. + // For the sake of simplicity in this rare case, let's just summon + // all the windows. + // TODO: Put this section inside of AppHost. + //if (_windowManager.IsMonarch()) + //{ + // _windowManager.SummonAllWindows(); + //} + Shell_NotifyIcon(NIM_DELETE, &_trayIconData); +} diff --git a/src/cascadia/WindowsTerminal/TrayIcon.h b/src/cascadia/WindowsTerminal/TrayIcon.h new file mode 100644 index 00000000000..0ca04e00fdc --- /dev/null +++ b/src/cascadia/WindowsTerminal/TrayIcon.h @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "../cascadia/inc/cppwinrt_utils.h" + +#define CM_NOTIFY_FROM_TRAY (WM_APP + 1) + +// This enumerates all the possible actions +// that our tray icon context menu could do. +enum class TrayMenuItemAction +{ + FocusTerminal, // Focus the MRU terminal. + SummonWindow +}; + +class TrayIcon +{ +public: + TrayIcon() = delete; + TrayIcon(const HWND owningHwnd); + ~TrayIcon(); + + void CreateTrayIcon(); + void TrayIconPressed(); + void ShowTrayContextMenu(const til::point coord, winrt::Windows::Foundation::Collections::IMapView peasants); + void TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex); + void DestroyTrayIcon(); + + WINRT_CALLBACK(SummonWindowRequested, winrt::delegate); + +private: + HMENU _CreateTrayContextMenu(); + HMENU _CreateWindowSubmenu(winrt::Windows::Foundation::Collections::IMapView peasants); + + HWND _owningHwnd; + NOTIFYICONDATA _trayIconData; +}; diff --git a/src/cascadia/WindowsTerminal/TrayIconData.h b/src/cascadia/WindowsTerminal/TrayIconData.h deleted file mode 100644 index 23498e026ca..00000000000 --- a/src/cascadia/WindowsTerminal/TrayIconData.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#pragma once -#include "pch.h" - -// This enumerates all the possible actions -// that our tray icon context menu could do. -enum class TrayMenuItemAction -{ - FocusTerminal, // Focus the MRU terminal. - SummonWindow -}; diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 2104e09bcb4..bbf7acb60c1 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -1,7 +1,6 @@ - {CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B} Win32Proj @@ -16,16 +15,13 @@ Windows true - - true - $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories); @@ -46,7 +42,7 @@ - + @@ -57,6 +53,7 @@ + @@ -76,19 +73,15 @@ - - - {CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE} false - x86 $(Platform) - <_OpenConsoleVCLibToCopy Include="$(VCToolsRedistInstallDir)\$(ReasonablePlatform)\Microsoft.VC142.CRT\*.dll" /> - $(ProjectName) BuiltProjectOutputGroup @@ -176,4 +154,4 @@ - + \ No newline at end of file From 3e6e5f55129d67683d382092ecd7c3f7678d1dac Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 24 Jun 2021 15:59:30 -0700 Subject: [PATCH 39/57] feature flags woohoo --- src/cascadia/TerminalApp/AppActionHandlers.cpp | 2 ++ src/cascadia/TerminalApp/AppLogic.cpp | 1 - src/cascadia/TerminalApp/TerminalPage.h | 3 +++ src/cascadia/WindowsTerminal/AppHost.cpp | 15 ++++++++++++++- src/cascadia/WindowsTerminal/AppHost.h | 13 +++---------- src/cascadia/WindowsTerminal/BaseWindow.h | 1 - src/cascadia/WindowsTerminal/IslandWindow.cpp | 8 ++++++++ src/cascadia/WindowsTerminal/IslandWindow.h | 3 +++ src/cascadia/WindowsTerminal/TrayIcon.cpp | 10 ---------- src/features.xml | 8 ++++++++ 10 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 4ee38241432..222718c98c3 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -816,6 +816,7 @@ namespace winrt::TerminalApp::implementation } } +#if TIL_FEATURE_TRAYICON_ENABLED void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, const ActionEventArgs& args) { @@ -826,4 +827,5 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } +#endif } diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 03f1d4eaeb2..649cba23bfc 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1496,5 +1496,4 @@ namespace winrt::TerminalApp::implementation return _settings.GlobalSettings().AlwaysShowTrayIcon(); } - } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index da359610d22..e2532fd86e7 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -123,7 +123,10 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); TYPED_EVENT(SummonWindowRequested, IInspectable, IInspectable); + +#if TIL_FEATURE_TRAYICON_ENABLED TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable); +#endif private: friend struct TerminalPageT; // for Xaml to bind events diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 63a69860ce2..d5059c280c7 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -66,7 +66,9 @@ AppHost::AppHost() noexcept : // Update our own internal state tracking if we're in quake mode or not. _IsQuakeWindowChanged(nullptr, nullptr); +#if TIL_FEATURE_TRAYICON_ENABLED _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); +#endif // Tell the window to callback to us when it's about to handle a WM_CREATE auto pfn = std::bind(&AppHost::_HandleCreateWindow, @@ -95,11 +97,13 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { +#if TIL_FEATURE_TRAYICON_ENABLED // destruction order is important for proper teardown here if (_windowManager.IsMonarch() && _trayIcon) { _DestroyTrayIcon(); } +#endif _window = nullptr; _app.Close(); @@ -277,7 +281,10 @@ void AppHost::Initialize() _logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged }); _logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged }); _logic.SummonWindowRequested({ this, &AppHost::_SummonWindowRequested }); + +#if TIL_FEATURE_TRAYICON_ENABLED _logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested }); +#endif _window->UpdateTitle(_logic.Title()); @@ -652,7 +659,9 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { +#if TIL_FEATURE_TRAYICON_ENABLED _CreateTrayIcon(); +#endif _setupGlobalHotkeys(); @@ -934,6 +943,7 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta { _setupGlobalHotkeys(); +#if TIL_FEATURE_TRAYICON_ENABLED // If we're monarch, we need to check two particular settings for // the tray icon - MinimizeToTray and AlwaysShowTrayIcon. If either // one of them are true, we want to make sure there's a tray icon. @@ -954,6 +964,7 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta } _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); +#endif } void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&, @@ -973,6 +984,7 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta _HandleSummon(sender, summonArgs); } +#if TIL_FEATURE_TRAYICON_ENABLED void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { @@ -991,7 +1003,7 @@ void AppHost::_CreateTrayIcon() // Hookup the handlers, save the tokens for revoking if settings change. _ReAddTrayIconToken = _window->NotifyReAddTrayIcon({ this, &AppHost::_CreateTrayIcon }); - _TrayIconPressedToken = _window->NotifyTrayIconPressed([this]() { _trayIcon->HandleTrayIconPressed(); }); + _TrayIconPressedToken = _window->NotifyTrayIconPressed([this]() { _trayIcon->TrayIconPressed(); }); _ShowTrayContextMenuToken = _window->NotifyShowTrayContextMenu([this](til::point coord) { _trayIcon->ShowTrayContextMenu(coord, _windowManager.GetPeasantNames()); }); _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU menuHandle, UINT menuItemIndex) { _trayIcon->TrayMenuItemSelected(menuHandle, menuItemIndex); }); _trayIcon->SummonWindowRequested([this](auto& args) { _windowManager.SummonWindow(args); }); @@ -1013,3 +1025,4 @@ void AppHost::_DestroyTrayIcon() _trayIcon->DestroyTrayIcon(); _trayIcon = nullptr; } +#endif diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 82f858078ba..5a8090115f6 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -87,23 +87,16 @@ class AppHost void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); +#if TIL_FEATURE_TRAYICON_ENABLED void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable&); - void _UpdateTrayIcon(); - void _HandleTrayIconPressed(); - void _ShowTrayContextMenu(const til::point coord); - HMENU _CreateTrayContextMenu(); - HMENU _CreateWindowSubmenu(); - void _TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex); - void _DestroyTrayIcon(); - - std::optional _trayIconData; - void _CreateTrayIcon(); + void _DestroyTrayIcon(); std::unique_ptr _trayIcon; winrt::event_token _ReAddTrayIconToken; winrt::event_token _TrayIconPressedToken; winrt::event_token _ShowTrayContextMenuToken; winrt::event_token _TrayMenuItemSelectedToken; +#endif }; diff --git a/src/cascadia/WindowsTerminal/BaseWindow.h b/src/cascadia/WindowsTerminal/BaseWindow.h index 3d285ed972c..d1a8b86d775 100644 --- a/src/cascadia/WindowsTerminal/BaseWindow.h +++ b/src/cascadia/WindowsTerminal/BaseWindow.h @@ -5,7 +5,6 @@ // Custom window messages #define CM_UPDATE_TITLE (WM_USER) -#define CM_NOTIFY_FROM_TRAY (WM_APP + 1) #include diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index e4badeaa856..4f62dd00d22 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -7,6 +7,10 @@ #include "resource.h" #include "icon.h" +#if TIL_FEATURE_TRAYICON_ENABLED +#include "TrayIcon.h" +#endif + extern "C" IMAGE_DOS_HEADER __ImageBase; using namespace winrt::Windows::UI; @@ -508,6 +512,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize case WM_THEMECHANGED: UpdateWindowIconForActiveMetrics(_window.get()); return 0; +#if TIL_FEATURE_TRAYICON_ENABLED case CM_NOTIFY_FROM_TRAY: { switch (LOWORD(lparam)) @@ -532,8 +537,10 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize _NotifyTrayMenuItemSelectedHandlers((HMENU)lparam, (UINT)wparam); return 0; } +#endif } +#if TIL_FEATURE_TRAYICON_ENABLED // We'll want to receive this message when explorer.exe restarts // so that we can re-add our icon to the tray. if (message == WM_TASKBARCREATED) @@ -541,6 +548,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize _NotifyReAddTrayIconHandlers(); return 0; } +#endif // TODO: handle messages here... return base_type::MessageHandler(message, wparam, lparam); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index c962f787e1b..50ba7dfcf49 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -54,10 +54,13 @@ class IslandWindow : WINRT_CALLBACK(MouseScrolled, winrt::delegate); WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); + +#if TIL_FEATURE_TRAYICON_ENABLED WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate); WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate); WINRT_CALLBACK(NotifyReAddTrayIcon, winrt::delegate); +#endif protected: void ForceResize() diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 6af83b693e7..35d57a892f9 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -214,15 +214,5 @@ void TrayIcon::TrayIconPressed() // - void TrayIcon::DestroyTrayIcon() { - // We currently have a tray icon, but after a settings change - // we shouldn't have one. In this case, we'll need to destroy our - // tray icon and show any hidden windows. - // For the sake of simplicity in this rare case, let's just summon - // all the windows. - // TODO: Put this section inside of AppHost. - //if (_windowManager.IsMonarch()) - //{ - // _windowManager.SummonAllWindows(); - //} Shell_NotifyIcon(NIM_DELETE, &_trayIconData); } diff --git a/src/features.xml b/src/features.xml index 7ad1db40c0c..e9f8705fb62 100644 --- a/src/features.xml +++ b/src/features.xml @@ -49,4 +49,12 @@ WindowsInbox + + + Feature_TrayIcon + Controls whether the Tray Icon and related settings (aka. MinimizeToTray and AlwaysShowTrayIcon) are enabled + AlwaysDisabled + + + From 4f58b42a2c2b0aa925b9f336b4b72d2f3a00b1b9 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 24 Jun 2021 17:07:00 -0700 Subject: [PATCH 40/57] feature flags woohoo 2 --- .../TerminalApp/AppActionHandlers.cpp | 4 +- src/cascadia/TerminalApp/TerminalPage.h | 3 - src/cascadia/WindowsTerminal/AppHost.cpp | 5 +- src/cascadia/WindowsTerminal/AppHost.h | 3 + src/cascadia/WindowsTerminal/IslandWindow.cpp | 4 + src/cascadia/WindowsTerminal/IslandWindow.h | 5 ++ src/cascadia/WindowsTerminal/TrayIcon.cpp | 86 ++++++++++--------- src/cascadia/WindowsTerminal/TrayIcon.h | 7 +- src/features.xml | 1 + 9 files changed, 66 insertions(+), 52 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 222718c98c3..f291b80093b 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -816,16 +816,16 @@ namespace winrt::TerminalApp::implementation } } -#if TIL_FEATURE_TRAYICON_ENABLED void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, const ActionEventArgs& args) { +#if TIL_FEATURE_TRAYICON_ENABLED if (_settings.GlobalSettings().MinimizeToTray() || _settings.GlobalSettings().AlwaysShowTrayIcon()) { _MinimizeToTrayRequestedHandlers(*this, nullptr); } +#endif args.Handled(true); } -#endif } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index e2532fd86e7..da359610d22 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -123,10 +123,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); TYPED_EVENT(SummonWindowRequested, IInspectable, IInspectable); - -#if TIL_FEATURE_TRAYICON_ENABLED TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable); -#endif private: friend struct TerminalPageT; // for Xaml to bind events diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index d5059c280c7..0be09871b48 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -11,7 +11,6 @@ #include "VirtualDesktopUtils.h" #include "icon.h" -#include #include using namespace winrt::Windows::UI; @@ -1002,10 +1001,10 @@ void AppHost::_CreateTrayIcon() _trayIcon = std::make_unique(_window->GetHandle()); // Hookup the handlers, save the tokens for revoking if settings change. - _ReAddTrayIconToken = _window->NotifyReAddTrayIcon({ this, &AppHost::_CreateTrayIcon }); + _ReAddTrayIconToken = _window->NotifyReAddTrayIcon([this]() { _trayIcon->ReAddTrayIcon(); }); _TrayIconPressedToken = _window->NotifyTrayIconPressed([this]() { _trayIcon->TrayIconPressed(); }); _ShowTrayContextMenuToken = _window->NotifyShowTrayContextMenu([this](til::point coord) { _trayIcon->ShowTrayContextMenu(coord, _windowManager.GetPeasantNames()); }); - _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU menuHandle, UINT menuItemIndex) { _trayIcon->TrayMenuItemSelected(menuHandle, menuItemIndex); }); + _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU hm, UINT idx) { _trayIcon->TrayMenuItemSelected(hm, idx); }); _trayIcon->SummonWindowRequested([this](auto& args) { _windowManager.SummonWindow(args); }); } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 5a8090115f6..8f12381366f 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -4,7 +4,10 @@ #include "pch.h" #include "NonClientIslandWindow.h" + +#if TIL_FEATURE_TRAYICON_ENABLED #include "TrayIcon.h" +#endif class AppHost { diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 4f62dd00d22..67b60132765 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -572,10 +572,12 @@ void IslandWindow::OnResize(const UINT width, const UINT height) void IslandWindow::OnMinimize() { // TODO GH#1989 Stop rendering island content when the app is minimized. +#if TIL_FEATURE_TRAYICON_ENABLED if (_minimizeToTray) { HideWindow(); } +#endif } // Method Description: @@ -1510,10 +1512,12 @@ void IslandWindow::HideWindow() ShowWindow(GetHandle(), SW_HIDE); } +#if TIL_FEATURE_TRAYICON_ENABLED void IslandWindow::SetMinimizeToTrayBehavior(bool minimizeToTray) noexcept { _minimizeToTray = minimizeToTray; } +#endif DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DEFINE_EVENT(IslandWindow, WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 50ba7dfcf49..d119ad4d6cd 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -47,7 +47,10 @@ class IslandWindow : void IsQuakeWindow(bool isQuakeWindow) noexcept; void HideWindow(); + +#if TIL_FEATURE_TRAYICON_ENABLED void SetMinimizeToTrayBehavior(bool minimizeToTray) noexcept; +#endif DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); @@ -123,7 +126,9 @@ class IslandWindow : void _summonWindowRoutineBody(winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior args); +#if TIL_FEATURE_TRAYICON_ENABLED bool _minimizeToTray{ false }; +#endif private: // This minimum width allows for width the tabs fit diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 35d57a892f9..6efc7690108 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -61,27 +61,15 @@ void TrayIcon::CreateTrayIcon() // - This creates our context menu and displays it at the given // screen coordinates. // Arguments: -// - The coordinates where we should be showing the context menu. +// - coord: The coordinates where we should be showing the context menu. +// - peasants: The map of all peasants that should be available in the context menu. // Return Value: // - void TrayIcon::ShowTrayContextMenu(const til::point coord, IMapView peasants) { - if (auto hmenu = _CreateTrayContextMenu()) + if (auto hmenu = _CreateTrayContextMenu(peasants)) { - // Submenu for Windows - if (auto windowSubmenu = _CreateWindowSubmenu(peasants)) - { - MENUINFO submenuInfo{}; - submenuInfo.cbSize = sizeof(MENUINFO); - submenuInfo.fMask = MIM_MENUDATA; - submenuInfo.dwStyle = MNS_NOTIFYBYPOS; - submenuInfo.dwMenuData = gsl::narrow(TrayMenuItemAction::SummonWindow); - SetMenuInfo(windowSubmenu, &submenuInfo); - - AppendMenu(hmenu, MF_POPUP, reinterpret_cast(windowSubmenu), RS_(L"TrayIconWindowSubmenu").c_str()); - } - // We'll need to set our window to the foreground before calling // TrackPopupMenuEx or else the menu won't dismiss when clicking away. SetForegroundWindow(_owningHwnd); @@ -107,10 +95,10 @@ void TrayIcon::ShowTrayContextMenu(const til::point coord, // Method Description: // - This creates the context menu for our tray icon. // Arguments: -// - +// - peasants: A map of all peasants' ID to their window name. // Return Value: // - The handle to the newly created context menu. -HMENU TrayIcon::_CreateTrayContextMenu() +HMENU TrayIcon::_CreateTrayContextMenu(IMapView peasants) { auto hmenu = CreatePopupMenu(); if (hmenu) @@ -125,36 +113,34 @@ HMENU TrayIcon::_CreateTrayContextMenu() // Focus Current Terminal Window AppendMenu(hmenu, MF_STRING, gsl::narrow(TrayMenuItemAction::FocusTerminal), RS_(L"TrayIconFocusTerminal").c_str()); AppendMenu(hmenu, MF_SEPARATOR, 0, L""); - } - return hmenu; -} -// Method Description: -// - Create a menu with a menu item for each window available to summon. -// If a window is unnamed, we'll use its ID but still mention that it's unnamed. -// Arguments: -// - -// Return Value: -// - The handle to the newly created window submenu. -HMENU TrayIcon::_CreateWindowSubmenu(IMapView peasants) -{ - if (auto hmenu = CreatePopupMenu()) - { - const auto locWindow = RS_(L"WindowIdLabel"); - const auto locUnnamed = RS_(L"UnnamedWindowName"); - for (const auto [id, name] : peasants) + // Submenu for Windows + if (auto submenu = CreatePopupMenu()) { - winrt::hstring displayText = name; - if (name.empty()) + const auto locWindow = RS_(L"WindowIdLabel"); + const auto locUnnamed = RS_(L"UnnamedWindowName"); + for (const auto [id, name] : peasants) { - displayText = fmt::format(L"{} {} - <{}>", locWindow, id, locUnnamed); + winrt::hstring displayText = name; + if (name.empty()) + { + displayText = fmt::format(L"{} {} - <{}>", locWindow, id, locUnnamed); + } + + AppendMenu(submenu, MF_STRING, gsl::narrow(id), displayText.c_str()); } - AppendMenu(hmenu, MF_STRING, gsl::narrow(id), displayText.c_str()); + MENUINFO submenuInfo{}; + submenuInfo.cbSize = sizeof(MENUINFO); + submenuInfo.fMask = MIM_MENUDATA; + submenuInfo.dwStyle = MNS_NOTIFYBYPOS; + submenuInfo.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; + SetMenuInfo(submenu, &submenuInfo); + + AppendMenu(hmenu, MF_POPUP, (UINT_PTR)submenu, RS_(L"TrayIconWindowSubmenu").c_str()); } - return hmenu; } - return nullptr; + return hmenu; } // Method Description: @@ -198,6 +184,12 @@ void TrayIcon::TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) } } +// Method Description: +// - This is the handler for when the tray icon itself is left-clicked. +// Arguments: +// - +// Return Value: +// - void TrayIcon::TrayIconPressed() { // No name in the args means summon the mru window. @@ -207,7 +199,19 @@ void TrayIcon::TrayIconPressed() } // Method Description: -// - Deletes our tray icon if we have one. +// - Re-add a tray icon using our currently saved tray icon data. +// Arguments: +// - +// Return Value: +// - +void TrayIcon::ReAddTrayIcon() +{ + Shell_NotifyIcon(NIM_ADD, &_trayIconData); + Shell_NotifyIcon(NIM_SETVERSION, &_trayIconData); +} + +// Method Description: +// - Deletes our tray icon. // Arguments: // - // Return Value: diff --git a/src/cascadia/WindowsTerminal/TrayIcon.h b/src/cascadia/WindowsTerminal/TrayIcon.h index 0ca04e00fdc..64dee43a2c1 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.h +++ b/src/cascadia/WindowsTerminal/TrayIcon.h @@ -22,16 +22,17 @@ class TrayIcon ~TrayIcon(); void CreateTrayIcon(); + void DestroyTrayIcon(); + void ReAddTrayIcon(); + void TrayIconPressed(); void ShowTrayContextMenu(const til::point coord, winrt::Windows::Foundation::Collections::IMapView peasants); void TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex); - void DestroyTrayIcon(); WINRT_CALLBACK(SummonWindowRequested, winrt::delegate); private: - HMENU _CreateTrayContextMenu(); - HMENU _CreateWindowSubmenu(winrt::Windows::Foundation::Collections::IMapView peasants); + HMENU _CreateTrayContextMenu(winrt::Windows::Foundation::Collections::IMapView peasants); HWND _owningHwnd; NOTIFYICONDATA _trayIconData; diff --git a/src/features.xml b/src/features.xml index e9f8705fb62..78d3acc7021 100644 --- a/src/features.xml +++ b/src/features.xml @@ -55,6 +55,7 @@ Controls whether the Tray Icon and related settings (aka. MinimizeToTray and AlwaysShowTrayIcon) are enabled AlwaysDisabled + Dev From 31901a5583efbafca3c340c850bf48854a22933f Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Sat, 26 Jun 2021 10:19:11 -0700 Subject: [PATCH 41/57] use alwaysDisabledReleaseTokens --- src/features.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/features.xml b/src/features.xml index 78d3acc7021..c06ce52aaf5 100644 --- a/src/features.xml +++ b/src/features.xml @@ -53,9 +53,7 @@ Feature_TrayIcon Controls whether the Tray Icon and related settings (aka. MinimizeToTray and AlwaysShowTrayIcon) are enabled - AlwaysDisabled - - Dev - + AlwaysEnabled + From 722e1765eae68f2cb9ee7faf3991dbd16d47caac Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 28 Jun 2021 08:34:39 -0700 Subject: [PATCH 42/57] formatting --- src/cascadia/WindowsTerminal/TrayIcon.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 6efc7690108..83cc505d5f3 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -56,7 +56,6 @@ void TrayIcon::CreateTrayIcon() _trayIconData = nid; } - // Method Description: // - This creates our context menu and displays it at the given // screen coordinates. From df6a765db3028252767719f59fad83c3d80ff22e Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 28 Jun 2021 12:26:38 -0700 Subject: [PATCH 43/57] manual resource load, vcxproj revert --- src/cascadia/WindowsTerminal/TrayIcon.cpp | 7 ++++- .../WindowsTerminal/WindowsTerminal.vcxproj | 26 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 83cc505d5f3..4df56f3e9f6 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -2,6 +2,7 @@ #include "icon.h" #include "TrayIcon.h" +#include #include using namespace winrt::Windows::Foundation::Collections; @@ -41,8 +42,12 @@ void TrayIcon::CreateTrayIcon() nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; + // AppName happens to be in CascadiaPackage's Resources. + ScopedResourceLoader srl{ L"Resources" }; + auto appNameLoc = srl.GetLocalizedString(L"AppName"); + nid.hIcon = static_cast(GetActiveAppIconHandle(true)); - StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), RS_(L"AppName").c_str()); + StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), appNameLoc.c_str()); nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &nid); diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index bbf7acb60c1..424c78e5d67 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -1,6 +1,7 @@ + {CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B} Win32Proj @@ -15,13 +16,16 @@ Windows true + + true + $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories); @@ -73,15 +77,18 @@ + + {CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE} false + x86 $(Platform) + <_OpenConsoleVCLibToCopy Include="$(VCToolsRedistInstallDir)\$(ReasonablePlatform)\Microsoft.VC142.CRT\*.dll" /> + $(ProjectName) BuiltProjectOutputGroup From 462fa7438dd995e3732486b41328c839deaf92e2 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 16 Jul 2021 07:20:51 -0700 Subject: [PATCH 44/57] spellers --- src/cascadia/WindowsTerminal/TrayIcon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 8e5b3081bad..4c4e59f4cde 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -44,8 +44,8 @@ void TrayIcon::CreateTrayIcon() nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY; // AppName happens to be in CascadiaPackage's Resources. - ScopedResourceLoader srl{ L"Resources" }; - auto appNameLoc = srl.GetLocalizedString(L"AppName"); + ScopedResourceLoader loader{ L"Resources" }; + auto appNameLoc = loader.GetLocalizedString(L"AppName"); nid.hIcon = static_cast(GetActiveAppIconHandle(true)); StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), appNameLoc.c_str()); From 09370d16de34108f0d48f93fad4221f8f8e76747 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 16 Jul 2021 07:33:40 -0700 Subject: [PATCH 45/57] adding events to Peasant --- src/cascadia/Remoting/Peasant.cpp | 50 +++++++++++++++++++++++++++++++ src/cascadia/Remoting/Peasant.h | 6 ++++ src/cascadia/Remoting/Peasant.idl | 6 ++++ 3 files changed, 62 insertions(+) diff --git a/src/cascadia/Remoting/Peasant.cpp b/src/cascadia/Remoting/Peasant.cpp index 768a1ba364a..52e98d8ce28 100644 --- a/src/cascadia/Remoting/Peasant.cpp +++ b/src/cascadia/Remoting/Peasant.cpp @@ -225,4 +225,54 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), TraceLoggingKeyword(TIL_KEYWORD_TRACE)); } + + void Peasant::RequestShowTrayIcon() + { + try + { + // Try/catch this, because the other side of this event is handled + // by the monarch. The monarch might have died. If they have, this + // will throw an exception. Just eat it, the election thread will + // handle hooking up the new one. + _ShowTrayIconRequestedHandlers(*this, nullptr); + //if (args.Succeeded()) + //{ + // _WindowName = args.NewName(); + //} + //successfullyNotified = true; + } + catch (...) + { + LOG_CAUGHT_EXCEPTION(); + } + TraceLoggingWrite(g_hRemotingProvider, + "Peasant_RequestShowTrayIcon", + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + } + + void Peasant::RequestHideTrayIcon() + { + try + { + // Try/catch this, because the other side of this event is handled + // by the monarch. The monarch might have died. If they have, this + // will throw an exception. Just eat it, the election thread will + // handle hooking up the new one. + _HideTrayIconRequestedHandlers(*this, nullptr); + //if (args.Succeeded()) + //{ + // _WindowName = args.NewName(); + //} + //successfullyNotified = true; + } + catch (...) + { + LOG_CAUGHT_EXCEPTION(); + } + TraceLoggingWrite(g_hRemotingProvider, + "Peasant_RequestHideTrayIcon", + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + } } diff --git a/src/cascadia/Remoting/Peasant.h b/src/cascadia/Remoting/Peasant.h index 54e04601b56..52bb692f14b 100644 --- a/src/cascadia/Remoting/Peasant.h +++ b/src/cascadia/Remoting/Peasant.h @@ -30,6 +30,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void DisplayWindowId(); void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args); + void RequestShowTrayIcon(); + void RequestHideTrayIcon(); + winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs GetLastActivatedArgs(); winrt::Microsoft::Terminal::Remoting::CommandlineArgs InitialArgs(); @@ -42,6 +45,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs); TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior); + TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + private: uint64_t _ourPID; diff --git a/src/cascadia/Remoting/Peasant.idl b/src/cascadia/Remoting/Peasant.idl index bc36e3f3038..8dd6ded3461 100644 --- a/src/cascadia/Remoting/Peasant.idl +++ b/src/cascadia/Remoting/Peasant.idl @@ -65,12 +65,18 @@ namespace Microsoft.Terminal.Remoting void RequestRename(RenameRequestArgs args); // Tells us to raise a RenameRequested void Summon(SummonWindowBehavior behavior); + void RequestShowTrayIcon(); + void RequestHideTrayIcon(); + event Windows.Foundation.TypedEventHandler WindowActivated; event Windows.Foundation.TypedEventHandler ExecuteCommandlineRequested; event Windows.Foundation.TypedEventHandler IdentifyWindowsRequested; event Windows.Foundation.TypedEventHandler DisplayWindowIdRequested; event Windows.Foundation.TypedEventHandler RenameRequested; event Windows.Foundation.TypedEventHandler SummonRequested; + + event Windows.Foundation.TypedEventHandler ShowTrayIconRequested; + event Windows.Foundation.TypedEventHandler HideTrayIconRequested; }; [default_interface] runtimeclass Peasant : IPeasant From 59310fa5b6e2c3b08095d654a261bc3ec61a28c2 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 16 Jul 2021 12:57:02 -0700 Subject: [PATCH 46/57] adding events to Monarch, WindowManager, AppHost --- src/cascadia/Remoting/Monarch.cpp | 3 +++ src/cascadia/Remoting/Monarch.h | 2 ++ src/cascadia/Remoting/Monarch.idl | 2 ++ src/cascadia/Remoting/Peasant.h | 1 + src/cascadia/Remoting/WindowManager.cpp | 5 ++++ src/cascadia/Remoting/WindowManager.h | 5 ++++ src/cascadia/Remoting/WindowManager.idl | 2 ++ src/cascadia/WindowsTerminal/AppHost.cpp | 30 ++++++++++++++++++++++++ src/cascadia/WindowsTerminal/AppHost.h | 4 ++++ 9 files changed, 54 insertions(+) diff --git a/src/cascadia/Remoting/Monarch.cpp b/src/cascadia/Remoting/Monarch.cpp index 9fa13e46a76..48bb23c2b8c 100644 --- a/src/cascadia/Remoting/Monarch.cpp +++ b/src/cascadia/Remoting/Monarch.cpp @@ -80,6 +80,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation peasant.IdentifyWindowsRequested({ this, &Monarch::_identifyWindows }); peasant.RenameRequested({ this, &Monarch::_renameRequested }); + peasant.ShowTrayIconRequested([this](auto&&, auto&&) { _ShowTrayIconRequestedHandlers(*this, nullptr); }); + peasant.HideTrayIconRequested([this](auto&&, auto&&) { _HideTrayIconRequestedHandlers(*this, nullptr); }); + _peasants[newPeasantsId] = peasant; TraceLoggingWrite(g_hRemotingProvider, diff --git a/src/cascadia/Remoting/Monarch.h b/src/cascadia/Remoting/Monarch.h index 57daa5eee26..2aa30dab444 100644 --- a/src/cascadia/Remoting/Monarch.h +++ b/src/cascadia/Remoting/Monarch.h @@ -56,6 +56,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation Windows::Foundation::Collections::IMapView GetPeasantNames(); TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); + TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); private: uint64_t _ourPID; diff --git a/src/cascadia/Remoting/Monarch.idl b/src/cascadia/Remoting/Monarch.idl index 5655c18124f..f4e8bd8b4e1 100644 --- a/src/cascadia/Remoting/Monarch.idl +++ b/src/cascadia/Remoting/Monarch.idl @@ -45,5 +45,7 @@ namespace Microsoft.Terminal.Remoting Windows.Foundation.Collections.IMapView GetPeasantNames { get; }; event Windows.Foundation.TypedEventHandler FindTargetWindowRequested; + event Windows.Foundation.TypedEventHandler ShowTrayIconRequested; + event Windows.Foundation.TypedEventHandler HideTrayIconRequested; }; } diff --git a/src/cascadia/Remoting/Peasant.h b/src/cascadia/Remoting/Peasant.h index 52bb692f14b..69393e7002a 100644 --- a/src/cascadia/Remoting/Peasant.h +++ b/src/cascadia/Remoting/Peasant.h @@ -37,6 +37,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation winrt::Microsoft::Terminal::Remoting::CommandlineArgs InitialArgs(); WINRT_PROPERTY(winrt::hstring, WindowName); + WINRT_PROPERTY(bool, IsQuake); TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs); TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::CommandlineArgs); diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index de16377e62e..91d7f10cd03 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -255,6 +255,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation _monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested }); +#if TIL_FEATURE_TRAYICON_ENABLED + _monarch.ShowTrayIconRequested([this](auto&&, auto&&){ _ShowTrayIconRequestedHandlers(*this, nullptr); }); + _monarch.HideTrayIconRequested([this](auto&&, auto&&){ _HideTrayIconRequestedHandlers(*this, nullptr); }); +#endif + _BecameMonarchHandlers(*this, nullptr); } diff --git a/src/cascadia/Remoting/WindowManager.h b/src/cascadia/Remoting/WindowManager.h index 7b2a0617d21..2af03717cb6 100644 --- a/src/cascadia/Remoting/WindowManager.h +++ b/src/cascadia/Remoting/WindowManager.h @@ -46,6 +46,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); TYPED_EVENT(BecameMonarch, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); +#if TIL_FEATURE_TRAYICON_ENABLED + TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); +#endif + private: bool _shouldCreateWindow{ false }; bool _isKing{ false }; diff --git a/src/cascadia/Remoting/WindowManager.idl b/src/cascadia/Remoting/WindowManager.idl index 2af74725228..5f125984b66 100644 --- a/src/cascadia/Remoting/WindowManager.idl +++ b/src/cascadia/Remoting/WindowManager.idl @@ -16,5 +16,7 @@ namespace Microsoft.Terminal.Remoting Windows.Foundation.Collections.IMapView GetPeasantNames(); event Windows.Foundation.TypedEventHandler FindTargetWindowRequested; event Windows.Foundation.TypedEventHandler BecameMonarch; + event Windows.Foundation.TypedEventHandler ShowTrayIconRequested; + event Windows.Foundation.TypedEventHandler HideTrayIconRequested; }; } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index ad7649bdbe8..5f71958e433 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -659,10 +659,19 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s const winrt::Windows::Foundation::IInspectable& /*args*/) { #if TIL_FEATURE_TRAYICON_ENABLED + // TODO: Check if there's a quake window _somewhere_. If there is, + // we'll need to show our tray icon regardless of settings. + if (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray()) { _CreateTrayIcon(); } + + // These events are coming from peasants that become or un-become quake windows. + // A "show" event's priority comes _before_ any tray icon display settings. + // A "hide" event's priority comes _after_ the tray icon display settings. + _windowManager.ShowTrayIconRequested({ this, &AppHost::_ShowTrayIconRequested }); + _windowManager.HideTrayIconRequested({ this, &AppHost::_HideTrayIconRequested }); #endif _setupGlobalHotkeys(); @@ -1027,4 +1036,25 @@ void AppHost::_DestroyTrayIcon() _trayIcon->DestroyTrayIcon(); _trayIcon = nullptr; } + +void AppHost::_ShowTrayIconRequested(const winrt::Windows::Foundation::IInspectable&, + const winrt::Windows::Foundation::IInspectable&) +{ + if (!_trayIcon) + { + _CreateTrayIcon(); + } +} + +void AppHost::_HideTrayIconRequested(const winrt::Windows::Foundation::IInspectable&, + const winrt::Windows::Foundation::IInspectable&) +{ + // Destroy it only if our settings allow it + if (_trayIcon && + !_logic.GetAlwaysShowTrayIcon() && + !_logic.GetMinimizeToTray()) + { + _DestroyTrayIcon(); + } +} #endif diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 8f12381366f..b8284bebe44 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -96,6 +96,10 @@ class AppHost void _CreateTrayIcon(); void _DestroyTrayIcon(); + void _ShowTrayIconRequested(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable& args); + void _HideTrayIconRequested(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable& args); std::unique_ptr _trayIcon; winrt::event_token _ReAddTrayIconToken; winrt::event_token _TrayIconPressedToken; From 7fd99025be33e5a064e41c25c4ff63ff82dbbcb3 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Sun, 18 Jul 2021 16:21:20 -0700 Subject: [PATCH 47/57] make the peasants let the monarch know what's up --- src/cascadia/Remoting/WindowManager.cpp | 13 +++++ src/cascadia/Remoting/WindowManager.h | 5 ++ src/cascadia/Remoting/WindowManager.idl | 2 + src/cascadia/WindowsTerminal/AppHost.cpp | 67 ++++++++++++++++++------ src/cascadia/WindowsTerminal/AppHost.h | 6 +-- 5 files changed, 73 insertions(+), 20 deletions(-) diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index 91d7f10cd03..1b930cccf97 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -526,4 +526,17 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation return _monarch.GetPeasantNames(); } +#if TIL_FEATURE_TRAYICON_ENABLED + // These should only be called if we're a Peasant. + void WindowManager::RequestShowTrayIcon() + { + _peasant.RequestShowTrayIcon(); + } + + void WindowManager::RequestHideTrayIcon() + { + _peasant.RequestHideTrayIcon(); + } +#endif + } diff --git a/src/cascadia/Remoting/WindowManager.h b/src/cascadia/Remoting/WindowManager.h index 2af03717cb6..3b64800d0f3 100644 --- a/src/cascadia/Remoting/WindowManager.h +++ b/src/cascadia/Remoting/WindowManager.h @@ -43,6 +43,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void SummonAllWindows(); Windows::Foundation::Collections::IMapView GetPeasantNames(); +#if TIL_FEATURE_TRAYICON_ENABLED + void RequestShowTrayIcon(); + void RequestHideTrayIcon(); +#endif + TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); TYPED_EVENT(BecameMonarch, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); diff --git a/src/cascadia/Remoting/WindowManager.idl b/src/cascadia/Remoting/WindowManager.idl index 5f125984b66..08053e18d5d 100644 --- a/src/cascadia/Remoting/WindowManager.idl +++ b/src/cascadia/Remoting/WindowManager.idl @@ -13,6 +13,8 @@ namespace Microsoft.Terminal.Remoting Boolean IsMonarch { get; }; void SummonWindow(SummonWindowSelectionArgs args); void SummonAllWindows(); + void RequestShowTrayIcon(); + void RequestHideTrayIcon(); Windows.Foundation.Collections.IMapView GetPeasantNames(); event Windows.Foundation.TypedEventHandler FindTargetWindowRequested; event Windows.Foundation.TypedEventHandler BecameMonarch; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 5f71958e433..16e5c4047be 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -97,13 +97,20 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { #if TIL_FEATURE_TRAYICON_ENABLED - // destruction order is important for proper teardown here + // We either delete our tray icon if we're the monarch and we have one, + // or we have to let the monarch know they should attempt to delete their + // icon. if (_windowManager.IsMonarch() && _trayIcon) { _DestroyTrayIcon(); } + else if (_window->IsQuakeWindow()) + { + _windowManager.RequestHideTrayIcon(); + } #endif + // destruction order is important for proper teardown here _window = nullptr; _app.Close(); _app = nullptr; @@ -668,10 +675,8 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s } // These events are coming from peasants that become or un-become quake windows. - // A "show" event's priority comes _before_ any tray icon display settings. - // A "hide" event's priority comes _after_ the tray icon display settings. - _windowManager.ShowTrayIconRequested({ this, &AppHost::_ShowTrayIconRequested }); - _windowManager.HideTrayIconRequested({ this, &AppHost::_HideTrayIconRequested }); + _windowManager.ShowTrayIconRequested([this](auto&&, auto&&) { _ShowTrayIconRequested(); }); + _windowManager.HideTrayIconRequested([this](auto&&, auto&&) { _HideTrayIconRequested(); }); #endif _setupGlobalHotkeys(); @@ -982,6 +987,22 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab const winrt::Windows::Foundation::IInspectable&) { _window->IsQuakeWindow(_logic.IsQuakeWindow()); + +#if TIL_FEATURE_TRAYICON_ENABLED + // We want the quake window to be accessible through the tray icon. + // This means if there's a quake window _somewhere_, we want the tray icon + // to show regardless of the tray icon settings. + // This also means we'll need to destroy the tray icon if it was created + // specifically for the quake window. If not, it should not be destroyed. + if (_window->IsQuakeWindow()) + { + _ShowTrayIconRequested(); + } + else + { + _HideTrayIconRequested(); + } +#endif } void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender, @@ -1037,24 +1058,38 @@ void AppHost::_DestroyTrayIcon() _trayIcon = nullptr; } -void AppHost::_ShowTrayIconRequested(const winrt::Windows::Foundation::IInspectable&, - const winrt::Windows::Foundation::IInspectable&) +void AppHost::_ShowTrayIconRequested() { - if (!_trayIcon) + if (_windowManager.IsMonarch()) { - _CreateTrayIcon(); + if (!_trayIcon) + { + _CreateTrayIcon(); + } + } + else + { + // TODO: Tell WindowManager to notify Monarch to show icon. + _windowManager.RequestShowTrayIcon(); } } -void AppHost::_HideTrayIconRequested(const winrt::Windows::Foundation::IInspectable&, - const winrt::Windows::Foundation::IInspectable&) +void AppHost::_HideTrayIconRequested() { - // Destroy it only if our settings allow it - if (_trayIcon && - !_logic.GetAlwaysShowTrayIcon() && - !_logic.GetMinimizeToTray()) + if (_windowManager.IsMonarch()) { - _DestroyTrayIcon(); + // Destroy it only if our settings allow it + if (_trayIcon && + !_logic.GetAlwaysShowTrayIcon() && + !_logic.GetMinimizeToTray()) + { + _DestroyTrayIcon(); + } + } + else + { + // TODO: Tell WindowManager to notify Monarch to hide the icon. + _windowManager.RequestHideTrayIcon(); } } #endif diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index b8284bebe44..f5cb05dae67 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -96,10 +96,8 @@ class AppHost void _CreateTrayIcon(); void _DestroyTrayIcon(); - void _ShowTrayIconRequested(const winrt::Windows::Foundation::IInspectable& sender, - const winrt::Windows::Foundation::IInspectable& args); - void _HideTrayIconRequested(const winrt::Windows::Foundation::IInspectable& sender, - const winrt::Windows::Foundation::IInspectable& args); + void _ShowTrayIconRequested(); + void _HideTrayIconRequested(); std::unique_ptr _trayIcon; winrt::event_token _ReAddTrayIconToken; winrt::event_token _TrayIconPressedToken; From add9aa0f9ad910a78fa169509248f3dddf3c6be8 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 19 Jul 2021 14:37:41 -0700 Subject: [PATCH 48/57] now make the new monarch check for quakes --- src/cascadia/Remoting/Peasant.cpp | 20 +--------- src/cascadia/Remoting/Peasant.h | 5 ++- src/cascadia/Remoting/WindowManager.cpp | 13 ++++++ src/cascadia/Remoting/WindowManager.h | 1 + src/cascadia/Remoting/WindowManager.idl | 1 + src/cascadia/WindowsTerminal/AppHost.cpp | 51 +++++++++++------------- 6 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/cascadia/Remoting/Peasant.cpp b/src/cascadia/Remoting/Peasant.cpp index 52e98d8ce28..124bd9a6ec0 100644 --- a/src/cascadia/Remoting/Peasant.cpp +++ b/src/cascadia/Remoting/Peasant.cpp @@ -226,20 +226,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TraceLoggingKeyword(TIL_KEYWORD_TRACE)); } +#if TIL_FEATURE_TRAYICON_ENABLED void Peasant::RequestShowTrayIcon() { try { - // Try/catch this, because the other side of this event is handled - // by the monarch. The monarch might have died. If they have, this - // will throw an exception. Just eat it, the election thread will - // handle hooking up the new one. _ShowTrayIconRequestedHandlers(*this, nullptr); - //if (args.Succeeded()) - //{ - // _WindowName = args.NewName(); - //} - //successfullyNotified = true; } catch (...) { @@ -255,16 +247,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation { try { - // Try/catch this, because the other side of this event is handled - // by the monarch. The monarch might have died. If they have, this - // will throw an exception. Just eat it, the election thread will - // handle hooking up the new one. _HideTrayIconRequestedHandlers(*this, nullptr); - //if (args.Succeeded()) - //{ - // _WindowName = args.NewName(); - //} - //successfullyNotified = true; } catch (...) { @@ -275,4 +258,5 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), TraceLoggingKeyword(TIL_KEYWORD_TRACE)); } +#endif } diff --git a/src/cascadia/Remoting/Peasant.h b/src/cascadia/Remoting/Peasant.h index 69393e7002a..e5e920699ed 100644 --- a/src/cascadia/Remoting/Peasant.h +++ b/src/cascadia/Remoting/Peasant.h @@ -30,14 +30,15 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void DisplayWindowId(); void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args); +#if TIL_FEATURE_TRAYICON_ENABLED void RequestShowTrayIcon(); void RequestHideTrayIcon(); +#endif winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs GetLastActivatedArgs(); winrt::Microsoft::Terminal::Remoting::CommandlineArgs InitialArgs(); WINRT_PROPERTY(winrt::hstring, WindowName); - WINRT_PROPERTY(bool, IsQuake); TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs); TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::CommandlineArgs); @@ -46,8 +47,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs); TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior); +#if TIL_FEATURE_TRAYICON_ENABLED TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); +#endif private: uint64_t _ourPID; diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index 1b930cccf97..effc5953a03 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -537,6 +537,19 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation { _peasant.RequestHideTrayIcon(); } + + bool WindowManager::DoesQuakeWindowExist() + { + const auto names = GetPeasantNames(); + for (const auto [id, name] : names) + { + if (name == QuakeWindowName) + { + return true; + } + } + return false; + } #endif } diff --git a/src/cascadia/Remoting/WindowManager.h b/src/cascadia/Remoting/WindowManager.h index 3b64800d0f3..cf8b51dc439 100644 --- a/src/cascadia/Remoting/WindowManager.h +++ b/src/cascadia/Remoting/WindowManager.h @@ -46,6 +46,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation #if TIL_FEATURE_TRAYICON_ENABLED void RequestShowTrayIcon(); void RequestHideTrayIcon(); + bool DoesQuakeWindowExist(); #endif TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); diff --git a/src/cascadia/Remoting/WindowManager.idl b/src/cascadia/Remoting/WindowManager.idl index 08053e18d5d..ca1f9f747b9 100644 --- a/src/cascadia/Remoting/WindowManager.idl +++ b/src/cascadia/Remoting/WindowManager.idl @@ -15,6 +15,7 @@ namespace Microsoft.Terminal.Remoting void SummonAllWindows(); void RequestShowTrayIcon(); void RequestHideTrayIcon(); + Boolean DoesQuakeWindowExist(); Windows.Foundation.Collections.IMapView GetPeasantNames(); event Windows.Foundation.TypedEventHandler FindTargetWindowRequested; event Windows.Foundation.TypedEventHandler BecameMonarch; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 16e5c4047be..120aa4bdc9c 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -97,14 +97,7 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { #if TIL_FEATURE_TRAYICON_ENABLED - // We either delete our tray icon if we're the monarch and we have one, - // or we have to let the monarch know they should attempt to delete their - // icon. - if (_windowManager.IsMonarch() && _trayIcon) - { - _DestroyTrayIcon(); - } - else if (_window->IsQuakeWindow()) + if (_window->IsQuakeWindow()) { _windowManager.RequestHideTrayIcon(); } @@ -665,11 +658,15 @@ winrt::fire_and_forget AppHost::_WindowActivated() void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { -#if TIL_FEATURE_TRAYICON_ENABLED - // TODO: Check if there's a quake window _somewhere_. If there is, - // we'll need to show our tray icon regardless of settings. + _setupGlobalHotkeys(); + + // The monarch is just going to be THE listener for inbound connections. + _listenForInboundConnections(); - if (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray()) +#if TIL_FEATURE_TRAYICON_ENABLED + if (_windowManager.DoesQuakeWindowExist() || + _window->IsQuakeWindow() || + (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray())) { _CreateTrayIcon(); } @@ -678,11 +675,6 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s _windowManager.ShowTrayIconRequested([this](auto&&, auto&&) { _ShowTrayIconRequested(); }); _windowManager.HideTrayIconRequested([this](auto&&, auto&&) { _HideTrayIconRequested(); }); #endif - - _setupGlobalHotkeys(); - - // The monarch is just going to be THE listener for inbound connections. - _listenForInboundConnections(); } void AppHost::_listenForInboundConnections() @@ -968,14 +960,17 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta // any hidden windows. if (_windowManager.IsMonarch()) { - if (!_trayIcon && (_logic.GetMinimizeToTray() || _logic.GetAlwaysShowTrayIcon())) + if (!_windowManager.DoesQuakeWindowExist()) { - _CreateTrayIcon(); - } - else if (_trayIcon && !_logic.GetMinimizeToTray() && !_logic.GetAlwaysShowTrayIcon()) - { - _windowManager.SummonAllWindows(); - _DestroyTrayIcon(); + if (!_trayIcon && (_logic.GetMinimizeToTray() || _logic.GetAlwaysShowTrayIcon())) + { + _CreateTrayIcon(); + } + else if (_trayIcon && !_logic.GetMinimizeToTray() && !_logic.GetAlwaysShowTrayIcon()) + { + _windowManager.SummonAllWindows(); + _DestroyTrayIcon(); + } } } @@ -986,23 +981,23 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { - _window->IsQuakeWindow(_logic.IsQuakeWindow()); - #if TIL_FEATURE_TRAYICON_ENABLED // We want the quake window to be accessible through the tray icon. // This means if there's a quake window _somewhere_, we want the tray icon // to show regardless of the tray icon settings. // This also means we'll need to destroy the tray icon if it was created // specifically for the quake window. If not, it should not be destroyed. - if (_window->IsQuakeWindow()) + if (!_window->IsQuakeWindow() && _logic.IsQuakeWindow()) { _ShowTrayIconRequested(); } - else + else if (_window->IsQuakeWindow() && !_logic.IsQuakeWindow()) { _HideTrayIconRequested(); } #endif + + _window->IsQuakeWindow(_logic.IsQuakeWindow()); } void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender, From 67e017cf3893a5880347d5d1d794879823302370 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 19 Jul 2021 14:39:45 -0700 Subject: [PATCH 49/57] formatting --- src/cascadia/Remoting/WindowManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index effc5953a03..e345df368a4 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -256,8 +256,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation _monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested }); #if TIL_FEATURE_TRAYICON_ENABLED - _monarch.ShowTrayIconRequested([this](auto&&, auto&&){ _ShowTrayIconRequestedHandlers(*this, nullptr); }); - _monarch.HideTrayIconRequested([this](auto&&, auto&&){ _HideTrayIconRequestedHandlers(*this, nullptr); }); + _monarch.ShowTrayIconRequested([this](auto&&, auto&&) { _ShowTrayIconRequestedHandlers(*this, nullptr); }); + _monarch.HideTrayIconRequested([this](auto&&, auto&&) { _HideTrayIconRequestedHandlers(*this, nullptr); }); #endif _BecameMonarchHandlers(*this, nullptr); From 570955bd1ade8e39418e4ce50861818c4886623e Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 19 Jul 2021 15:27:05 -0700 Subject: [PATCH 50/57] test oopsies --- src/cascadia/UnitTests_Remoting/RemotingTests.cpp | 15 +++++++++++++++ src/cascadia/WindowsTerminal/AppHost.cpp | 6 ++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp index 708653d0172..c06574660e3 100644 --- a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp +++ b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp @@ -71,12 +71,27 @@ namespace RemotingUnitTests Remoting::WindowActivatedArgs GetLastActivatedArgs() { throw winrt::hresult_error{}; } void RequestRename(const Remoting::RenameRequestArgs& /*args*/) { throw winrt::hresult_error{}; } void Summon(const Remoting::SummonWindowBehavior& /*args*/) { throw winrt::hresult_error{}; }; +#if TIL_FEATURE_TRAYICON_ENABLED + void RequestShowTrayIcon() + { + throw winrt::hresult_error{}; + }; + void RequestHideTrayIcon() + { + throw winrt::hresult_error{}; + } +#endif TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, Remoting::WindowActivatedArgs); TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, Remoting::CommandlineArgs); TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, Remoting::RenameRequestArgs); TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, Remoting::SummonWindowBehavior); + +#if TIL_FEATURE_TRAYICON_ENABLED + TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); +#endif }; class RemotingTests diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 120aa4bdc9c..791d2c85b18 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -952,8 +952,10 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta _setupGlobalHotkeys(); #if TIL_FEATURE_TRAYICON_ENABLED - // If we're monarch, we need to check two particular settings for - // the tray icon - MinimizeToTray and AlwaysShowTrayIcon. If either + // If we're monarch, we need to check some conditions to show the tray icon. + // If there's a Quake window somewhere, we'll want to keep the tray icon. + // Then there's also two particular settings for the tray icon - + // MinimizeToTray and AlwaysShowTrayIcon. If either // one of them are true, we want to make sure there's a tray icon. // If both are false, we want to remove our icon from the tray (if we had one). // When we remove our icon from the tray, we'll also want to re-summon From d827e6b8de16c7f65fbfb43b39e24be0bdd2efeb Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 21 Jul 2021 12:29:32 -0700 Subject: [PATCH 51/57] cleaning up so eyes don't bleed --- src/cascadia/Remoting/Peasant.cpp | 2 -- src/cascadia/Remoting/Peasant.h | 6 ---- src/cascadia/Remoting/Peasant.idl | 2 -- src/cascadia/Remoting/WindowManager.cpp | 7 ++--- src/cascadia/Remoting/WindowManager.h | 5 ---- .../TerminalApp/AppActionHandlers.cpp | 1 - src/cascadia/TerminalApp/AppLogic.cpp | 8 +++++ .../Resources/en-US/Resources.resw | 3 -- .../UnitTests_Remoting/RemotingTests.cpp | 15 ++-------- src/cascadia/WindowsTerminal/AppHost.cpp | 29 +++++++------------ src/cascadia/WindowsTerminal/AppHost.h | 6 ---- src/cascadia/WindowsTerminal/IslandWindow.cpp | 11 ------- src/cascadia/WindowsTerminal/IslandWindow.h | 7 ----- src/cascadia/WindowsTerminal/main.cpp | 6 ++++ 14 files changed, 29 insertions(+), 79 deletions(-) diff --git a/src/cascadia/Remoting/Peasant.cpp b/src/cascadia/Remoting/Peasant.cpp index 124bd9a6ec0..a9787f59733 100644 --- a/src/cascadia/Remoting/Peasant.cpp +++ b/src/cascadia/Remoting/Peasant.cpp @@ -226,7 +226,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TraceLoggingKeyword(TIL_KEYWORD_TRACE)); } -#if TIL_FEATURE_TRAYICON_ENABLED void Peasant::RequestShowTrayIcon() { try @@ -258,5 +257,4 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), TraceLoggingKeyword(TIL_KEYWORD_TRACE)); } -#endif } diff --git a/src/cascadia/Remoting/Peasant.h b/src/cascadia/Remoting/Peasant.h index e5e920699ed..b7a0483aec6 100644 --- a/src/cascadia/Remoting/Peasant.h +++ b/src/cascadia/Remoting/Peasant.h @@ -29,11 +29,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void RequestIdentifyWindows(); void DisplayWindowId(); void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args); - -#if TIL_FEATURE_TRAYICON_ENABLED void RequestShowTrayIcon(); void RequestHideTrayIcon(); -#endif winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs GetLastActivatedArgs(); @@ -46,11 +43,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs); TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior); - -#if TIL_FEATURE_TRAYICON_ENABLED TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); -#endif private: uint64_t _ourPID; diff --git a/src/cascadia/Remoting/Peasant.idl b/src/cascadia/Remoting/Peasant.idl index 8dd6ded3461..454d748cf4e 100644 --- a/src/cascadia/Remoting/Peasant.idl +++ b/src/cascadia/Remoting/Peasant.idl @@ -64,7 +64,6 @@ namespace Microsoft.Terminal.Remoting void RequestIdentifyWindows(); // Tells us to raise a IdentifyWindowsRequested void RequestRename(RenameRequestArgs args); // Tells us to raise a RenameRequested void Summon(SummonWindowBehavior behavior); - void RequestShowTrayIcon(); void RequestHideTrayIcon(); @@ -74,7 +73,6 @@ namespace Microsoft.Terminal.Remoting event Windows.Foundation.TypedEventHandler DisplayWindowIdRequested; event Windows.Foundation.TypedEventHandler RenameRequested; event Windows.Foundation.TypedEventHandler SummonRequested; - event Windows.Foundation.TypedEventHandler ShowTrayIconRequested; event Windows.Foundation.TypedEventHandler HideTrayIconRequested; }; diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index e345df368a4..87d42d71d9e 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -254,11 +254,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation // window, and when the current monarch dies. _monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested }); - -#if TIL_FEATURE_TRAYICON_ENABLED _monarch.ShowTrayIconRequested([this](auto&&, auto&&) { _ShowTrayIconRequestedHandlers(*this, nullptr); }); _monarch.HideTrayIconRequested([this](auto&&, auto&&) { _HideTrayIconRequestedHandlers(*this, nullptr); }); -#endif _BecameMonarchHandlers(*this, nullptr); } @@ -516,7 +513,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void WindowManager::SummonAllWindows() { +#if TIL_FEATURE_TRAYICON_ENABLED _monarch.SummonAllWindows(); +#endif } Windows::Foundation::Collections::IMapView WindowManager::GetPeasantNames() @@ -526,7 +525,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation return _monarch.GetPeasantNames(); } -#if TIL_FEATURE_TRAYICON_ENABLED // These should only be called if we're a Peasant. void WindowManager::RequestShowTrayIcon() { @@ -550,6 +548,5 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation } return false; } -#endif } diff --git a/src/cascadia/Remoting/WindowManager.h b/src/cascadia/Remoting/WindowManager.h index cf8b51dc439..8169f37379b 100644 --- a/src/cascadia/Remoting/WindowManager.h +++ b/src/cascadia/Remoting/WindowManager.h @@ -43,19 +43,14 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void SummonAllWindows(); Windows::Foundation::Collections::IMapView GetPeasantNames(); -#if TIL_FEATURE_TRAYICON_ENABLED void RequestShowTrayIcon(); void RequestHideTrayIcon(); bool DoesQuakeWindowExist(); -#endif TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs); TYPED_EVENT(BecameMonarch, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); - -#if TIL_FEATURE_TRAYICON_ENABLED TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); -#endif private: bool _shouldCreateWindow{ false }; diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 4667142fe8c..40b05c6edc7 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -843,7 +843,6 @@ namespace winrt::TerminalApp::implementation _MinimizeToTrayRequestedHandlers(*this, nullptr); } #endif - args.Handled(true); } } diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index c45ec87227f..d0bf66490d9 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1452,6 +1452,7 @@ namespace winrt::TerminalApp::implementation bool AppLogic::GetMinimizeToTray() { +#if TIL_FEATURE_TRAYICON_ENABLED if (!_loadedInitialSettings) { // Load settings if we haven't already @@ -1459,10 +1460,14 @@ namespace winrt::TerminalApp::implementation } return _settings.GlobalSettings().MinimizeToTray(); +#else + return false; +#endif } bool AppLogic::GetAlwaysShowTrayIcon() { +#if TIL_FEATURE_TRAYICON_ENABLED if (!_loadedInitialSettings) { // Load settings if we haven't already @@ -1470,5 +1475,8 @@ namespace winrt::TerminalApp::implementation } return _settings.GlobalSettings().AlwaysShowTrayIcon(); +#else + return false; +#endif } } diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 13c7aa3b6ef..67335d37ab0 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -637,9 +637,6 @@ Command Palette - - Windows Terminal - Focus Terminal This is displayed as a label for the context menu item that focuses the terminal. diff --git a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp index c06574660e3..8c6de41ca00 100644 --- a/src/cascadia/UnitTests_Remoting/RemotingTests.cpp +++ b/src/cascadia/UnitTests_Remoting/RemotingTests.cpp @@ -71,27 +71,16 @@ namespace RemotingUnitTests Remoting::WindowActivatedArgs GetLastActivatedArgs() { throw winrt::hresult_error{}; } void RequestRename(const Remoting::RenameRequestArgs& /*args*/) { throw winrt::hresult_error{}; } void Summon(const Remoting::SummonWindowBehavior& /*args*/) { throw winrt::hresult_error{}; }; -#if TIL_FEATURE_TRAYICON_ENABLED - void RequestShowTrayIcon() - { - throw winrt::hresult_error{}; - }; - void RequestHideTrayIcon() - { - throw winrt::hresult_error{}; - } -#endif + void RequestShowTrayIcon() { throw winrt::hresult_error{}; }; + void RequestHideTrayIcon() { throw winrt::hresult_error{}; }; TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, Remoting::WindowActivatedArgs); TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, Remoting::CommandlineArgs); TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, Remoting::RenameRequestArgs); TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, Remoting::SummonWindowBehavior); - -#if TIL_FEATURE_TRAYICON_ENABLED TYPED_EVENT(ShowTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); -#endif }; class RemotingTests diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 791d2c85b18..800dbeaae7b 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -65,9 +65,7 @@ AppHost::AppHost() noexcept : // Update our own internal state tracking if we're in quake mode or not. _IsQuakeWindowChanged(nullptr, nullptr); -#if TIL_FEATURE_TRAYICON_ENABLED _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); -#endif // Tell the window to callback to us when it's about to handle a WM_CREATE auto pfn = std::bind(&AppHost::_HandleCreateWindow, @@ -96,12 +94,10 @@ AppHost::AppHost() noexcept : AppHost::~AppHost() { -#if TIL_FEATURE_TRAYICON_ENABLED if (_window->IsQuakeWindow()) { _windowManager.RequestHideTrayIcon(); } -#endif // destruction order is important for proper teardown here _window = nullptr; @@ -280,10 +276,7 @@ void AppHost::Initialize() _logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged }); _logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged }); _logic.SummonWindowRequested({ this, &AppHost::_SummonWindowRequested }); - -#if TIL_FEATURE_TRAYICON_ENABLED _logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested }); -#endif _window->UpdateTitle(_logic.Title()); @@ -663,7 +656,6 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s // The monarch is just going to be THE listener for inbound connections. _listenForInboundConnections(); -#if TIL_FEATURE_TRAYICON_ENABLED if (_windowManager.DoesQuakeWindowExist() || _window->IsQuakeWindow() || (_logic.GetAlwaysShowTrayIcon() || _logic.GetMinimizeToTray())) @@ -674,7 +666,6 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s // These events are coming from peasants that become or un-become quake windows. _windowManager.ShowTrayIconRequested([this](auto&&, auto&&) { _ShowTrayIconRequested(); }); _windowManager.HideTrayIconRequested([this](auto&&, auto&&) { _HideTrayIconRequested(); }); -#endif } void AppHost::_listenForInboundConnections() @@ -951,15 +942,14 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta { _setupGlobalHotkeys(); -#if TIL_FEATURE_TRAYICON_ENABLED // If we're monarch, we need to check some conditions to show the tray icon. // If there's a Quake window somewhere, we'll want to keep the tray icon. - // Then there's also two particular settings for the tray icon - - // MinimizeToTray and AlwaysShowTrayIcon. If either + // Then there's also two settings - MinimizeToTray and AlwaysShowTrayIcon. If either // one of them are true, we want to make sure there's a tray icon. // If both are false, we want to remove our icon from the tray (if we had one). // When we remove our icon from the tray, we'll also want to re-summon - // any hidden windows. + // any hidden windows, but right now we're not keeping track of who's hidden, + // so just summon them all. if (_windowManager.IsMonarch()) { if (!_windowManager.DoesQuakeWindowExist()) @@ -977,13 +967,11 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta } _window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray()); -#endif } void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { -#if TIL_FEATURE_TRAYICON_ENABLED // We want the quake window to be accessible through the tray icon. // This means if there's a quake window _somewhere_, we want the tray icon // to show regardless of the tray icon settings. @@ -997,7 +985,6 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab { _HideTrayIconRequested(); } -#endif _window->IsQuakeWindow(_logic.IsQuakeWindow()); } @@ -1013,7 +1000,6 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta _HandleSummon(sender, summonArgs); } -#if TIL_FEATURE_TRAYICON_ENABLED void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&) { @@ -1028,6 +1014,7 @@ void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspec // - void AppHost::_CreateTrayIcon() { +#if TIL_FEATURE_TRAYICON_ENABLED _trayIcon = std::make_unique(_window->GetHandle()); // Hookup the handlers, save the tokens for revoking if settings change. @@ -1036,6 +1023,7 @@ void AppHost::_CreateTrayIcon() _ShowTrayContextMenuToken = _window->NotifyShowTrayContextMenu([this](til::point coord) { _trayIcon->ShowTrayContextMenu(coord, _windowManager.GetPeasantNames()); }); _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU hm, UINT idx) { _trayIcon->TrayMenuItemSelected(hm, idx); }); _trayIcon->SummonWindowRequested([this](auto& args) { _windowManager.SummonWindow(args); }); +#endif } // Method Description: @@ -1046,6 +1034,7 @@ void AppHost::_CreateTrayIcon() // - void AppHost::_DestroyTrayIcon() { +#if TIL_FEATURE_TRAYICON_ENABLED _window->NotifyReAddTrayIcon(_ReAddTrayIconToken); _window->NotifyTrayIconPressed(_TrayIconPressedToken); _window->NotifyShowTrayContextMenu(_ShowTrayContextMenuToken); @@ -1053,10 +1042,12 @@ void AppHost::_DestroyTrayIcon() _trayIcon->DestroyTrayIcon(); _trayIcon = nullptr; +#endif } void AppHost::_ShowTrayIconRequested() { +#if TIL_FEATURE_TRAYICON_ENABLED if (_windowManager.IsMonarch()) { if (!_trayIcon) @@ -1069,10 +1060,12 @@ void AppHost::_ShowTrayIconRequested() // TODO: Tell WindowManager to notify Monarch to show icon. _windowManager.RequestShowTrayIcon(); } +#endif } void AppHost::_HideTrayIconRequested() { +#if TIL_FEATURE_TRAYICON_ENABLED if (_windowManager.IsMonarch()) { // Destroy it only if our settings allow it @@ -1088,5 +1081,5 @@ void AppHost::_HideTrayIconRequested() // TODO: Tell WindowManager to notify Monarch to hide the icon. _windowManager.RequestHideTrayIcon(); } -} #endif +} diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index f5cb05dae67..ec7e8e32af3 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -2,12 +2,8 @@ // Licensed under the MIT license. #include "pch.h" - #include "NonClientIslandWindow.h" - -#if TIL_FEATURE_TRAYICON_ENABLED #include "TrayIcon.h" -#endif class AppHost { @@ -90,7 +86,6 @@ class AppHost void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); -#if TIL_FEATURE_TRAYICON_ENABLED void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable&); @@ -103,5 +98,4 @@ class AppHost winrt::event_token _TrayIconPressedToken; winrt::event_token _ShowTrayContextMenuToken; winrt::event_token _TrayMenuItemSelectedToken; -#endif }; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 5c48ae04078..8749f9bdcc4 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -6,10 +6,7 @@ #include "../types/inc/Viewport.hpp" #include "resource.h" #include "icon.h" - -#if TIL_FEATURE_TRAYICON_ENABLED #include "TrayIcon.h" -#endif extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -513,7 +510,6 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize case WM_THEMECHANGED: UpdateWindowIconForActiveMetrics(_window.get()); return 0; -#if TIL_FEATURE_TRAYICON_ENABLED case CM_NOTIFY_FROM_TRAY: { switch (LOWORD(lparam)) @@ -538,10 +534,8 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize _NotifyTrayMenuItemSelectedHandlers((HMENU)lparam, (UINT)wparam); return 0; } -#endif } -#if TIL_FEATURE_TRAYICON_ENABLED // We'll want to receive this message when explorer.exe restarts // so that we can re-add our icon to the tray. if (message == WM_TASKBARCREATED) @@ -549,7 +543,6 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize _NotifyReAddTrayIconHandlers(); return 0; } -#endif // TODO: handle messages here... return base_type::MessageHandler(message, wparam, lparam); @@ -573,12 +566,10 @@ void IslandWindow::OnResize(const UINT width, const UINT height) void IslandWindow::OnMinimize() { // TODO GH#1989 Stop rendering island content when the app is minimized. -#if TIL_FEATURE_TRAYICON_ENABLED if (_minimizeToTray) { HideWindow(); } -#endif } // Method Description: @@ -1513,12 +1504,10 @@ void IslandWindow::HideWindow() ShowWindow(GetHandle(), SW_HIDE); } -#if TIL_FEATURE_TRAYICON_ENABLED void IslandWindow::SetMinimizeToTrayBehavior(bool minimizeToTray) noexcept { _minimizeToTray = minimizeToTray; } -#endif DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DEFINE_EVENT(IslandWindow, WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index d119ad4d6cd..e80d7c2f68c 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -48,22 +48,17 @@ class IslandWindow : void HideWindow(); -#if TIL_FEATURE_TRAYICON_ENABLED void SetMinimizeToTrayBehavior(bool minimizeToTray) noexcept; -#endif DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); WINRT_CALLBACK(MouseScrolled, winrt::delegate); WINRT_CALLBACK(WindowActivated, winrt::delegate); WINRT_CALLBACK(HotkeyPressed, winrt::delegate); - -#if TIL_FEATURE_TRAYICON_ENABLED WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate); WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate); WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate); WINRT_CALLBACK(NotifyReAddTrayIcon, winrt::delegate); -#endif protected: void ForceResize() @@ -126,9 +121,7 @@ class IslandWindow : void _summonWindowRoutineBody(winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior args); -#if TIL_FEATURE_TRAYICON_ENABLED bool _minimizeToTray{ false }; -#endif private: // This minimum width allows for width the tabs fit diff --git a/src/cascadia/WindowsTerminal/main.cpp b/src/cascadia/WindowsTerminal/main.cpp index da212a04fae..1a4d0d1b4d8 100644 --- a/src/cascadia/WindowsTerminal/main.cpp +++ b/src/cascadia/WindowsTerminal/main.cpp @@ -22,6 +22,12 @@ TRACELOGGING_DEFINE_PROVIDER( (0x56c06166, 0x2e2e, 0x5f4d, 0x7f, 0xf3, 0x74, 0xf4, 0xb7, 0x8c, 0x87, 0xd6), TraceLoggingOptionMicrosoftTelemetry()); +// !! BODGY !! +// Manually use the resources from TerminalApp as our resources. +// The WindowsTerminal project doesn't actually build a Resources.resw file, but +// we still need to be able to localize strings for the tray icon menu. Anything +// you want localized for WindowsTerminal.exe should be stuck in +// ...\TerminalApp\Resources\en-US\Resources.resw #include UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources"); From bc62fef401c8d10a81f249300966580941277d7f Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 22 Jul 2021 08:07:11 -0700 Subject: [PATCH 52/57] a bit of cleanup --- src/cascadia/Remoting/Monarch.cpp | 15 +++++++++++---- src/cascadia/Remoting/Peasant.h | 2 +- src/cascadia/Remoting/WindowManager.cpp | 13 ++++++++++++- src/cascadia/WindowsTerminal/AppHost.cpp | 4 ---- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/cascadia/Remoting/Monarch.cpp b/src/cascadia/Remoting/Monarch.cpp index 48bb23c2b8c..1507c196c2a 100644 --- a/src/cascadia/Remoting/Monarch.cpp +++ b/src/cascadia/Remoting/Monarch.cpp @@ -815,11 +815,18 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void Monarch::SummonAllWindows() { - for (const auto [id, peasant] : _peasants) - { + auto callback = [](auto&& p, auto&& /*id*/) { SummonWindowBehavior args{}; args.ToggleVisibility(false); - peasant.Summon(args); - } + p.Summon(args); + }; + auto onError = [](auto&& id) { + TraceLoggingWrite(g_hRemotingProvider, + "Monarch_SummonAll_Failed", + TraceLoggingInt64(id, "peasantID", "The ID of the peasant which we could not summon"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + }; + _forAllPeasantsIgnoringTheDead(callback, onError); } } diff --git a/src/cascadia/Remoting/Peasant.h b/src/cascadia/Remoting/Peasant.h index b7a0483aec6..6093cd835c0 100644 --- a/src/cascadia/Remoting/Peasant.h +++ b/src/cascadia/Remoting/Peasant.h @@ -16,7 +16,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation struct Peasant : public PeasantT { Peasant(); - Peasant(const uint64_t testPID); void AssignID(uint64_t id); uint64_t GetID(); @@ -47,6 +46,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation TYPED_EVENT(HideTrayIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); private: + Peasant(const uint64_t testPID); uint64_t _ourPID; uint64_t _id{ 0 }; diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index 87d42d71d9e..37d184861ed 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -525,12 +525,23 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation return _monarch.GetPeasantNames(); } - // These should only be called if we're a Peasant. + // Method Description: + // - Ask the monarch to show a tray icon. + // Arguments: + // - + // Return Value: + // - void WindowManager::RequestShowTrayIcon() { _peasant.RequestShowTrayIcon(); } + // Method Description: + // - Ask the monarch to hide its tray icon. + // Arguments: + // - + // Return Value: + // - void WindowManager::RequestHideTrayIcon() { _peasant.RequestHideTrayIcon(); diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 800dbeaae7b..a0b14b9c823 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -11,8 +11,6 @@ #include "VirtualDesktopUtils.h" #include "icon.h" -#include - using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Composition; using namespace winrt::Windows::UI::Xaml; @@ -1057,7 +1055,6 @@ void AppHost::_ShowTrayIconRequested() } else { - // TODO: Tell WindowManager to notify Monarch to show icon. _windowManager.RequestShowTrayIcon(); } #endif @@ -1078,7 +1075,6 @@ void AppHost::_HideTrayIconRequested() } else { - // TODO: Tell WindowManager to notify Monarch to hide the icon. _windowManager.RequestHideTrayIcon(); } #endif From af2ee794813d4b6ae6ce189110d1bc3c91fa6e0a Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 5 Aug 2021 14:50:46 -0700 Subject: [PATCH 53/57] smalls --- src/cascadia/WindowsTerminal/TrayIcon.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 4c4e59f4cde..8b54924dffe 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -73,7 +73,7 @@ void TrayIcon::CreateTrayIcon() void TrayIcon::ShowTrayContextMenu(const til::point coord, IMapView peasants) { - if (auto hmenu = _CreateTrayContextMenu(peasants)) + if (const auto hMenu = _CreateTrayContextMenu(peasants)) { // We'll need to set our window to the foreground before calling // TrackPopupMenuEx or else the menu won't dismiss when clicking away. @@ -93,7 +93,7 @@ void TrayIcon::ShowTrayContextMenu(const til::point coord, uFlags |= TPM_LEFTALIGN; } - TrackPopupMenuEx(hmenu, uFlags, gsl::narrow(coord.x()), gsl::narrow(coord.y()), _owningHwnd, NULL); + TrackPopupMenuEx(hMenu, uFlags, gsl::narrow(coord.x()), gsl::narrow(coord.y()), _owningHwnd, NULL); } } @@ -105,19 +105,19 @@ void TrayIcon::ShowTrayContextMenu(const til::point coord, // - The handle to the newly created context menu. HMENU TrayIcon::_CreateTrayContextMenu(IMapView peasants) { - auto hmenu = CreatePopupMenu(); - if (hmenu) + auto hMenu = CreatePopupMenu(); + if (hMenu) { MENUINFO mi{}; mi.cbSize = sizeof(MENUINFO); mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS | MIM_MENUDATA; mi.dwStyle = MNS_NOTIFYBYPOS; mi.dwMenuData = NULL; - SetMenuInfo(hmenu, &mi); + SetMenuInfo(hMenu, &mi); // Focus Current Terminal Window - AppendMenu(hmenu, MF_STRING, gsl::narrow(TrayMenuItemAction::FocusTerminal), RS_(L"TrayIconFocusTerminal").c_str()); - AppendMenu(hmenu, MF_SEPARATOR, 0, L""); + AppendMenu(hMenu, MF_STRING, gsl::narrow(TrayMenuItemAction::FocusTerminal), RS_(L"TrayIconFocusTerminal").c_str()); + AppendMenu(hMenu, MF_SEPARATOR, 0, L""); // Submenu for Windows if (auto submenu = CreatePopupMenu()) @@ -142,10 +142,10 @@ HMENU TrayIcon::_CreateTrayContextMenu(IMapView peasan submenuInfo.dwMenuData = (UINT_PTR)TrayMenuItemAction::SummonWindow; SetMenuInfo(submenu, &submenuInfo); - AppendMenu(hmenu, MF_POPUP, (UINT_PTR)submenu, RS_(L"TrayIconWindowSubmenu").c_str()); + AppendMenu(hMenu, MF_POPUP, (UINT_PTR)submenu, RS_(L"TrayIconWindowSubmenu").c_str()); } } - return hmenu; + return hMenu; } // Method Description: From a90d2ec377e4c0af5227ac2dc860ccdc79fc686c Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 6 Aug 2021 09:45:05 -0700 Subject: [PATCH 54/57] other smalls --- src/cascadia/TerminalApp/AppActionHandlers.cpp | 12 ------------ src/cascadia/TerminalApp/AppLogic.h | 1 - src/cascadia/TerminalApp/AppLogic.idl | 1 - src/cascadia/TerminalApp/TerminalPage.h | 1 - src/cascadia/TerminalApp/TerminalPage.idl | 1 - src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp | 2 -- .../TerminalSettingsModel/AllShortcutActions.h | 3 +-- src/cascadia/WindowsTerminal/AppHost.cpp | 7 ------- src/cascadia/WindowsTerminal/AppHost.h | 3 --- 9 files changed, 1 insertion(+), 30 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 40b05c6edc7..cdc92aaf6ae 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -833,16 +833,4 @@ namespace winrt::TerminalApp::implementation } } } - - void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/, - const ActionEventArgs& args) - { -#if TIL_FEATURE_TRAYICON_ENABLED - if (_settings.GlobalSettings().MinimizeToTray() || _settings.GlobalSettings().AlwaysShowTrayIcon()) - { - _MinimizeToTrayRequestedHandlers(*this, nullptr); - } -#endif - args.Handled(true); - } } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 4880c908e56..4e4ae636af5 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -166,7 +166,6 @@ namespace winrt::TerminalApp::implementation FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested); FORWARDED_TYPED_EVENT(IsQuakeWindowChanged, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IsQuakeWindowChanged); FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested); - FORWARDED_TYPED_EVENT(MinimizeToTrayRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, MinimizeToTrayRequested); #ifdef UNIT_TESTING friend class TerminalAppLocalTests::CommandlineTest; diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 0b935aa5371..46f10e9975f 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -96,6 +96,5 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler SettingsChanged; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; event Windows.Foundation.TypedEventHandler SummonWindowRequested; - event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 0ca9b7bb7c2..414c233fdec 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -123,7 +123,6 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); TYPED_EVENT(SummonWindowRequested, IInspectable, IInspectable); - TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable); private: friend struct TerminalPageT; // for Xaml to bind events diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 79d23adb7b9..0d055782268 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -57,6 +57,5 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler RenameWindowRequested; event Windows.Foundation.TypedEventHandler IsQuakeWindowChanged; event Windows.Foundation.TypedEventHandler SummonWindowRequested; - event Windows.Foundation.TypedEventHandler MinimizeToTrayRequested; } } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index 8e6fa89a428..430980a6c95 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -62,7 +62,6 @@ static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" }; static constexpr std::string_view GlobalSummonKey{ "globalSummon" }; static constexpr std::string_view QuakeModeKey{ "quakeMode" }; static constexpr std::string_view FocusPaneKey{ "focusPane" }; -static constexpr std::string_view MinimizeToTrayKey{ "minimizeToTray" }; static constexpr std::string_view ActionKey{ "action" }; @@ -361,7 +360,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") }, { ShortcutAction::FocusPane, L"" }, // Intentionally omitted, must be generated by GenerateName - { ShortcutAction::MinimizeToTray, RS_(L"MinimizeToTrayCommandKey") }, }; }(); diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index 48a024aba8e..cc3559037ba 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -75,8 +75,7 @@ ON_ALL_ACTIONS(OpenWindowRenamer) \ ON_ALL_ACTIONS(GlobalSummon) \ ON_ALL_ACTIONS(QuakeMode) \ - ON_ALL_ACTIONS(FocusPane) \ - ON_ALL_ACTIONS(MinimizeToTray) + ON_ALL_ACTIONS(FocusPane) #define ALL_SHORTCUT_ACTIONS_WITH_ARGS \ ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \ diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index a0b14b9c823..5cc3080bf4c 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -274,7 +274,6 @@ void AppHost::Initialize() _logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged }); _logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged }); _logic.SummonWindowRequested({ this, &AppHost::_SummonWindowRequested }); - _logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested }); _window->UpdateTitle(_logic.Title()); @@ -998,12 +997,6 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta _HandleSummon(sender, summonArgs); } -void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable&, - const winrt::Windows::Foundation::IInspectable&) -{ - _window->HideWindow(); -} - // Method Description: // - Creates a Tray Icon and hooks up its handlers // Arguments: diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index ec7e8e32af3..b3d97ebaa2d 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -86,9 +86,6 @@ class AppHost void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); - void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender, - const winrt::Windows::Foundation::IInspectable&); - void _CreateTrayIcon(); void _DestroyTrayIcon(); void _ShowTrayIconRequested(); From ac8513e2e6b875ee06b2b5ec6b520581cc3a5013 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Mon, 9 Aug 2021 12:56:32 -0700 Subject: [PATCH 55/57] rename from destroy tray icon to remove, put the if statement in default because I think it looks nicer --- src/cascadia/WindowsTerminal/AppHost.cpp | 2 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 18 ++++++++++-------- src/cascadia/WindowsTerminal/TrayIcon.cpp | 4 ++-- src/cascadia/WindowsTerminal/TrayIcon.h | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 02880989d13..5aca833485e 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1032,7 +1032,7 @@ void AppHost::_DestroyTrayIcon() _window->NotifyShowTrayContextMenu(_ShowTrayContextMenuToken); _window->NotifyTrayMenuItemSelected(_TrayMenuItemSelectedToken); - _trayIcon->DestroyTrayIcon(); + _trayIcon->RemoveIconFromTray(); _trayIcon = nullptr; #endif } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index d6e67e06fb0..a601d4a6bc8 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -589,14 +589,16 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize _NotifyTrayMenuItemSelectedHandlers((HMENU)lparam, (UINT)wparam); return 0; } - } - - // We'll want to receive this message when explorer.exe restarts - // so that we can re-add our icon to the tray. - if (message == WM_TASKBARCREATED) - { - _NotifyReAddTrayIconHandlers(); - return 0; + default: + // We'll want to receive this message when explorer.exe restarts + // so that we can re-add our icon to the tray. + // This unfortunately isn't a switch case because we register the + // message at runtime. + if (message == WM_TASKBARCREATED) + { + _NotifyReAddTrayIconHandlers(); + return 0; + } } // TODO: handle messages here... diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 8b54924dffe..d2fcf426677 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -16,7 +16,7 @@ TrayIcon::TrayIcon(const HWND owningHwnd) : TrayIcon::~TrayIcon() { - DestroyTrayIcon(); + RemoveIconFromTray(); } // Method Description: @@ -221,7 +221,7 @@ void TrayIcon::ReAddTrayIcon() // - // Return Value: // - -void TrayIcon::DestroyTrayIcon() +void TrayIcon::RemoveIconFromTray() { Shell_NotifyIcon(NIM_DELETE, &_trayIconData); } diff --git a/src/cascadia/WindowsTerminal/TrayIcon.h b/src/cascadia/WindowsTerminal/TrayIcon.h index 61833cfd774..aa58d17f16d 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.h +++ b/src/cascadia/WindowsTerminal/TrayIcon.h @@ -20,7 +20,7 @@ class TrayIcon ~TrayIcon(); void CreateTrayIcon(); - void DestroyTrayIcon(); + void RemoveIconFromTray(); void ReAddTrayIcon(); void TrayIconPressed(); From 1c731a159514ff0dd5c261a74293c92a28f77ee0 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 10 Aug 2021 14:15:23 -0700 Subject: [PATCH 56/57] move the windows to whence they came --- src/cascadia/WindowsTerminal/TrayIcon.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index d2fcf426677..32ff9c64699 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -7,6 +7,7 @@ #include using namespace winrt::Windows::Foundation::Collections; +using namespace winrt::Microsoft::Terminal; TrayIcon::TrayIcon(const HWND owningHwnd) : _owningHwnd{ owningHwnd } @@ -170,6 +171,8 @@ void TrayIcon::TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) winrt::Microsoft::Terminal::Remoting::SummonWindowSelectionArgs args{}; args.WindowID(GetMenuItemID(menu, menuItemIndex)); args.SummonBehavior().ToggleVisibility(false); + args.SummonBehavior().MoveToCurrentDesktop(false); + args.SummonBehavior().ToMonitor(Remoting::MonitorBehavior::InPlace); _SummonWindowRequestedHandlers(args); return; } @@ -183,6 +186,8 @@ void TrayIcon::TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex) { winrt::Microsoft::Terminal::Remoting::SummonWindowSelectionArgs args{}; args.SummonBehavior().ToggleVisibility(false); + args.SummonBehavior().MoveToCurrentDesktop(false); + args.SummonBehavior().ToMonitor(Remoting::MonitorBehavior::InPlace); _SummonWindowRequestedHandlers(args); break; } @@ -199,6 +204,8 @@ void TrayIcon::TrayIconPressed() { // No name in the args means summon the mru window. winrt::Microsoft::Terminal::Remoting::SummonWindowSelectionArgs args{}; + args.SummonBehavior().MoveToCurrentDesktop(false); + args.SummonBehavior().ToMonitor(Remoting::MonitorBehavior::InPlace); args.SummonBehavior().ToggleVisibility(false); _SummonWindowRequestedHandlers(args); } From cbf08aa453a4f29d1ca41e6ae8409bbff45a4eb3 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 12 Aug 2021 12:28:21 -0700 Subject: [PATCH 57/57] use constexpr for feature flag, copyright header, narrow_cast --- doc/cascadia/profiles.schema.json | 1 - src/cascadia/Remoting/WindowManager.cpp | 7 +- src/cascadia/TerminalApp/AppLogic.cpp | 42 ++++++----- src/cascadia/WindowsTerminal/AppHost.cpp | 88 ++++++++++++----------- src/cascadia/WindowsTerminal/TrayIcon.cpp | 7 +- 5 files changed, 79 insertions(+), 66 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index b43810d0059..ebc306e4954 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -237,7 +237,6 @@ "globalSummon", "identifyWindow", "identifyWindows", - "minimizeToTray", "moveFocus", "movePane", "moveTab", diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index 37d184861ed..551bd093096 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -513,9 +513,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void WindowManager::SummonAllWindows() { -#if TIL_FEATURE_TRAYICON_ENABLED - _monarch.SummonAllWindows(); -#endif + if constexpr (Feature_TrayIcon::IsEnabled()) + { + _monarch.SummonAllWindows(); + } } Windows::Foundation::Collections::IMapView WindowManager::GetPeasantNames() diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 8af71d425c8..106da0fbdea 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1444,31 +1444,37 @@ namespace winrt::TerminalApp::implementation bool AppLogic::GetMinimizeToTray() { -#if TIL_FEATURE_TRAYICON_ENABLED - if (!_loadedInitialSettings) + if constexpr (Feature_TrayIcon::IsEnabled()) { - // Load settings if we haven't already - LoadSettings(); - } + if (!_loadedInitialSettings) + { + // Load settings if we haven't already + LoadSettings(); + } - return _settings.GlobalSettings().MinimizeToTray(); -#else - return false; -#endif + return _settings.GlobalSettings().MinimizeToTray(); + } + else + { + return false; + } } bool AppLogic::GetAlwaysShowTrayIcon() { -#if TIL_FEATURE_TRAYICON_ENABLED - if (!_loadedInitialSettings) + if constexpr (Feature_TrayIcon::IsEnabled()) { - // Load settings if we haven't already - LoadSettings(); - } + if (!_loadedInitialSettings) + { + // Load settings if we haven't already + LoadSettings(); + } - return _settings.GlobalSettings().AlwaysShowTrayIcon(); -#else - return false; -#endif + return _settings.GlobalSettings().AlwaysShowTrayIcon(); + } + else + { + return false; + } } } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 2f88988dfdf..356d1d5c4f7 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1022,16 +1022,17 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta // - void AppHost::_CreateTrayIcon() { -#if TIL_FEATURE_TRAYICON_ENABLED - _trayIcon = std::make_unique(_window->GetHandle()); - - // Hookup the handlers, save the tokens for revoking if settings change. - _ReAddTrayIconToken = _window->NotifyReAddTrayIcon([this]() { _trayIcon->ReAddTrayIcon(); }); - _TrayIconPressedToken = _window->NotifyTrayIconPressed([this]() { _trayIcon->TrayIconPressed(); }); - _ShowTrayContextMenuToken = _window->NotifyShowTrayContextMenu([this](til::point coord) { _trayIcon->ShowTrayContextMenu(coord, _windowManager.GetPeasantNames()); }); - _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU hm, UINT idx) { _trayIcon->TrayMenuItemSelected(hm, idx); }); - _trayIcon->SummonWindowRequested([this](auto& args) { _windowManager.SummonWindow(args); }); -#endif + if constexpr (Feature_TrayIcon::IsEnabled()) + { + _trayIcon = std::make_unique(_window->GetHandle()); + + // Hookup the handlers, save the tokens for revoking if settings change. + _ReAddTrayIconToken = _window->NotifyReAddTrayIcon([this]() { _trayIcon->ReAddTrayIcon(); }); + _TrayIconPressedToken = _window->NotifyTrayIconPressed([this]() { _trayIcon->TrayIconPressed(); }); + _ShowTrayContextMenuToken = _window->NotifyShowTrayContextMenu([this](til::point coord) { _trayIcon->ShowTrayContextMenu(coord, _windowManager.GetPeasantNames()); }); + _TrayMenuItemSelectedToken = _window->NotifyTrayMenuItemSelected([this](HMENU hm, UINT idx) { _trayIcon->TrayMenuItemSelected(hm, idx); }); + _trayIcon->SummonWindowRequested([this](auto& args) { _windowManager.SummonWindow(args); }); + } } // Method Description: @@ -1042,52 +1043,55 @@ void AppHost::_CreateTrayIcon() // - void AppHost::_DestroyTrayIcon() { -#if TIL_FEATURE_TRAYICON_ENABLED - _window->NotifyReAddTrayIcon(_ReAddTrayIconToken); - _window->NotifyTrayIconPressed(_TrayIconPressedToken); - _window->NotifyShowTrayContextMenu(_ShowTrayContextMenuToken); - _window->NotifyTrayMenuItemSelected(_TrayMenuItemSelectedToken); - - _trayIcon->RemoveIconFromTray(); - _trayIcon = nullptr; -#endif + if constexpr (Feature_TrayIcon::IsEnabled()) + { + _window->NotifyReAddTrayIcon(_ReAddTrayIconToken); + _window->NotifyTrayIconPressed(_TrayIconPressedToken); + _window->NotifyShowTrayContextMenu(_ShowTrayContextMenuToken); + _window->NotifyTrayMenuItemSelected(_TrayMenuItemSelectedToken); + + _trayIcon->RemoveIconFromTray(); + _trayIcon = nullptr; + } } winrt::fire_and_forget AppHost::_ShowTrayIconRequested() { -#if TIL_FEATURE_TRAYICON_ENABLED - co_await winrt::resume_background(); - if (_windowManager.IsMonarch()) + if constexpr (Feature_TrayIcon::IsEnabled()) { - if (!_trayIcon) + co_await winrt::resume_background(); + if (_windowManager.IsMonarch()) { - _CreateTrayIcon(); + if (!_trayIcon) + { + _CreateTrayIcon(); + } + } + else + { + _windowManager.RequestShowTrayIcon(); } } - else - { - _windowManager.RequestShowTrayIcon(); - } -#endif } winrt::fire_and_forget AppHost::_HideTrayIconRequested() { -#if TIL_FEATURE_TRAYICON_ENABLED - co_await winrt::resume_background(); - if (_windowManager.IsMonarch()) + if constexpr (Feature_TrayIcon::IsEnabled()) { - // Destroy it only if our settings allow it - if (_trayIcon && - !_logic.GetAlwaysShowTrayIcon() && - !_logic.GetMinimizeToTray()) + co_await winrt::resume_background(); + if (_windowManager.IsMonarch()) + { + // Destroy it only if our settings allow it + if (_trayIcon && + !_logic.GetAlwaysShowTrayIcon() && + !_logic.GetMinimizeToTray()) + { + _DestroyTrayIcon(); + } + } + else { - _DestroyTrayIcon(); + _windowManager.RequestHideTrayIcon(); } } - else - { - _windowManager.RequestHideTrayIcon(); - } -#endif } diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 32ff9c64699..83bc04343f2 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + #include "pch.h" #include "icon.h" #include "TrayIcon.h" @@ -46,7 +49,7 @@ void TrayIcon::CreateTrayIcon() // AppName happens to be in CascadiaPackage's Resources. ScopedResourceLoader loader{ L"Resources" }; - auto appNameLoc = loader.GetLocalizedString(L"AppName"); + const auto appNameLoc = loader.GetLocalizedString(L"AppName"); nid.hIcon = static_cast(GetActiveAppIconHandle(true)); StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), appNameLoc.c_str()); @@ -94,7 +97,7 @@ void TrayIcon::ShowTrayContextMenu(const til::point coord, uFlags |= TPM_LEFTALIGN; } - TrackPopupMenuEx(hMenu, uFlags, gsl::narrow(coord.x()), gsl::narrow(coord.y()), _owningHwnd, NULL); + TrackPopupMenuEx(hMenu, uFlags, gsl::narrow_cast(coord.x()), gsl::narrow_cast(coord.y()), _owningHwnd, NULL); } }