From 54009e130542caaf7a74ffb8f44fc604c56c19eb Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 29 Apr 2026 14:40:33 -0700 Subject: [PATCH] --from-toast & GetTickCount64() --- src/cascadia/TerminalApp/AppCommandlineArgs.cpp | 4 ++-- src/cascadia/TerminalApp/DesktopNotification.cpp | 16 ++++++++-------- src/cascadia/TerminalApp/DesktopNotification.h | 7 +++---- src/cascadia/WindowsTerminal/WindowEmperor.cpp | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/cascadia/TerminalApp/AppCommandlineArgs.cpp b/src/cascadia/TerminalApp/AppCommandlineArgs.cpp index a7ae09a01f..950984019b 100644 --- a/src/cascadia/TerminalApp/AppCommandlineArgs.cpp +++ b/src/cascadia/TerminalApp/AppCommandlineArgs.cpp @@ -1069,10 +1069,10 @@ int AppCommandlineArgs::ParseArgs(winrt::array_view args) } // When a toast notification is clicked, Windows may launch a new instance - // with "__fromToast" as the argument. This is a no-op sentinel — the + // with "--from-toast" as the argument. This is a no-op sentinel — the // in-process Activated handler on the toast already handled activation. // See DesktopNotification.cpp for more details. - if (args.size() == 2 && args[1] == L"__fromToast") + if (args.size() == 2 && args[1] == L"--from-toast") { return 0; } diff --git a/src/cascadia/TerminalApp/DesktopNotification.cpp b/src/cascadia/TerminalApp/DesktopNotification.cpp index fb33d1a84d..d1e8a198c7 100644 --- a/src/cascadia/TerminalApp/DesktopNotification.cpp +++ b/src/cascadia/TerminalApp/DesktopNotification.cpp @@ -11,7 +11,7 @@ using namespace winrt::Windows::Data::Xml::Dom; namespace winrt::TerminalApp::implementation { - std::atomic DesktopNotification::_lastNotificationTime{ 0 }; + std::atomic DesktopNotification::_lastNotificationTime{ 0 }; // Method Description: // - Rate-limits toast notifications so we don't spam the user. @@ -19,12 +19,12 @@ namespace winrt::TerminalApp::implementation // - Returns true if a notification is allowed, false if too recent. bool DesktopNotification::ShouldSendNotification() { - FILETIME ft{}; - GetSystemTimeAsFileTime(&ft); - const auto now = (static_cast(ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + const auto now = GetTickCount64(); auto last = _lastNotificationTime.load(std::memory_order_relaxed); - if (now - last < MinNotificationIntervalTicks) + // Subtraction wraps cleanly modulo 2^64, so the delta is correct even + // across the (~584 million year) GetTickCount64 rollover. + if (now - last < MinNotificationIntervalMs) { return false; } @@ -53,7 +53,7 @@ namespace winrt::TerminalApp::implementation // Build the toast XML. We use a simple template with a title and body text. // - // + // // // // Title @@ -74,9 +74,9 @@ namespace winrt::TerminalApp::implementation // When a toast is clicked, Windows launches a new instance of the app // with the "launch" attribute as command-line arguments. We handle // toast activation in-process via the Activated event below, so the - // new instance should do nothing. "__fromToast" is recognized by + // new instance should do nothing. "--from-toast" is recognized by // AppCommandlineArgs::ParseArgs as a no-op sentinel. - toastElement.SetAttribute(L"launch", L"__fromToast"); + toastElement.SetAttribute(L"launch", L"--from-toast"); toastElement.SetAttribute(L"scenario", L"default"); diff --git a/src/cascadia/TerminalApp/DesktopNotification.h b/src/cascadia/TerminalApp/DesktopNotification.h index 273fad18b8..a3bab6dddd 100644 --- a/src/cascadia/TerminalApp/DesktopNotification.h +++ b/src/cascadia/TerminalApp/DesktopNotification.h @@ -29,10 +29,9 @@ namespace winrt::TerminalApp::implementation static void SendNotification(const DesktopNotificationArgs& args, std::function activatedFunc); private: - static std::atomic _lastNotificationTime; + static std::atomic _lastNotificationTime; - // Minimum interval between notifications, in 100ns ticks (FILETIME units). - // 5 seconds = 5 * 10,000,000 - static constexpr int64_t MinNotificationIntervalTicks = 50'000'000LL; + // Minimum interval between notifications, in milliseconds (GetTickCount64 units). + static constexpr uint64_t MinNotificationIntervalMs = 5'000; }; } diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index a7e72c70b3..7000abc2d2 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -1029,10 +1029,10 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c const auto handoff = deserializeHandoffPayload(static_cast(cds->lpData), static_cast(cds->lpData) + cds->cbData); const auto argv = commandlineToArgArray(handoff.args.c_str()); // When a toast notification is clicked, Windows launches a new - // wt.exe with "__fromToast". That instance hands off here via + // wt.exe with "--from-toast". That instance hands off here via // WM_COPYDATA. We already handle activation in-process via the // toast's Activated event, so just ignore this handoff. - if (argv.size() != 2 || argv[1] != L"__fromToast") + if (argv.size() != 2 || argv[1] != L"--from-toast") { _dispatchCommandlineCommon(argv, handoff.cwd, handoff.env, handoff.show); }