diff --git a/src/cascadia/WindowsTerminal/TrayIcon.cpp b/src/cascadia/WindowsTerminal/TrayIcon.cpp index 83bc04343..e3df4fb0b 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.cpp +++ b/src/cascadia/WindowsTerminal/TrayIcon.cpp @@ -23,6 +23,32 @@ TrayIcon::~TrayIcon() RemoveIconFromTray(); } +void TrayIcon::_CreateWindow() +{ + WNDCLASSW wc{}; + wc.hCursor = LoadCursor(nullptr, IDC_ARROW); + wc.hInstance = wil::GetModuleInstanceHandle(); + wc.lpszClassName = L"TRAY_ICON_HOSTING_WINDOW_CLASS"; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = DefWindowProcW; + wc.hIcon = static_cast(GetActiveAppIconHandle(true)); + RegisterClass(&wc); + + _trayIconHwnd = wil::unique_hwnd(CreateWindowW(wc.lpszClassName, + wc.lpszClassName, + WS_DISABLED, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + HWND_MESSAGE, + nullptr, + wc.hInstance, + nullptr)); + + WINRT_VERIFY(_trayIconHwnd); +} + // Method Description: // - Creates and adds an icon to the notification tray. // If an icon already exists, update the HWND associated @@ -33,6 +59,15 @@ TrayIcon::~TrayIcon() // - void TrayIcon::CreateTrayIcon() { + if (!_trayIconHwnd) + { + // Creating a disabled, non visible window just so we can set it + // as the foreground window when showing the context menu. + // This is done so that the context menu can be dismissed + // when clicking outside of it. + _CreateWindow(); + } + NOTIFYICONDATA nid{}; nid.cbSize = sizeof(NOTIFYICONDATA); @@ -81,7 +116,7 @@ void TrayIcon::ShowTrayContextMenu(const til::point coord, { // 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); + SetForegroundWindow(_trayIconHwnd.get()); // User can select menu items with the left and right buttons. UINT uFlags = TPM_RIGHTBUTTON; diff --git a/src/cascadia/WindowsTerminal/TrayIcon.h b/src/cascadia/WindowsTerminal/TrayIcon.h index aa58d17f1..6095e56e3 100644 --- a/src/cascadia/WindowsTerminal/TrayIcon.h +++ b/src/cascadia/WindowsTerminal/TrayIcon.h @@ -30,8 +30,10 @@ public: WINRT_CALLBACK(SummonWindowRequested, winrt::delegate); private: + void _CreateWindow(); HMENU _CreateTrayContextMenu(winrt::Windows::Foundation::Collections::IMapView peasants); + wil::unique_hwnd _trayIconHwnd; HWND _owningHwnd; NOTIFYICONDATA _trayIconData; };