mirror of
https://github.com/microsoft/terminal.git
synced 2026-07-08 17:46:05 +00:00
Add support for OSC777 (Send Notification) (#20012)
## Summary of the Pull Request targets #20010 This adds support for the `OSC 777 ; notify ; title ; body ST` sequence. This allows client applications to send a notification to the Terminal. When this notification is clicked, it summons the terminal window that sent it. ## Validation Steps Performed ```pwsh # in PowerShell. Terminal should not be focused. sleep 2; Write-Output "`e]777;notify;Hello;This is a notification`a" ``` ## PR Checklist - [X] Closes #7718 - [ ] Documentation updated - [X] Schema updated (if necessary) Heavily based on #19938 Co-authored by @zadjii-msft
This commit is contained in:
1
.github/actions/spelling/expect/expect.txt
vendored
1
.github/actions/spelling/expect/expect.txt
vendored
@@ -1758,6 +1758,7 @@ UPKEY
|
||||
upss
|
||||
uregex
|
||||
URegular
|
||||
urxvt
|
||||
usebackq
|
||||
USECALLBACK
|
||||
USECOLOR
|
||||
|
||||
@@ -2794,6 +2794,11 @@
|
||||
"description": "When set to true, VT applications will be allowed to set the contents of the local clipboard using OSC 52 (Manipulate Selection Data).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.allowOSC777": {
|
||||
"default": false,
|
||||
"description": "When set to true, applications can send OSC 777 escape sequences to trigger desktop toast notifications with a custom title and body.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"unfocusedAppearance": {
|
||||
"$ref": "#/$defs/AppearanceConfig",
|
||||
"description": "Sets the appearance of the terminal when it is unfocused.",
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// When the user activates (clicks) the toast, fire the callback.
|
||||
if (activatedFunc)
|
||||
{
|
||||
toast.Activated([activatedFunc](const auto& /*sender*/, const auto& /*eventArgs*/) {
|
||||
toast.Activated([activatedFunc = std::move(activatedFunc)](const auto& /*sender*/, const auto& /*eventArgs*/) {
|
||||
activatedFunc();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1353,7 +1353,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Use the Tab object's identity hash as a stable toast tag.
|
||||
// This survives tab reordering and cross-window moves.
|
||||
const auto tabHash = std::hash<winrt::Windows::Foundation::IUnknown>{}(*tab);
|
||||
#ifdef _WIN64
|
||||
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:016x}"), tabHash) };
|
||||
#else
|
||||
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:08x}"), tabHash) };
|
||||
#endif
|
||||
|
||||
const implementation::DesktopNotificationArgs args{
|
||||
.Title = notificationTitle,
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_controlEvents._SetTaskbarProgress = _control.SetTaskbarProgress(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlSetTaskbarProgress });
|
||||
_controlEvents._ReadOnlyChanged = _control.ReadOnlyChanged(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlReadOnlyChanged });
|
||||
_controlEvents._FocusFollowMouseRequested = _control.FocusFollowMouseRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlFocusFollowMouseRequested });
|
||||
_controlEvents._ShowNotification = _control.ShowNotification(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlShowNotification });
|
||||
}
|
||||
void TerminalPaneContent::_removeControlEvents()
|
||||
{
|
||||
@@ -170,6 +171,11 @@ namespace winrt::TerminalApp::implementation
|
||||
FocusRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlShowNotification(const IInspectable& /*sender*/, const ShowNotificationEventArgs& args)
|
||||
{
|
||||
NotificationRequested.raise(*this, winrt::make<implementation::NotificationEventArgs>(args.Title(), args.Body()));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when our attached control is closed. Triggers listeners to our close
|
||||
// event, if we're a leaf pane.
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Control::TermControl::SetTaskbarProgress_revoker _SetTaskbarProgress;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ReadOnlyChanged_revoker _ReadOnlyChanged;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::FocusFollowMouseRequested_revoker _FocusFollowMouseRequested;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ShowNotification_revoker _ShowNotification;
|
||||
|
||||
} _controlEvents;
|
||||
void _setupControlEvents();
|
||||
@@ -103,6 +104,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _controlSetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlReadOnlyChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlFocusFollowMouseRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlShowNotification(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::Control::ShowNotificationEventArgs& args);
|
||||
|
||||
void _closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _restartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
|
||||
@@ -139,6 +139,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnSearchMissingCommand = [this](auto&& PH1, auto&& PH2) { _terminalSearchMissingCommand(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
|
||||
_terminal->SetSearchMissingCommandCallback(pfnSearchMissingCommand);
|
||||
|
||||
auto pfnShowNotification = [this](auto&& PH1, auto&& PH2) { _terminalShowNotification(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
|
||||
_terminal->SetShowNotificationCallback(pfnShowNotification);
|
||||
|
||||
auto pfnClearQuickFix = [this] { ClearQuickFix(); };
|
||||
_terminal->SetClearQuickFixCallback(pfnClearQuickFix);
|
||||
|
||||
@@ -1692,6 +1695,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
SearchMissingCommand.raise(*this, make<implementation::SearchMissingCommandEventArgs>(hstring{ missingCommand }, bufferRow));
|
||||
}
|
||||
|
||||
void ControlCore::_terminalShowNotification(std::wstring_view title, std::wstring_view body)
|
||||
{
|
||||
ShowNotification.raise(*this, make<implementation::ShowNotificationEventArgs>(hstring{ title }, hstring{ body }));
|
||||
}
|
||||
|
||||
void ControlCore::OpenCWD()
|
||||
{
|
||||
const auto workingDirectory = WorkingDirectory();
|
||||
|
||||
@@ -292,6 +292,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
til::typed_event<IInspectable, Control::CompletionsChangedEventArgs> CompletionsChanged;
|
||||
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
til::typed_event<IInspectable, Control::ShowNotificationEventArgs> ShowNotification;
|
||||
til::typed_event<> RefreshQuickFixUI;
|
||||
til::typed_event<IInspectable, Control::WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
@@ -333,6 +334,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const int velocity,
|
||||
const std::chrono::microseconds duration);
|
||||
void _terminalSearchMissingCommand(std::wstring_view missingCommand, const til::CoordType& bufferRow);
|
||||
void _terminalShowNotification(std::wstring_view title, std::wstring_view body);
|
||||
void _terminalWindowSizeChanged(int32_t width, int32_t height);
|
||||
|
||||
void _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
|
||||
@@ -198,6 +198,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RefreshQuickFixUI;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "CharSentEventArgs.g.h"
|
||||
#include "StringSentEventArgs.g.h"
|
||||
#include "SearchMissingCommandEventArgs.g.h"
|
||||
#include "ShowNotificationEventArgs.g.h"
|
||||
#include "WindowSizeChangedEventArgs.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
@@ -252,6 +253,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::property<til::CoordType> BufferRow;
|
||||
};
|
||||
|
||||
struct ShowNotificationEventArgs : public ShowNotificationEventArgsT<ShowNotificationEventArgs>
|
||||
{
|
||||
public:
|
||||
ShowNotificationEventArgs(const winrt::hstring& title, const winrt::hstring& body) :
|
||||
Title(title),
|
||||
Body(body) {}
|
||||
|
||||
til::property<winrt::hstring> Title;
|
||||
til::property<winrt::hstring> Body;
|
||||
};
|
||||
|
||||
struct WindowSizeChangedEventArgs : public WindowSizeChangedEventArgsT<WindowSizeChangedEventArgs>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -160,6 +160,12 @@ namespace Microsoft.Terminal.Control
|
||||
Int32 BufferRow { get; };
|
||||
}
|
||||
|
||||
runtimeclass ShowNotificationEventArgs
|
||||
{
|
||||
String Title { get; };
|
||||
String Body { get; };
|
||||
}
|
||||
|
||||
runtimeclass WindowSizeChangedEventArgs
|
||||
{
|
||||
Int32 Width;
|
||||
|
||||
@@ -328,6 +328,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.CompletionsChanged = _core.CompletionsChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleCompletionsChanged });
|
||||
_revokers.RestartTerminalRequested = _core.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleRestartTerminalRequested });
|
||||
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
|
||||
_revokers.ShowNotification = _core.ShowNotification(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleShowNotification });
|
||||
_revokers.WindowSizeChanged = _core.WindowSizeChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWindowSizeChanged });
|
||||
_revokers.WriteToClipboard = _core.WriteToClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWriteToClipboard });
|
||||
|
||||
|
||||
@@ -230,6 +230,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(WriteToClipboard, IInspectable, Control::WriteToClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ShowNotification, IInspectable, Control::ShowNotificationEventArgs);
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -468,6 +469,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::ControlCore::CompletionsChanged_revoker CompletionsChanged;
|
||||
Control::ControlCore::RestartTerminalRequested_revoker RestartTerminalRequested;
|
||||
Control::ControlCore::SearchMissingCommand_revoker SearchMissingCommand;
|
||||
Control::ControlCore::ShowNotification_revoker ShowNotification;
|
||||
Control::ControlCore::RefreshQuickFixUI_revoker RefreshQuickFixUI;
|
||||
Control::ControlCore::WindowSizeChanged_revoker WindowSizeChanged;
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, CharSentEventArgs> CharSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, StringSentEventArgs> StringSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
|
||||
|
||||
|
||||
Microsoft.UI.Xaml.Controls.CommandBarFlyout ContextMenu { get; };
|
||||
|
||||
@@ -124,6 +124,7 @@ namespace Microsoft.Terminal.Core
|
||||
Boolean AllowKittyKeyboardMode { get; };
|
||||
Boolean AllowVtChecksumReport { get; };
|
||||
Boolean AllowVtClipboardWrite { get; };
|
||||
Boolean AllowOscNotifications { get; };
|
||||
Boolean TrimBlockSelection { get; };
|
||||
Boolean DetectURLs { get; };
|
||||
|
||||
|
||||
@@ -267,6 +267,7 @@ void Terminal::SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettin
|
||||
auto features = til::enumset<ITermDispatch::OptionalFeature>{};
|
||||
features.set(ITermDispatch::OptionalFeature::ChecksumReport, settings.AllowVtChecksumReport());
|
||||
features.set(ITermDispatch::OptionalFeature::ClipboardWrite, settings.AllowVtClipboardWrite());
|
||||
features.set(ITermDispatch::OptionalFeature::DesktopNotification, settings.AllowOscNotifications());
|
||||
engine.Dispatch().SetOptionalFeatures(features);
|
||||
}
|
||||
|
||||
@@ -1276,6 +1277,11 @@ void Microsoft::Terminal::Core::Terminal::SetSearchMissingCommandCallback(std::f
|
||||
_pfnSearchMissingCommand.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept
|
||||
{
|
||||
_pfnShowNotification.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnClearQuickFix.swap(pfn);
|
||||
|
||||
@@ -165,6 +165,8 @@ public:
|
||||
|
||||
void SearchMissingCommand(const std::wstring_view command) override;
|
||||
|
||||
void ShowNotification(const std::wstring_view title, const std::wstring_view body) override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
@@ -233,6 +235,7 @@ public:
|
||||
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 SetSearchMissingCommandCallback(std::function<void(std::wstring_view, const til::CoordType)> pfn) noexcept;
|
||||
void SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept;
|
||||
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
||||
void SetWindowSizeChangedCallback(std::function<void(int32_t, int32_t)> pfn) noexcept;
|
||||
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
||||
@@ -341,6 +344,7 @@ private:
|
||||
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, const til::CoordType)> _pfnSearchMissingCommand;
|
||||
std::function<void(std::wstring_view, std::wstring_view)> _pfnShowNotification;
|
||||
std::function<void()> _pfnClearQuickFix;
|
||||
std::function<void(int32_t, int32_t)> _pfnWindowSizeChanged;
|
||||
|
||||
|
||||
@@ -380,6 +380,14 @@ void Terminal::SearchMissingCommand(const std::wstring_view command)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::ShowNotification(const std::wstring_view title, const std::wstring_view body)
|
||||
{
|
||||
if (_pfnShowNotification)
|
||||
{
|
||||
_pfnShowNotification(title, body);
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyBufferRotation(const int delta)
|
||||
{
|
||||
// Update our selection, so it doesn't move as the buffer is cycled
|
||||
|
||||
@@ -352,6 +352,7 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
_AllowKittyKeyboardMode = profile.AllowKittyKeyboardMode();
|
||||
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
|
||||
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
|
||||
_AllowOscNotifications = profile.AllowOscNotifications();
|
||||
_PathTranslationStyle = profile.PathTranslationStyle();
|
||||
_DragDropDelimiter = profile.DragDropDelimiter();
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowKittyKeyboardMode);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtChecksumReport);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtClipboardWrite);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowOscNotifications);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AnswerbackMessage);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
|
||||
|
||||
@@ -142,5 +142,6 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, DragDropDelimiter);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowOscNotifications);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,16 @@
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Allow OSC 777 Desktop Notifications -->
|
||||
<local:SettingContainer x:Name="AllowOscNotifications"
|
||||
x:Uid="Profile_AllowOscNotifications"
|
||||
ClearSettingValue="{x:Bind Profile.ClearAllowOscNotifications}"
|
||||
HasSettingValue="{x:Bind Profile.HasAllowOscNotifications, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.AllowOscNotificationsOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.AllowOscNotifications, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Answerback Message -->
|
||||
<local:SettingContainer x:Name="AnswerbackMessage"
|
||||
x:Uid="Profile_AnswerbackMessage"
|
||||
|
||||
@@ -573,6 +573,14 @@
|
||||
<value>Allow OSC 52 (Manipulate Selection Data) to write to the clipboard</value>
|
||||
<comment>{Locked="OSC 52"}{Locked="Manipulate Selection Data"}Header for a control to toggle support for applications to change the contents of the Windows system clipboard.</comment>
|
||||
</data>
|
||||
<data name="Profile_AllowOscNotifications.Header" xml:space="preserve">
|
||||
<value>Allow OSC 777 (Desktop Notification) to show toast notifications</value>
|
||||
<comment>{Locked="OSC 777"}{Locked="Desktop Notification"}Header for a control to toggle support for applications to display desktop toast notifications via the OSC 777 escape sequence.</comment>
|
||||
</data>
|
||||
<data name="Profile_AllowOscNotifications.HelpText" xml:space="preserve">
|
||||
<value>When enabled, applications can send the OSC 777 escape sequence to trigger a desktop notification with a custom title and body.</value>
|
||||
<comment>{Locked="OSC 777"}Help text for the OSC 777 desktop notification toggle.</comment>
|
||||
</data>
|
||||
<data name="Globals_AllowHeadless.Header" xml:space="preserve">
|
||||
<value>Allow Windows Terminal to run in the background</value>
|
||||
<comment>Header for a control to toggle support for Windows Terminal to run in the background.</comment>
|
||||
|
||||
@@ -108,6 +108,7 @@ Author(s):
|
||||
X(bool, AllowKittyKeyboardMode, "compatibility.kittyKeyboardMode", true) \
|
||||
X(bool, AllowVtChecksumReport, "compatibility.allowDECRQCRA", false) \
|
||||
X(bool, AllowVtClipboardWrite, "compatibility.allowOSC52", true) \
|
||||
X(bool, AllowOscNotifications, "compatibility.allowOSC777", false) \
|
||||
X(bool, AllowKeypadMode, "compatibility.allowDECNKM", false) \
|
||||
X(hstring, DragDropDelimiter, "dragDropDelimiter", L" ") \
|
||||
X(Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, "pathTranslationStyle", Microsoft::Terminal::Control::PathTranslationStyle::None)
|
||||
|
||||
@@ -93,6 +93,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, AllowVtChecksumReport);
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, AllowKeypadMode);
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, AllowOscNotifications);
|
||||
|
||||
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
|
||||
INHERITABLE_PROFILE_SETTING(String, DragDropDelimiter);
|
||||
|
||||
@@ -56,7 +56,8 @@
|
||||
X(bool, RepositionCursorWithMouse, false) \
|
||||
X(bool, RainbowSuggestions) \
|
||||
X(bool, AllowVtChecksumReport) \
|
||||
X(bool, AllowVtClipboardWrite, true)
|
||||
X(bool, AllowVtClipboardWrite, true) \
|
||||
X(bool, AllowOscNotifications, false)
|
||||
|
||||
// --------------------------- Control Settings ---------------------------
|
||||
// All of these settings are defined in IControlSettings.
|
||||
|
||||
@@ -459,3 +459,7 @@ void ConhostInternalGetSet::SearchMissingCommand(std::wstring_view /*missingComm
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
void ConhostInternalGetSet::ShowNotification(std::wstring_view /*title*/, std::wstring_view /*body*/)
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
@@ -74,6 +74,8 @@ public:
|
||||
|
||||
void SearchMissingCommand(std::wstring_view missingCommand) override;
|
||||
|
||||
void ShowNotification(std::wstring_view title, std::wstring_view body) override;
|
||||
|
||||
private:
|
||||
Microsoft::Console::IIoProvider& _io;
|
||||
};
|
||||
|
||||
@@ -336,6 +336,18 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
return sentinel{};
|
||||
}
|
||||
|
||||
typename iterator::value_type next() noexcept
|
||||
{
|
||||
const auto part = value();
|
||||
advance();
|
||||
return part;
|
||||
}
|
||||
|
||||
typename iterator::value_type remaining() noexcept
|
||||
{
|
||||
return { _it, _end };
|
||||
}
|
||||
|
||||
private:
|
||||
bool valid() const noexcept
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
{
|
||||
ChecksumReport,
|
||||
ClipboardWrite,
|
||||
DesktopNotification,
|
||||
};
|
||||
|
||||
#pragma warning(push)
|
||||
@@ -162,6 +163,8 @@ public:
|
||||
virtual void DoVsCodeAction(const std::wstring_view string) = 0;
|
||||
virtual void DoWTAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual void DoUrxvtAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual StringHandler DefineSixelImage(const VTInt macroParameter,
|
||||
const DispatchTypes::SixelBackground backgroundSelect,
|
||||
const VTParameter backgroundColor) = 0; // SIXEL
|
||||
|
||||
@@ -92,5 +92,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
virtual void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) = 0;
|
||||
|
||||
virtual void SearchMissingCommand(const std::wstring_view command) = 0;
|
||||
|
||||
virtual void ShowNotification(const std::wstring_view title, const std::wstring_view body) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3872,6 +3872,41 @@ void AdaptDispatch::DoWTAction(const std::wstring_view string)
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - OSC 777 - Handles urxvt requests. Currently, the only supported request is for desktop notifications.
|
||||
// The format is: OSC 777;notify;title;body ST
|
||||
// Arguments:
|
||||
// - string: contains the parameters that define the notification
|
||||
void AdaptDispatch::DoUrxvtAction(const std::wstring_view string)
|
||||
{
|
||||
if (!_optionalFeatures.test(OptionalFeature::DesktopNotification))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto parts = Utils::SplitString(string, L';');
|
||||
|
||||
if (parts.size() < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
til::split_iterator split{ string, L';' };
|
||||
const auto action = split.next();
|
||||
if (action == L"notify")
|
||||
{
|
||||
// The body is everything after "notify;title;". We can't just use
|
||||
// parts[2] because the body itself may contain semicolons.
|
||||
const auto title = split.next();
|
||||
const auto body = split.remaining();
|
||||
_api.ShowNotification(title, body);
|
||||
}
|
||||
else
|
||||
{
|
||||
_api.UnknownSequence();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - SIXEL - Defines an image transmitted in sixel format via the returned
|
||||
// StringHandler function.
|
||||
|
||||
@@ -163,6 +163,8 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
void DoWTAction(const std::wstring_view string) override;
|
||||
|
||||
void DoUrxvtAction(const std::wstring_view string) override;
|
||||
|
||||
StringHandler DefineSixelImage(const VTInt macroParameter,
|
||||
const DispatchTypes::SixelBackground backgroundSelect,
|
||||
const VTParameter backgroundColor) override; // SIXEL
|
||||
|
||||
@@ -153,6 +153,8 @@ public:
|
||||
|
||||
void DoWTAction(const std::wstring_view /*string*/) override {}
|
||||
|
||||
void DoUrxvtAction(const std::wstring_view /*string*/) override {}
|
||||
|
||||
StringHandler DefineSixelImage(const VTInt /*macroParameter*/,
|
||||
const DispatchTypes::SixelBackground /*backgroundSelect*/,
|
||||
const VTParameter /*backgroundColor*/) override { return nullptr; }; // SIXEL
|
||||
|
||||
@@ -233,6 +233,11 @@ public:
|
||||
Log::Comment(L"SearchMissingCommand MOCK called...");
|
||||
}
|
||||
|
||||
void ShowNotification(const std::wstring_view /*title*/, const std::wstring_view /*body*/) override
|
||||
{
|
||||
Log::Comment(L"ShowNotification MOCK called...");
|
||||
}
|
||||
|
||||
void PrepData()
|
||||
{
|
||||
PrepData(CursorDirection::UP); // if called like this, the cursor direction doesn't matter.
|
||||
|
||||
@@ -909,6 +909,9 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||
_dispatch->DoWTAction(string);
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::UrxvtAction:
|
||||
_dispatch->DoUrxvtAction(string);
|
||||
break;
|
||||
default:
|
||||
_dispatch->UnknownSequence();
|
||||
break;
|
||||
|
||||
@@ -227,6 +227,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
ResetHighlightColor = 117,
|
||||
FinalTermAction = 133,
|
||||
VsCodeAction = 633,
|
||||
UrxvtAction = 777,
|
||||
ITerm2Action = 1337,
|
||||
WTAction = 9001,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user