diff --git a/.github/actions/spell-check/expect/5757ec679b03a4240130c3c53766c91bbc5cd6a7.txt b/.github/actions/spell-check/expect/5757ec679b03a4240130c3c53766c91bbc5cd6a7.txt
index 9f713a5ff52..696b9b1e499 100644
--- a/.github/actions/spell-check/expect/5757ec679b03a4240130c3c53766c91bbc5cd6a7.txt
+++ b/.github/actions/spell-check/expect/5757ec679b03a4240130c3c53766c91bbc5cd6a7.txt
@@ -1 +1 @@
-renamer
\ No newline at end of file
+renamer
diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt
index 55298a2bdec..9bb806aa3f4 100644
--- a/.github/actions/spell-check/expect/expect.txt
+++ b/.github/actions/spell-check/expect/expect.txt
@@ -2829,4 +2829,4 @@ zy
AAAAABBBBBBCCC
AAAAA
BBBBBCCC
-abcd
\ No newline at end of file
+abcd
diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
index 698d5861285..7690b12d085 100644
--- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
+++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
@@ -1,17 +1,17 @@
-
@@ -488,4 +488,19 @@
Back
-
+
+ OK
+
+
+ Debug
+
+
+ Error
+
+
+ Information
+
+
+ Warning
+
+
\ No newline at end of file
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index d476a906f0a..4b1cba8fa73 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -1121,6 +1121,8 @@ namespace winrt::TerminalApp::implementation
// - hostingTab: The Tab that's hosting this TermControl instance
void TerminalPage::_RegisterTerminalEvents(TermControl term, TerminalTab& hostingTab)
{
+ term.RaiseNotice({ this, &TerminalPage::_ControlNoticeRaisedHandler });
+
// Add an event handler when the terminal's selection wants to be copied.
// When the text buffer data is retrieved, we'll copy the data into the Clipboard
term.CopyToClipboard({ this, &TerminalPage::_CopyToClipboardHandler });
@@ -1928,6 +1930,48 @@ namespace winrt::TerminalApp::implementation
}
}
+ void TerminalPage::_ControlNoticeRaisedHandler(const IInspectable /*sender*/, const Microsoft::Terminal::TerminalControl::NoticeEventArgs eventArgs)
+ {
+ winrt::hstring message = eventArgs.Message();
+
+ winrt::hstring title;
+
+ switch (eventArgs.Level())
+ {
+ case TerminalControl::NoticeLevel::Debug:
+ title = RS_(L"NoticeDebug"); //\xebe8
+ break;
+ case TerminalControl::NoticeLevel::Info:
+ title = RS_(L"NoticeInfo"); // \xe946
+ break;
+ case TerminalControl::NoticeLevel::Warning:
+ title = RS_(L"NoticeWarning"); //\xe7ba
+ break;
+ case TerminalControl::NoticeLevel::Error:
+ title = RS_(L"NoticeError"); //\xe783
+ break;
+ }
+
+ _ShowControlNoticeDialog(title, message);
+ }
+
+ void TerminalPage::_ShowControlNoticeDialog(const winrt::hstring& title, const winrt::hstring& message)
+ {
+ if (auto presenter{ _dialogPresenter.get() })
+ {
+ // FindName needs to be called first to actually load the xaml object
+ auto controlNoticeDialog = FindName(L"ControlNoticeDialog").try_as();
+
+ ControlNoticeDialog().Title(winrt::box_value(title));
+
+ // Insert the message
+ NoticeMessage().Text(message);
+
+ // Show the dialog
+ presenter.ShowDialog(controlNoticeDialog);
+ }
+ }
+
// Method Description:
// - Copy text from the focused terminal to the Windows Clipboard
// Arguments:
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index 65d318cadc6..5275227f613 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -197,6 +197,9 @@ namespace winrt::TerminalApp::implementation
void _PasteText();
+ void _ControlNoticeRaisedHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::NoticeEventArgs eventArgs);
+ void _ShowControlNoticeDialog(const winrt::hstring& title, const winrt::hstring& message);
+
fire_and_forget _LaunchSettings(const Microsoft::Terminal::Settings::Model::SettingsTarget target);
void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
diff --git a/src/cascadia/TerminalApp/TerminalPage.xaml b/src/cascadia/TerminalApp/TerminalPage.xaml
index 4e3e2b5b16f..ae5c242a9d4 100644
--- a/src/cascadia/TerminalApp/TerminalPage.xaml
+++ b/src/cascadia/TerminalApp/TerminalPage.xaml
@@ -69,6 +69,16 @@ the MIT License. See LICENSE in the project root for license information. -->
DefaultButton="Primary">
+
+
+
+
+
+
-
@@ -178,4 +178,12 @@
Ctrl+Click to follow link
-
+
+ Unable to find the selected font "{0}".
+
+"{1}" has been selected instead.
+
+Please either install the missing font or choose another one.
+ 0 and 1 are names of fonts provided by the user and system respectively.
+
+
\ No newline at end of file
diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp
index ffc6aeb0f69..1711b2fef0e 100644
--- a/src/cascadia/TerminalControl/TermControl.cpp
+++ b/src/cascadia/TerminalControl/TermControl.cpp
@@ -1987,6 +1987,33 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// actually fail. We need a way to gracefully fallback.
_renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont);
+ // If the actual font isn't what was requested...
+ if (_actualFont.GetFaceName() != _desiredFont.GetFaceName())
+ {
+ // Then warn the user that we picked something because we couldn't find their font.
+
+ // Format message with user's choice of font and the font that was chosen instead.
+ const winrt::hstring message{ fmt::format(std::wstring_view{ RS_(L"NoticeFontNotFound") }, _desiredFont.GetFaceName(), _actualFont.GetFaceName()) };
+
+ // Capture what we need to resume later.
+ [strongThis = get_strong(), message]() -> winrt::fire_and_forget {
+ // Take these out of the lambda and store them locally
+ // because the coroutine will lose them into space
+ // by the time it resumes.
+ const auto msg = message;
+ const auto strong = strongThis;
+
+ // Pop the rest of this function to the tail of the UI thread
+ // Just in case someone was holding a lock when they called us and
+ // the handlers decide to do something that take another lock
+ // (like ShellExecute pumping our messaging thread...GH#7994)
+ co_await strong->Dispatcher();
+
+ auto noticeArgs = winrt::make(NoticeLevel::Warning, std::move(msg));
+ strong->_raiseNoticeHandlers(*strong, std::move(noticeArgs));
+ }();
+ }
+
const auto actualNewSize = _actualFont.GetSize();
_fontSizeChangedHandlers(actualNewSize.X, actualNewSize.Y, initialUpdate);
}
@@ -3074,5 +3101,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs);
+ DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, RaiseNotice, _raiseNoticeHandlers, TerminalControl::TermControl, TerminalControl::NoticeEventArgs);
// clang-format on
}
diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h
index cc7601f728d..c5dcd819f6c 100644
--- a/src/cascadia/TerminalControl/TermControl.h
+++ b/src/cascadia/TerminalControl/TermControl.h
@@ -7,6 +7,7 @@
#include "CopyToClipboardEventArgs.g.h"
#include "PasteFromClipboardEventArgs.g.h"
#include "OpenHyperlinkEventArgs.g.h"
+#include "NoticeEventArgs.g.h"
#include
#include "../../renderer/base/Renderer.hpp"
#include "../../renderer/dx/DxRenderer.hpp"
@@ -81,6 +82,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
hstring _uri;
};
+ struct NoticeEventArgs :
+ public NoticeEventArgsT
+ {
+ public:
+ NoticeEventArgs(const NoticeLevel level, const hstring& message) :
+ _level(level),
+ _message(message) {}
+
+ NoticeLevel Level() { return _level; };
+ hstring Message() { return _message; };
+
+ private:
+ const NoticeLevel _level;
+ const hstring _message;
+ };
+
struct TermControl : TermControlT
{
TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection);
@@ -150,6 +167,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs);
+ DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(RaiseNotice, _raiseNoticeHandlers, TerminalControl::TermControl, TerminalControl::NoticeEventArgs);
TYPED_EVENT(WarningBell, IInspectable, IInspectable);
TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable);
diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl
index d8bc580e0e9..f1cfcef3bf1 100644
--- a/src/cascadia/TerminalControl/TermControl.idl
+++ b/src/cascadia/TerminalControl/TermControl.idl
@@ -45,6 +45,20 @@ namespace Microsoft.Terminal.TerminalControl
String Uri { get; };
}
+ enum NoticeLevel
+ {
+ Debug = 10,
+ Info = 20,
+ Warning = 30,
+ Error = 40,
+ };
+
+ runtimeclass NoticeEventArgs
+ {
+ NoticeLevel Level { get; };
+ String Message { get; };
+ }
+
[default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener
{
TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
@@ -60,6 +74,7 @@ namespace Microsoft.Terminal.TerminalControl
event Windows.Foundation.TypedEventHandler CopyToClipboard;
event Windows.Foundation.TypedEventHandler PasteFromClipboard;
event Windows.Foundation.TypedEventHandler OpenHyperlink;
+ event Windows.Foundation.TypedEventHandler RaiseNotice;
event Windows.Foundation.TypedEventHandler