mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
31 Commits
dev/duhowe
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d28c0be8c1 | ||
|
|
70d905b658 | ||
|
|
9a6ded2e39 | ||
|
|
eac27dbe25 | ||
|
|
d3a98b3754 | ||
|
|
d234049640 | ||
|
|
4ab628d62f | ||
|
|
8309901fc9 | ||
|
|
015c5e8b93 | ||
|
|
1726176c85 | ||
|
|
3b02c96bd5 | ||
|
|
dc448b4781 | ||
|
|
75ea5f3aab | ||
|
|
6ac5137ba8 | ||
|
|
7b524b0d31 | ||
|
|
654416cdc1 | ||
|
|
cae6f04cfb | ||
|
|
9208222884 | ||
|
|
8b67ed7779 | ||
|
|
c4f623aaf0 | ||
|
|
3d83cc348a | ||
|
|
8e170eb643 | ||
|
|
0f339d2498 | ||
|
|
054f173995 | ||
|
|
1fd87fecdf | ||
|
|
e9b2e5184a | ||
|
|
f0f75dcdd0 | ||
|
|
006da6a549 | ||
|
|
67d854821f | ||
|
|
65bc163da4 | ||
|
|
ce375fa7f3 |
1
.github/actions/spelling/allow/allow.txt
vendored
1
.github/actions/spelling/allow/allow.txt
vendored
@@ -117,6 +117,7 @@ uiatextrange
|
||||
UIs
|
||||
und
|
||||
unregister
|
||||
urxvt
|
||||
versioned
|
||||
vsdevcmd
|
||||
walkthrough
|
||||
|
||||
@@ -461,4 +461,35 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
co_await winrt::resume_background();
|
||||
_monarch.RequestSendContent(args);
|
||||
}
|
||||
|
||||
// Attempt to summon an existing window. This static function does NOT
|
||||
// pre-register as the monarch. This is used for activations from a
|
||||
// notification, where this process should NEVER become its own window.
|
||||
bool WindowManager::SummonForNotification(const uint64_t windowId)
|
||||
{
|
||||
auto monarch = create_instance<Remoting::IMonarch>(Monarch_clsid,
|
||||
CLSCTX_LOCAL_SERVER);
|
||||
|
||||
if (monarch == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SummonWindowSelectionArgs args{};
|
||||
args.WindowID(windowId);
|
||||
|
||||
// Summon the window...
|
||||
// * On its current desktop
|
||||
// * Without a dropdown
|
||||
// * On the monitor it is already on
|
||||
// * Do not toggle, just make visible.
|
||||
const Remoting::SummonWindowBehavior summonArgs{};
|
||||
summonArgs.MoveToCurrentDesktop(false);
|
||||
summonArgs.DropdownDuration(0);
|
||||
summonArgs.ToMonitor(Remoting::MonitorBehavior::InPlace);
|
||||
summonArgs.ToggleVisibility(false);
|
||||
|
||||
args.SummonBehavior(summonArgs);
|
||||
monarch.SummonWindow(args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
winrt::fire_and_forget RequestMoveContent(winrt::hstring window, winrt::hstring content, uint32_t tabIndex, Windows::Foundation::IReference<Windows::Foundation::Rect> windowBounds);
|
||||
winrt::fire_and_forget RequestSendContent(Remoting::RequestReceiveContentArgs args);
|
||||
|
||||
static bool SummonForNotification(const uint64_t windowId);
|
||||
|
||||
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
||||
|
||||
TYPED_EVENT(WindowCreated, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Microsoft.Terminal.Remoting
|
||||
void RequestMoveContent(String window, String content, UInt32 tabIndex, Windows.Foundation.IReference<Windows.Foundation.Rect> bounds);
|
||||
void RequestSendContent(RequestReceiveContentArgs args);
|
||||
|
||||
static Boolean SummonForNotification(UInt64 windowId);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WindowCreated;
|
||||
|
||||
@@ -114,4 +114,16 @@ namespace winrt::TerminalApp::implementation
|
||||
AddOtherProvider(winrt::Microsoft::Terminal::Settings::Editor::XamlMetaDataProvider{});
|
||||
}
|
||||
}
|
||||
|
||||
void App::OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs const& args)
|
||||
{
|
||||
if (args != nullptr &&
|
||||
args.Kind() == Windows::ApplicationModel::Activation::ActivationKind::ToastNotification)
|
||||
{
|
||||
if (const auto& toastArgs{ args.try_as<Windows::ApplicationModel::Activation::ToastNotificationActivatedEventArgs>() })
|
||||
{
|
||||
Logic().DoTheThing();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace winrt::TerminalApp::implementation
|
||||
App();
|
||||
void OnLaunched(const Windows::ApplicationModel::Activation::LaunchActivatedEventArgs&);
|
||||
void Initialize();
|
||||
void OnActivated(Windows::ApplicationModel::Activation::IActivatedEventArgs const& args);
|
||||
|
||||
TerminalApp::AppLogic Logic();
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::ParseCommandlineResult GetParseCommandlineMessage(array_view<const winrt::hstring> args);
|
||||
|
||||
void DoTheThing() { DebugBreak(); }
|
||||
|
||||
TYPED_EVENT(SettingsChanged, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::SettingsLoadEventArgs);
|
||||
|
||||
private:
|
||||
|
||||
@@ -57,5 +57,7 @@ namespace TerminalApp
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, SettingsLoadEventArgs> SettingsChanged;
|
||||
|
||||
void DoTheThing();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <inc/WindowingBehavior.h>
|
||||
#include <LibraryResources.h>
|
||||
#include <WtExeUtils.h>
|
||||
#include <TerminalCore/ControlKeyStates.hpp>
|
||||
#include <til/latch.h>
|
||||
|
||||
@@ -45,6 +46,9 @@ using namespace ::Microsoft::Console;
|
||||
using namespace ::Microsoft::Terminal::Core;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using namespace winrt::Windows::UI::Notifications;
|
||||
using namespace winrt::Windows::Data::Xml::Dom;
|
||||
|
||||
#define HOOKUP_ACTION(action) _actionDispatch->action({ this, &TerminalPage::_Handle##action });
|
||||
|
||||
namespace winrt
|
||||
@@ -1671,6 +1675,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
term.CompletionsChanged({ get_weak(), &TerminalPage::_ControlCompletionsChangedHandler });
|
||||
}
|
||||
|
||||
winrt::weak_ref<TermControl> weakTerm{ term };
|
||||
term.ContextMenu().Opening([weak = get_weak(), weakTerm](auto&& sender, auto&& /*args*/) {
|
||||
if (const auto& page{ weak.get() })
|
||||
@@ -1684,6 +1689,7 @@ namespace winrt::TerminalApp::implementation
|
||||
page->_PopulateContextMenu(weakTerm.get(), sender.try_as<MUX::Controls::CommandBarFlyout>(), true);
|
||||
}
|
||||
});
|
||||
term.SendNotification({ get_weak(), &TerminalPage::_SendNotificationHandler });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -2958,6 +2964,124 @@ namespace winrt::TerminalApp::implementation
|
||||
_ShowWindowChangedHandlers(*this, args);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handler for a control's SendNotification event. `args` will contain the
|
||||
// title and body of the notification requested by the client application.
|
||||
// - This will only actually send a notification when the sender is
|
||||
// - in an inactive window OR
|
||||
// - in an inactive tab.
|
||||
winrt::fire_and_forget TerminalPage::_SendNotificationHandler(const IInspectable sender,
|
||||
const Microsoft::Terminal::Control::SendNotificationArgs args)
|
||||
{
|
||||
// This never works as expected when we're an elevated instance. The
|
||||
// notification will end up launching an unelevated instance to handle
|
||||
// it, and there's no good way to get back to the elevated one.
|
||||
// Possibly revisit after GH #13276.
|
||||
//
|
||||
// We're using CanDragDrop, because TODO! I bet this works with UAC disabled
|
||||
if (!CanDragDrop())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
auto weakThis = get_weak();
|
||||
|
||||
co_await resume_foreground(Dispatcher());
|
||||
auto page{ weakThis.get() };
|
||||
if (page)
|
||||
{
|
||||
// If the window is inactive, we always want to send the notification.
|
||||
//
|
||||
// Otherwise, we only want to send the notification for panes in inactive tabs.
|
||||
if (_activated)
|
||||
{
|
||||
auto foundControl = false;
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
activeTab->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
if (const auto& term{ pane->GetTerminalControl() })
|
||||
{
|
||||
if (term == sender)
|
||||
{
|
||||
foundControl = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// The control that sent this is in the active tab. We
|
||||
// should only send the notification if the window was
|
||||
// inactive.
|
||||
if (foundControl)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
_sendNotification(args.Title(), args.Body());
|
||||
}
|
||||
}
|
||||
|
||||
// Actually write the payload to a XML doc and load it into a ToastNotification.
|
||||
void TerminalPage::_sendNotification(const std::wstring_view title,
|
||||
const std::wstring_view body)
|
||||
{
|
||||
// ToastNotificationManager::CreateToastNotifier doesn't work in
|
||||
// unpackaged scenarios without an AUMID. We probably don't have one if
|
||||
// we're unpackaged. Unpackaged isn't a wholly supported scenario
|
||||
// anyways, so let's just bail.
|
||||
|
||||
if (!IsPackaged())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static winrt::hstring xmlTemplate{ L"\
|
||||
<toast launch=\"foo\">\
|
||||
<visual>\
|
||||
<binding template=\"ToastGeneric\">\
|
||||
<text></text>\
|
||||
<text></text>\
|
||||
</binding>\
|
||||
</visual>\
|
||||
</toast>" };
|
||||
|
||||
XmlDocument doc;
|
||||
doc.LoadXml(xmlTemplate);
|
||||
// Populate with text and values
|
||||
// auto payload{ fmt::format(L"window={}&tabIndex=0", WindowProperties().WindowId()) };
|
||||
// doc.DocumentElement().SetAttribute(L"launch", payload);
|
||||
// doc.SelectSingleNode(L"//toast").Attributes().SetNamedItem(payload);
|
||||
doc.SelectSingleNode(L"//text[1]").InnerText(title);
|
||||
doc.SelectSingleNode(L"//text[2]").InnerText(body);
|
||||
|
||||
// Construct the notification
|
||||
ToastNotification notification{ doc };
|
||||
|
||||
// lazy-init
|
||||
if (!_toastNotifier)
|
||||
{
|
||||
_toastNotifier = ToastNotificationManager::CreateToastNotifier();
|
||||
}
|
||||
|
||||
if (_toastNotifier)
|
||||
{
|
||||
_toastActivatedRevoker = notification.Activated(winrt::auto_revoke, [this](auto&&, auto&&) {
|
||||
TraceLoggingWrite(g_hTerminalAppProvider, "ActivatedFromToast", TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
// Request a summon of this window to the foreground
|
||||
_SummonWindowRequestedHandlers(*this, nullptr);
|
||||
|
||||
// args.Handled(true);
|
||||
});
|
||||
|
||||
// And show it!
|
||||
_toastNotifier.Show(notification);
|
||||
TraceLoggingWrite(g_hTerminalAppProvider, "SendToastNotification", TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Paste text from the Windows Clipboard to the focused terminal
|
||||
void TerminalPage::_PasteText()
|
||||
|
||||
@@ -272,6 +272,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::ContentManager _manager{ nullptr };
|
||||
|
||||
winrt::Windows::UI::Notifications::ToastNotification::Activated_revoker _toastActivatedRevoker;
|
||||
|
||||
struct StashedDragData
|
||||
{
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::TabBase> draggedTab{ nullptr };
|
||||
@@ -287,6 +289,9 @@ namespace winrt::TerminalApp::implementation
|
||||
__declspec(noinline) SuggestionsControl _loadSuggestionsElementSlowPath();
|
||||
bool _suggestionsControlIs(winrt::Windows::UI::Xaml::Visibility visibility);
|
||||
|
||||
// todo! maybe move to TerminalWindow
|
||||
winrt::Windows::UI::Notifications::ToastNotifier _toastNotifier{ nullptr };
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowDialogHelper(const std::wstring_view& name);
|
||||
|
||||
void _ShowAboutDialog();
|
||||
@@ -543,6 +548,9 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
|
||||
winrt::com_ptr<TerminalTab> _senderOrFocusedTab(const IInspectable& sender);
|
||||
|
||||
winrt::fire_and_forget _SendNotificationHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::SendNotificationArgs args);
|
||||
|
||||
void _sendNotification(const std::wstring_view title, const std::wstring_view body);
|
||||
#pragma region ActionHandlers
|
||||
// These are all defined in AppActionHandlers.cpp
|
||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Foundation.Metadata.h>
|
||||
@@ -35,6 +37,7 @@
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
#include <winrt/Windows.UI.Input.h>
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
#include <winrt/Windows.UI.Text.h>
|
||||
#include <winrt/Windows.UI.ViewManagement.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Peers.h>
|
||||
|
||||
@@ -126,6 +126,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnCompletionsChanged = [=](auto&& menuJson, auto&& replaceLength) { _terminalCompletionsChanged(menuJson, replaceLength); };
|
||||
_terminal->CompletionsChangedCallback(pfnCompletionsChanged);
|
||||
|
||||
auto pfnSendNotification = std::bind(&ControlCore::_terminalSendNotification, this, std::placeholders::_1, std::placeholders::_2);
|
||||
_terminal->SetSendNotificationCallback(pfnSendNotification);
|
||||
|
||||
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
|
||||
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
|
||||
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
|
||||
@@ -1585,6 +1588,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_midiAudio.PlayNote(reinterpret_cast<HWND>(_owningHwnd), noteNumber, velocity, std::chrono::duration_cast<std::chrono::milliseconds>(duration));
|
||||
}
|
||||
|
||||
void ControlCore::_terminalSendNotification(const std::wstring_view title,
|
||||
const std::wstring_view body)
|
||||
{
|
||||
const auto e = winrt::make_self<implementation::SendNotificationArgs>(title, body);
|
||||
_SendNotificationHandlers(*this, *e);
|
||||
}
|
||||
|
||||
bool ControlCore::HasSelection() const
|
||||
{
|
||||
const auto lock = _terminal->LockForReading();
|
||||
|
||||
@@ -280,6 +280,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
|
||||
|
||||
TYPED_EVENT(Attached, IInspectable, IInspectable);
|
||||
|
||||
TYPED_EVENT(SendNotification, IInspectable, Control::SendNotificationArgs);
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
@@ -372,6 +374,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
winrt::fire_and_forget _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
|
||||
void _terminalSendNotification(const std::wstring_view title,
|
||||
const std::wstring_view body);
|
||||
#pragma endregion
|
||||
|
||||
MidiAudio _midiAudio;
|
||||
|
||||
@@ -190,5 +190,7 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, CompletionsChangedEventArgs> CompletionsChanged;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, SendNotificationArgs> SendNotification;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,3 +20,4 @@
|
||||
#include "KeySentEventArgs.g.cpp"
|
||||
#include "CharSentEventArgs.g.cpp"
|
||||
#include "StringSentEventArgs.g.cpp"
|
||||
#include "SendNotificationArgs.g.cpp"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "KeySentEventArgs.g.h"
|
||||
#include "CharSentEventArgs.g.h"
|
||||
#include "StringSentEventArgs.g.h"
|
||||
#include "SendNotificationArgs.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
@@ -251,6 +252,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, Text);
|
||||
};
|
||||
|
||||
struct SendNotificationArgs : public SendNotificationArgsT<SendNotificationArgs>
|
||||
{
|
||||
public:
|
||||
SendNotificationArgs(const std::wstring_view title,
|
||||
const std::wstring_view body) :
|
||||
_Title(title),
|
||||
_Body(body)
|
||||
{
|
||||
}
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, Title);
|
||||
WINRT_PROPERTY(winrt::hstring, Body);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::factory_implementation
|
||||
|
||||
@@ -121,4 +121,10 @@ namespace Microsoft.Terminal.Control
|
||||
{
|
||||
String Text { get; };
|
||||
}
|
||||
|
||||
runtimeclass SendNotificationArgs
|
||||
{
|
||||
String Title { get; };
|
||||
String Body { get; };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
_revokers.PasteFromClipboard = _interactivity.PasteFromClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubblePasteFromClipboard });
|
||||
|
||||
// Re-raise the event with us as the sender.
|
||||
_core.SendNotification([weakThis = get_weak()](auto s, auto e) {
|
||||
if (auto self{ weakThis.get() })
|
||||
{
|
||||
self->_SendNotificationHandlers(*self, e);
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the terminal only once the swapchainpanel is loaded - that
|
||||
// way, we'll be able to query the real pixel size it got on layout
|
||||
_layoutUpdatedRevoker = SwapChainPanel().LayoutUpdated(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) {
|
||||
|
||||
@@ -194,6 +194,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TYPED_EVENT(KeySent, IInspectable, Control::KeySentEventArgs);
|
||||
TYPED_EVENT(CharSent, IInspectable, Control::CharSentEventArgs);
|
||||
TYPED_EVENT(StringSent, IInspectable, Control::StringSentEventArgs);
|
||||
TYPED_EVENT(SendNotification, IInspectable, Control::SendNotificationArgs);
|
||||
// clang-format on
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, BackgroundBrush, _PropertyChangedHandlers, nullptr);
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> ReadOnlyChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FocusFollowMouseRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SendNotificationArgs> SendNotification;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, CompletionsChangedEventArgs> CompletionsChanged;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Microsoft.Terminal.Core
|
||||
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> StartingTabColor;
|
||||
|
||||
Boolean AutoMarkPrompts;
|
||||
Boolean AllowNotifications;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
_startingTitle = settings.StartingTitle();
|
||||
_trimBlockSelection = settings.TrimBlockSelection();
|
||||
_autoMarkPrompts = settings.AutoMarkPrompts();
|
||||
_allowNotifications = settings.AllowNotifications();
|
||||
|
||||
_getTerminalInput().ForceDisableWin32InputMode(settings.ForceVTInput());
|
||||
|
||||
@@ -1160,6 +1161,11 @@ void Terminal::SetPlayMidiNoteCallback(std::function<void(const int, const int,
|
||||
_pfnPlayMidiNote.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetSendNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept
|
||||
{
|
||||
_pfnSendNotification.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::BlinkCursor() noexcept
|
||||
{
|
||||
if (_selectionMode != SelectionInteractionMode::Mark)
|
||||
|
||||
@@ -163,6 +163,7 @@ public:
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
void SendNotification(const std::wstring_view title, const std::wstring_view body) override;
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
@@ -237,6 +238,7 @@ public:
|
||||
void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
|
||||
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
|
||||
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
|
||||
void SetSendNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept;
|
||||
|
||||
void BlinkCursor() noexcept;
|
||||
void SetCursorOn(const bool isOn) noexcept;
|
||||
@@ -345,6 +347,7 @@ private:
|
||||
std::function<void(bool)> _pfnShowWindowChanged;
|
||||
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
|
||||
std::function<void(std::wstring_view, unsigned int)> _pfnCompletionsChanged;
|
||||
std::function<void(std::wstring_view, std::wstring_view)> _pfnSendNotification;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
@@ -363,6 +366,7 @@ private:
|
||||
bool _suppressApplicationTitle = false;
|
||||
bool _trimBlockSelection = false;
|
||||
bool _autoMarkPrompts = false;
|
||||
bool _allowNotifications = true;
|
||||
|
||||
size_t _taskbarState = 0;
|
||||
size_t _taskbarProgress = 0;
|
||||
|
||||
@@ -511,3 +511,13 @@ void Terminal::NotifyBufferRotation(const int delta)
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::SendNotification(const std::wstring_view title,
|
||||
const std::wstring_view body)
|
||||
{
|
||||
// Only send notifications if enabled in the settings
|
||||
if (_pfnSendNotification && _allowNotifications)
|
||||
{
|
||||
_pfnSendNotification(title, body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,8 @@ Author(s):
|
||||
X(bool, AutoMarkPrompts, "experimental.autoMarkPrompts", false) \
|
||||
X(bool, ShowMarks, "experimental.showMarksOnScrollbar", false) \
|
||||
X(bool, RepositionCursorWithMouse, "experimental.repositionCursorWithMouse", false) \
|
||||
X(bool, ReloadEnvironmentVariables, "compatibility.reloadEnvironmentVariables", true)
|
||||
X(bool, ReloadEnvironmentVariables, "compatibility.reloadEnvironmentVariables", true) \
|
||||
X(bool, AllowNotifications, "allowNotifications", true)
|
||||
|
||||
// Intentionally omitted Profile settings:
|
||||
// * Name
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, RightClickContextMenu);
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, RepositionCursorWithMouse);
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, AllowNotifications);
|
||||
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, ReloadEnvironmentVariables);
|
||||
|
||||
|
||||
@@ -339,6 +339,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
_RightClickContextMenu = profile.RightClickContextMenu();
|
||||
|
||||
_RepositionCursorWithMouse = profile.RepositionCursorWithMouse();
|
||||
_AllowNotifications = profile.AllowNotifications();
|
||||
|
||||
_ReloadEnvironmentVariables = profile.ReloadEnvironmentVariables();
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, ShowMarks, false);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, RightClickContextMenu, false);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, RepositionCursorWithMouse, false);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, AllowNotifications, true);
|
||||
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, ReloadEnvironmentVariables, true);
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::UI::Notifications;
|
||||
|
||||
// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
|
||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||
|
||||
@@ -71,6 +71,8 @@ private:
|
||||
void _HandleCommandlineArgs(const winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs& args);
|
||||
void _HandleSessionRestore(const bool startedForContent);
|
||||
|
||||
// bool _HandleLaunchArgs();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::LaunchPosition _GetWindowLaunchPosition();
|
||||
|
||||
void _HandleCreateWindow(const HWND hwnd, const til::rect& proposedRect);
|
||||
|
||||
@@ -27,6 +27,18 @@ using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
#define XAML_HOSTING_WINDOW_CLASS_NAME L"CASCADIA_HOSTING_WINDOW_CLASS"
|
||||
#define IDM_SYSTEM_MENU_BEGIN 0x1000
|
||||
|
||||
#ifndef NDEBUG
|
||||
void _trace(const wchar_t* const pwsz)
|
||||
{
|
||||
TraceLoggingWrite(g_hWindowsTerminalProvider,
|
||||
"TraceMessage",
|
||||
TraceLoggingDescription("debug print messages"),
|
||||
TraceLoggingWideString(pwsz, "message", "the message"),
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||
}
|
||||
#endif
|
||||
|
||||
IslandWindow::IslandWindow() noexcept :
|
||||
_interopWindowHandle{ nullptr },
|
||||
_rootGrid{ nullptr },
|
||||
@@ -1327,8 +1339,9 @@ void IslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
|
||||
winrt::fire_and_forget IslandWindow::SummonWindow(Remoting::SummonWindowBehavior args)
|
||||
{
|
||||
// On the foreground thread:
|
||||
co_await wil::resume_foreground(_rootGrid.Dispatcher());
|
||||
// co_await wil::resume_foreground(_rootGrid.Dispatcher());
|
||||
_summonWindowRoutineBody(args);
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1337,6 +1350,8 @@ winrt::fire_and_forget IslandWindow::SummonWindow(Remoting::SummonWindowBehavior
|
||||
// when this was part of the coroutine body.
|
||||
void IslandWindow::_summonWindowRoutineBody(Remoting::SummonWindowBehavior args)
|
||||
{
|
||||
_trace(L"_summonWindowRoutineBody");
|
||||
|
||||
auto actualDropdownDuration = args.DropdownDuration();
|
||||
// If the user requested an animation, let's check if animations are enabled in the OS.
|
||||
if (actualDropdownDuration > 0)
|
||||
@@ -1507,12 +1522,15 @@ void IslandWindow::_slideUpWindow(const uint32_t dropdownDuration)
|
||||
void IslandWindow::_globalActivateWindow(const uint32_t dropdownDuration,
|
||||
const Remoting::MonitorBehavior toMonitor)
|
||||
{
|
||||
_trace(L"_globalActivateWindow");
|
||||
// First, get the window that's currently in the foreground. We'll need
|
||||
// _this_ window to be able to appear on top of. If we just use
|
||||
// GetForegroundWindow after the SetWindowPlacement/ShowWindow call, _we_
|
||||
// will be the foreground window.
|
||||
const auto oldForegroundWindow = GetForegroundWindow();
|
||||
|
||||
_trace(fmt::format(L"oldForegroundWindow: {}", (uint64_t)oldForegroundWindow).c_str());
|
||||
|
||||
// From: https://stackoverflow.com/a/59659421
|
||||
// > The trick is to make windows ‘think’ that our process and the target
|
||||
// > window (hwnd) are related by attaching the threads (using
|
||||
@@ -1522,6 +1540,8 @@ void IslandWindow::_globalActivateWindow(const uint32_t dropdownDuration,
|
||||
// restore-down the window.
|
||||
if (IsIconic(_window.get()))
|
||||
{
|
||||
_trace(L"window was iconic");
|
||||
|
||||
if (dropdownDuration > 0)
|
||||
{
|
||||
_dropdownWindow(dropdownDuration, toMonitor);
|
||||
@@ -1538,6 +1558,36 @@ void IslandWindow::_globalActivateWindow(const uint32_t dropdownDuration,
|
||||
}
|
||||
ShowWindow(_window.get(), SW_RESTORE);
|
||||
|
||||
if (!SetForegroundWindow(_window.get()))
|
||||
{
|
||||
const auto gle = GetLastError();
|
||||
_trace(fmt::format(L"SetForegroundWindow failed: {}", gle).c_str());
|
||||
|
||||
const auto fg = GetForegroundWindow();
|
||||
std::wstring title(GetWindowTextLength(fg) + 1, L'\0');
|
||||
GetWindowTextW(fg, &title[0], (DWORD)title.size());
|
||||
DWORD fgPid = 0;
|
||||
GetWindowThreadProcessId(fg, &fgPid);
|
||||
_trace(fmt::format(L"Foreground Window is: [{}]={}", (uint64_t)fgPid, title).c_str());
|
||||
|
||||
SwitchToThisWindow(_window.get(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_trace(L"got fg?");
|
||||
}
|
||||
|
||||
// LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
|
||||
if (!BringWindowToTop(_window.get()))
|
||||
{
|
||||
const auto gle = GetLastError();
|
||||
_trace(fmt::format(L"BringWindowToTop failed: {}", gle).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
_trace(L"brought to top?");
|
||||
}
|
||||
|
||||
// Once we've been restored, throw us on the active monitor.
|
||||
_moveToMonitor(oldForegroundWindow, toMonitor);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ using namespace winrt;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::UI::Notifications;
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace std::chrono_literals;
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
@@ -58,8 +60,92 @@ void _buildArgsFromCommandline(std::vector<winrt::hstring>& args)
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempt to handle activated event args, which are a kind of "modern"
|
||||
// activation, which we use for supporting toast notifications.
|
||||
// - If we do find we were activated from a toast notification, we'll unpack the
|
||||
// arguments from the toast. Then, we'll try to open up a connection to the
|
||||
// monarch and ask the monarch to activate the right window.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
bool WindowEmperor::_handleLaunchArgs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// try
|
||||
// {
|
||||
// // AppInstance::GetActivatedEventArgs will throw when unpackaged.
|
||||
// if (!IsPackaged())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// // If someone clicks on a notification, then a fresh instance of
|
||||
// // windowsterminal.exe will spawn. We certainly don't want to create a new
|
||||
// // window for that - we only want to activate the window that created the
|
||||
// // actual notification. In the toast arg's payload will be the window id
|
||||
// // that sent the notification. We'll ask the window manager to try and
|
||||
// // activate that window ID, without even bothering to register as the
|
||||
// // monarch ourselves (if we can't find a monarch, then there are no windows
|
||||
// // running, so whoever sent it must have died.)
|
||||
|
||||
// const auto activatedArgs = AppInstance::GetActivatedEventArgs();
|
||||
// if (activatedArgs != nullptr &&
|
||||
// activatedArgs.Kind() == Activation::ActivationKind::ToastNotification)
|
||||
// {
|
||||
// if (const auto& toastArgs{ activatedArgs.try_as<Activation::ToastNotificationActivatedEventArgs>() })
|
||||
// {
|
||||
// // Obtain the arguments from the notification
|
||||
// const auto args = toastArgs.Argument();
|
||||
|
||||
// // Args is gonna look like
|
||||
// //
|
||||
// // "window=id&foo=bar&..."
|
||||
// //
|
||||
// // We need to first split on &, then split those pairs on =
|
||||
|
||||
// // tabIndex code here is left as reference for parsing multiple
|
||||
// // arguments, despite it not being used currently.
|
||||
// uint32_t window;
|
||||
// // uint32_t tabIndex = 0;
|
||||
|
||||
// const std::wstring_view argsView{ args };
|
||||
// const auto pairs = Utils::SplitString(argsView, L'&');
|
||||
// for (const auto& pair : pairs)
|
||||
// {
|
||||
// const auto pairParts = Utils::SplitString(pair, L'=');
|
||||
// if (pairParts.size() == 2)
|
||||
// {
|
||||
// if (til::at(pairParts, 0) == L"window")
|
||||
// {
|
||||
// window = std::wcstoul(pairParts[1].data(), nullptr, 10);
|
||||
// }
|
||||
// // else if (pairParts[0] == L"tabIndex")
|
||||
// // {
|
||||
// // // convert a wide string to a uint
|
||||
// // tabIndex = std::wcstoul(pairParts[1].data(), nullptr, 10);
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
// return winrt::Microsoft::Terminal::Remoting::WindowManager::SummonForNotification(window);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
// CATCH_LOG_RETURN_HR(false)
|
||||
|
||||
void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
|
||||
{
|
||||
// Before handling any commandline arguments, check if this was a toast
|
||||
// invocation. If it was, we can go ahead and totally ignore everything
|
||||
// else.
|
||||
if (_handleLaunchArgs())
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), 0u);
|
||||
}
|
||||
|
||||
std::vector<winrt::hstring> args;
|
||||
_buildArgsFromCommandline(args);
|
||||
const auto cwd{ wil::GetCurrentDirectoryW<std::wstring>() };
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
void HandleCommandlineArgs(int nCmdShow);
|
||||
|
||||
private:
|
||||
bool _handleLaunchArgs();
|
||||
void _createNewWindowThread(const winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs& args);
|
||||
|
||||
[[nodiscard]] static LRESULT __stdcall _wndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept;
|
||||
|
||||
@@ -59,7 +59,14 @@ Abstract:
|
||||
// * Media for ScaleTransform
|
||||
// * ApplicationModel for finding the path to wt.exe
|
||||
// * Primitives for Popup (used by GetOpenPopupsForXamlRoot)
|
||||
// * XML, Notifications, Activation: for notification activations
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
#include <winrt/Windows.UI.Composition.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.UI.Xaml.Data.h>
|
||||
|
||||
@@ -49,7 +49,8 @@
|
||||
X(bool, DetectURLs, true) \
|
||||
X(bool, VtPassthrough, false) \
|
||||
X(bool, AutoMarkPrompts) \
|
||||
X(bool, RepositionCursorWithMouse, false)
|
||||
X(bool, RepositionCursorWithMouse, false) \
|
||||
X(bool, AllowNotifications, true)
|
||||
|
||||
// --------------------------- Control Settings ---------------------------
|
||||
// All of these settings are defined in IControlSettings.
|
||||
|
||||
@@ -187,4 +187,15 @@
|
||||
</alwaysEnabledBrandingTokens>
|
||||
</feature>
|
||||
|
||||
<feature>
|
||||
<name>Feature_Notifications</name>
|
||||
<description>Enables OSC777 notifications</description>
|
||||
<id>16654</id>
|
||||
<stage>AlwaysDisabled</stage>
|
||||
<alwaysEnabledBrandingTokens>
|
||||
<brandingToken>Dev</brandingToken>
|
||||
<brandingToken>Canary</brandingToken>
|
||||
</alwaysEnabledBrandingTokens>
|
||||
</feature>
|
||||
|
||||
</featureStaging>
|
||||
|
||||
@@ -76,6 +76,8 @@ public:
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
void SendNotification(const std::wstring_view /*title*/, const std::wstring_view /*body*/) noexcept override{};
|
||||
|
||||
private:
|
||||
Microsoft::Console::IIoProvider& _io;
|
||||
};
|
||||
|
||||
@@ -137,6 +137,7 @@ public:
|
||||
virtual bool DoITerm2Action(const std::wstring_view string) = 0;
|
||||
|
||||
virtual bool DoFinalTermAction(const std::wstring_view string) = 0;
|
||||
virtual bool DoUrxvtAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual bool DoVsCodeAction(const std::wstring_view string) = 0;
|
||||
|
||||
|
||||
@@ -87,5 +87,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
virtual void MarkCommandFinish(std::optional<unsigned int> error) = 0;
|
||||
|
||||
virtual void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) = 0;
|
||||
|
||||
virtual void SendNotification(const std::wstring_view title, const std::wstring_view body) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3863,6 +3863,41 @@ bool AdaptDispatch::DoVsCodeAction(const std::wstring_view string)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdaptDispatch::DoUrxvtAction(const std::wstring_view string)
|
||||
{
|
||||
// This is not implemented in conhost.
|
||||
if (_api.IsConsolePty())
|
||||
{
|
||||
// Flush the frame manually, to make sure marks end up on the right line, like the alt buffer sequence.
|
||||
_renderer.TriggerFlush(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if constexpr (!Feature_Notifications::IsEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto parts = Utils::SplitString(string, L';');
|
||||
|
||||
if (parts.size() < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto action = til::at(parts, 0);
|
||||
|
||||
if (action == L"notify")
|
||||
{
|
||||
const std::wstring_view title = parts.size() > 1 ? til::at(parts, 1) : L"";
|
||||
const std::wstring_view body = parts.size() > 2 ? til::at(parts, 2) : L"";
|
||||
_api.SendNotification(title, body);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - DECDLD - Downloads one or more characters of a dynamically redefinable
|
||||
// character set (DRCS) with a specified pixel pattern. The pixel array is
|
||||
|
||||
@@ -139,6 +139,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
bool DoITerm2Action(const std::wstring_view string) override;
|
||||
|
||||
bool DoFinalTermAction(const std::wstring_view string) override;
|
||||
bool DoUrxvtAction(const std::wstring_view string) override;
|
||||
|
||||
bool DoVsCodeAction(const std::wstring_view string) override;
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ public:
|
||||
|
||||
bool DoVsCodeAction(const std::wstring_view /*string*/) override { return false; }
|
||||
|
||||
bool DoUrxvtAction(const std::wstring_view /*string*/) override { return false; }
|
||||
|
||||
StringHandler DownloadDRCS(const VTInt /*fontNumber*/,
|
||||
const VTParameter /*startChar*/,
|
||||
const DispatchTypes::DrcsEraseControl /*eraseControl*/,
|
||||
|
||||
@@ -238,6 +238,11 @@ public:
|
||||
VERIFY_ARE_EQUAL(_expectedReplaceLength, replaceLength);
|
||||
}
|
||||
|
||||
void SendNotification(const std::wstring_view /*title*/, const std::wstring_view /*body*/) override
|
||||
{
|
||||
Log::Comment(L"SendNotification MOCK called...");
|
||||
}
|
||||
|
||||
void PrepData()
|
||||
{
|
||||
PrepData(CursorDirection::UP); // if called like this, the cursor direction doesn't matter.
|
||||
|
||||
@@ -883,6 +883,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/,
|
||||
success = _dispatch->DoVsCodeAction(string);
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::UrxvtAction:
|
||||
{
|
||||
success = _dispatch->DoUrxvtAction(string);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// If no functions to call, overall dispatch was a failure.
|
||||
success = false;
|
||||
|
||||
@@ -218,6 +218,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
ResetCursorColor = 112,
|
||||
FinalTermAction = 133,
|
||||
VsCodeAction = 633,
|
||||
UrxvtAction = 777,
|
||||
ITerm2Action = 1337,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user