Skip to content

Commit 3b02c96

Browse files
committed
summon didn't work but the rest did
1 parent dc448b4 commit 3b02c96

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/cascadia/WindowsTerminal/WindowEmperor.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ using namespace winrt;
1717
using namespace winrt::Microsoft::Terminal;
1818
using namespace winrt::Microsoft::Terminal::Settings::Model;
1919
using namespace winrt::Windows::Foundation;
20+
using namespace winrt::Windows::ApplicationModel;
21+
using namespace winrt::Windows::UI::Notifications;
2022
using namespace ::Microsoft::Console;
2123
using namespace std::chrono_literals;
2224
using 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

84148
bool 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>() };

src/cascadia/WindowsTerminal/WindowEmperor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class WindowEmperor : public std::enable_shared_from_this<WindowEmperor>
3030
bool HandleCommandlineArgs();
3131

3232
private:
33+
bool _handleLaunchArgs();
3334
void _createNewWindowThread(const winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs& args);
3435

3536
[[nodiscard]] static LRESULT __stdcall _wndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept;

0 commit comments

Comments
 (0)