@@ -17,6 +17,8 @@ using namespace winrt;
1717using namespace winrt ::Microsoft::Terminal;
1818using namespace winrt ::Microsoft::Terminal::Settings::Model;
1919using namespace winrt ::Windows::Foundation;
20+ using namespace winrt ::Windows::ApplicationModel;
21+ using namespace winrt ::Windows::UI::Notifications;
2022using namespace ::Microsoft::Console;
2123using namespace std ::chrono_literals;
2224using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
@@ -80,9 +82,74 @@ void _buildArgsFromCommandline(std::vector<winrt::hstring>& args)
8082 args.emplace_back (L" wt.exe" );
8183 }
8284}
85+ bool WindowEmperor::_handleLaunchArgs ()
86+ try
87+ {
88+ // AppInstance::GetActivatedEventArgs will throw when unpackaged.
89+ if (!IsPackaged ())
90+ {
91+ return false ;
92+ }
93+ // If someone clicks on a notification, then a fresh instance of
94+ // windowsterminal.exe will spawn. We certainly don't want to create a new
95+ // window for that - we only want to activate the window that created the
96+ // actual notification. In the toast arg's payload will be the window id
97+ // that sent the notification. We'll ask the window manager to try and
98+ // activate that window ID, without even bothering to register as the
99+ // monarch ourselves (if we can't find a monarch, then there are no windows
100+ // running, so whoever sent it must have died.)
101+
102+ const auto activatedArgs = AppInstance::GetActivatedEventArgs ();
103+ if (activatedArgs != nullptr &&
104+ activatedArgs.Kind () == Activation::ActivationKind::ToastNotification)
105+ {
106+ if (const auto & toastArgs{ activatedArgs.try_as <Activation::ToastNotificationActivatedEventArgs>() })
107+ {
108+ // Obtain the arguments from the notification
109+ const auto args = toastArgs.Argument ();
110+
111+ // Args is gonna look like
112+ //
113+ // "window=id&foo=bar&..."
114+ //
115+ // We need to first split on &, then split those pairs on =
116+
117+ // tabIndex code here is left as reference for parsing multiple
118+ // arguments, despite it not being used currently.
119+ uint32_t window;
120+ // uint32_t tabIndex = 0;
121+
122+ const std::wstring_view argsView{ args };
123+ const auto pairs = Utils::SplitString (argsView, L' &' );
124+ for (const auto & pair : pairs)
125+ {
126+ const auto pairParts = Utils::SplitString (pair, L' =' );
127+ if (pairParts.size () == 2 )
128+ {
129+ if (til::at (pairParts, 0 ) == L" window" )
130+ {
131+ window = std::wcstoul (pairParts[1 ].data (), nullptr , 10 );
132+ }
133+ // else if (pairParts[0] == L"tabIndex")
134+ // {
135+ // // convert a wide string to a uint
136+ // tabIndex = std::wcstoul(pairParts[1].data(), nullptr, 10);
137+ // }
138+ }
139+ }
140+ return winrt::Microsoft::Terminal::Remoting::WindowManager::SummonForNotification (window);
141+ }
142+ }
143+
144+ return false ;
145+ }
146+ CATCH_LOG_RETURN_HR (false )
83147
84148bool WindowEmperor::HandleCommandlineArgs()
85149{
150+ if (_handleLaunchArgs ())
151+ return false ;
152+
86153 std::vector<winrt::hstring> args;
87154 _buildArgsFromCommandline (args);
88155 const auto cwd{ wil::GetCurrentDirectoryW<std::wstring>() };
0 commit comments