diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 8dc7142a3f0..66b65dfdfcc 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -8,6 +8,7 @@ #include "AppLogic.h" #include "../../types/inc/utils.hpp" +#include #include #include "TerminalPage.g.cpp" @@ -1141,6 +1142,8 @@ namespace winrt::TerminalApp::implementation // Add an event handler when the terminal wants to paste data from the Clipboard. term.PasteFromClipboard({ this, &TerminalPage::_PasteFromClipboardHandler }); + term.WarningBell({ this, &TerminalPage::_WarningBellHandler }); + term.OpenHyperlink({ this, &TerminalPage::_OpenHyperlinkHandler }); // Bind Tab events to the TermControl and the Tab's Pane @@ -1801,6 +1804,18 @@ namespace winrt::TerminalApp::implementation CATCH_LOG(); } + // Method Description: + // - Plays a warning note when triggered by the BEL control character, + // using the sound configured for the "Critical Stop" system event. + // This matches the behavior of the Windows Console host. + // Arguments: + // - + void TerminalPage::_WarningBellHandler(const IInspectable sender, const IInspectable eventArgs) + { + const auto soundAlias = reinterpret_cast(SND_ALIAS_SYSTEMHAND); + PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY); + } + void TerminalPage::_OpenHyperlinkHandler(const IInspectable /*sender*/, const Microsoft::Terminal::TerminalControl::OpenHyperlinkEventArgs eventArgs) { try diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 540921c0c23..4874627b10c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -176,6 +176,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget _PasteFromClipboardHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs); + void _WarningBellHandler(const IInspectable sender, const IInspectable eventArgs); void _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::OpenHyperlinkEventArgs eventArgs); void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri); bool _CopyText(const bool singleLine, const Windows::Foundation::IReference& formats); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index a44ee4c0586..684387f46d3 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -82,6 +82,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>(); + auto pfnWarningBell = std::bind(&TermControl::_TerminalWarningBell, this); + _terminal->SetWarningBellCallback(pfnWarningBell); + auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1); _terminal->SetTitleChangedCallback(pfnTitleChanged); @@ -2127,6 +2130,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } } + void TermControl::_TerminalWarningBell() + { + _WarningBellHandlers(*this, nullptr); + } + void TermControl::_TerminalTitleChanged(const std::wstring_view& wstr) { _titleChangedHandlers(winrt::hstring{ wstr }); diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index c2c46d01d66..ff52dac344d 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -149,6 +149,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); + TYPED_EVENT(WarningBell, IInspectable, IInspectable); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); TYPED_EVENT(Initialized, TerminalControl::TermControl, Windows::UI::Xaml::RoutedEventArgs); TYPED_EVENT(TabColorChanged, IInspectable, IInspectable); @@ -259,6 +260,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _SwapChainScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel const& sender, Windows::Foundation::IInspectable const& args); void _DoResizeUnderLock(const double newWidth, const double newHeight); void _RefreshSizeUnderLock(); + void _TerminalWarningBell(); void _TerminalTitleChanged(const std::wstring_view& wstr); void _TerminalTabColorChanged(const std::optional color); void _CopyToClipboard(const std::wstring_view& wstr); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 8c570838b82..d8bc580e0e9 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -60,6 +60,7 @@ namespace Microsoft.Terminal.TerminalControl event Windows.Foundation.TypedEventHandler CopyToClipboard; event Windows.Foundation.TypedEventHandler PasteFromClipboard; event Windows.Foundation.TypedEventHandler OpenHyperlink; + event Windows.Foundation.TypedEventHandler WarningBell; event Windows.Foundation.TypedEventHandler Initialized; // This is an event handler forwarder for the underlying connection. diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index 9661a2db51d..fda9cef77cc 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -34,6 +34,7 @@ namespace Microsoft::Terminal::Core virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept = 0; virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept = 0; + virtual bool WarningBell() noexcept = 0; virtual bool SetWindowTitle(std::wstring_view title) noexcept = 0; virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept = 0; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index f7a9acab759..f3c55d5c84e 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -965,6 +965,11 @@ void Terminal::SetWriteInputCallback(std::function pfn) noe _pfnWriteInput.swap(pfn); } +void Terminal::SetWarningBellCallback(std::function pfn) noexcept +{ + _pfnWarningBell.swap(pfn); +} + void Terminal::SetTitleChangedCallback(std::function pfn) noexcept { _pfnTitleChanged.swap(pfn); diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index accc7a2797d..ff565cba536 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -90,6 +90,7 @@ class Microsoft::Terminal::Core::Terminal final : bool EraseCharacters(const size_t numChars) noexcept override; bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override; bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override; + bool WarningBell() noexcept override; bool SetWindowTitle(std::wstring_view title) noexcept override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override; @@ -175,6 +176,7 @@ class Microsoft::Terminal::Core::Terminal final : #pragma endregion void SetWriteInputCallback(std::function pfn) noexcept; + void SetWarningBellCallback(std::function pfn) noexcept; void SetTitleChangedCallback(std::function pfn) noexcept; void SetTabColorChangedCallback(std::function)> pfn) noexcept; void SetCopyToClipboardCallback(std::function pfn) noexcept; @@ -205,6 +207,7 @@ class Microsoft::Terminal::Core::Terminal final : private: std::function _pfnWriteInput; + std::function _pfnWarningBell; std::function _pfnTitleChanged; std::function _pfnCopyToClipboard; std::function _pfnScrollPositionChanged; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 9a7e896fe95..00c39d25bcc 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -345,6 +345,14 @@ try } CATCH_LOG_RETURN_FALSE() +bool Terminal::WarningBell() noexcept +try +{ + _pfnWarningBell(); + return true; +} +CATCH_LOG_RETURN_FALSE() + bool Terminal::SetWindowTitle(std::wstring_view title) noexcept try { diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 06874b38889..0db4a539f08 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -109,6 +109,13 @@ try } CATCH_LOG_RETURN_FALSE() +bool TerminalDispatch::WarningBell() noexcept +try +{ + return _terminalApi.WarningBell(); +} +CATCH_LOG_RETURN_FALSE() + bool TerminalDispatch::CarriageReturn() noexcept try { diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 993433f43f2..77458ea876d 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -30,6 +30,7 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc bool LineFeed(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::LineFeedType lineFeedType) noexcept override; bool EraseCharacters(const size_t numChars) noexcept override; + bool WarningBell() noexcept override; bool CarriageReturn() noexcept override; bool SetWindowTitle(std::wstring_view title) noexcept override;