From 2a0dd78a7dec922b9c27ae1ea5b17c06746a867b Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 24 Mar 2026 18:12:04 -0700 Subject: [PATCH 1/2] Send notifications even when we're unpackaged --- .../TerminalApp/DesktopNotification.cpp | 26 ++++++++++++++++--- .../WindowsTerminal/WindowEmperor.cpp | 23 ++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/cascadia/TerminalApp/DesktopNotification.cpp b/src/cascadia/TerminalApp/DesktopNotification.cpp index 9d9294a1c52..50214cdbf7e 100644 --- a/src/cascadia/TerminalApp/DesktopNotification.cpp +++ b/src/cascadia/TerminalApp/DesktopNotification.cpp @@ -4,6 +4,8 @@ #include "pch.h" #include "DesktopNotification.h" +#include + using namespace winrt::Windows::UI::Notifications; using namespace winrt::Windows::Data::Xml::Dom; @@ -96,10 +98,26 @@ namespace winrt::TerminalApp::implementation } // For packaged apps, CreateToastNotifier() uses the package identity automatically. - // For unpackaged apps, we need to provide an AUMID, but that case is less common - // and toast notifications may not be supported without additional setup. - auto notifier = ToastNotificationManager::CreateToastNotifier(); - notifier.Show(toast); + // For unpackaged apps, we must pass the explicit AUMID that was registered + // at startup via SetCurrentProcessExplicitAppUserModelID. + winrt::Windows::UI::Notifications::ToastNotifier notifier{ nullptr }; + if (IsPackaged()) + { + notifier = ToastNotificationManager::CreateToastNotifier(); + } + else + { + // Retrieve the AUMID that was set by WindowEmperor at startup. + wil::unique_cotaskmem_string aumid; + if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&aumid))) + { + notifier = ToastNotificationManager::CreateToastNotifier(aumid.get()); + } + } + if (notifier) + { + notifier.Show(toast); + } } catch (...) { diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index 07e96fcc2e5..f7527aed237 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -364,6 +364,29 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow) __assume(false); } + // When running without package identity, set an explicit AppUserModelID so + // that toast notifications (and other shell features like taskbar grouping) + // work correctly. We include a hash of the executable path to prevent + // crosstalk between different portable/unpackaged installations — the same + // isolation strategy used for the single-instance mutex above. + if (!IsPackaged()) + { + std::wstring aumid; +#if defined(WT_BRANDING_RELEASE) + aumid = L"Microsoft.WindowsTerminal"; +#elif defined(WT_BRANDING_PREVIEW) + aumid = L"Microsoft.WindowsTerminalPreview"; +#elif defined(WT_BRANDING_CANARY) + aumid = L"Microsoft.WindowsTerminalCanary"; +#else + aumid = L"Microsoft.WindowsTerminalDev"; +#endif + const auto path = wil::QueryFullProcessImageNameW(); + const auto hash = til::hash(path); + fmt::format_to(std::back_inserter(aumid), FMT_COMPILE(L".{:016x}"), hash); + LOG_IF_FAILED(SetCurrentProcessExplicitAppUserModelID(aumid.c_str())); + } + _app = winrt::TerminalApp::App{}; _app.Logic().ReloadSettings(); From fc1b724011380b1f5a01083ceca18af0c8fa3bc2 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 25 Mar 2026 11:32:49 -0700 Subject: [PATCH 2/2] remove WindowEmperor changes --- .../WindowsTerminal/WindowEmperor.cpp | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index f7527aed237..07e96fcc2e5 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -364,29 +364,6 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow) __assume(false); } - // When running without package identity, set an explicit AppUserModelID so - // that toast notifications (and other shell features like taskbar grouping) - // work correctly. We include a hash of the executable path to prevent - // crosstalk between different portable/unpackaged installations — the same - // isolation strategy used for the single-instance mutex above. - if (!IsPackaged()) - { - std::wstring aumid; -#if defined(WT_BRANDING_RELEASE) - aumid = L"Microsoft.WindowsTerminal"; -#elif defined(WT_BRANDING_PREVIEW) - aumid = L"Microsoft.WindowsTerminalPreview"; -#elif defined(WT_BRANDING_CANARY) - aumid = L"Microsoft.WindowsTerminalCanary"; -#else - aumid = L"Microsoft.WindowsTerminalDev"; -#endif - const auto path = wil::QueryFullProcessImageNameW(); - const auto hash = til::hash(path); - fmt::format_to(std::back_inserter(aumid), FMT_COMPILE(L".{:016x}"), hash); - LOG_IF_FAILED(SetCurrentProcessExplicitAppUserModelID(aumid.c_str())); - } - _app = winrt::TerminalApp::App{}; _app.Logic().ReloadSettings();