Add a setting for sending a notification on BEL (#20011)

## Summary of the Pull Request
Targets #20010 

Adds another `bellStyle` flag option. This sends a windows toast
notification to the user when a BEL is encountered

- [X] Closes #18605 
- [ ] Documentation updated

Heavily based on #19936 
Co-authored by @zadjii-msft
This commit is contained in:
Carlos Zamora
2026-05-04 10:38:17 -07:00
committed by GitHub
parent 059986ebce
commit a834313fb7
12 changed files with 43 additions and 8 deletions

View File

@@ -60,7 +60,8 @@
"enum": [
"audible",
"window",
"taskbar"
"taskbar",
"notification"
]
}
},
@@ -70,6 +71,7 @@
"audible",
"taskbar",
"window",
"notification",
"all",
"none"
]

View File

@@ -14,6 +14,7 @@ namespace TerminalApp
runtimeclass BellEventArgs
{
Boolean FlashTaskbar { get; };
Boolean SendNotification { get; };
};
runtimeclass NotificationEventArgs

View File

@@ -1148,6 +1148,14 @@ namespace winrt::TerminalApp::implementation
tab->TabRaiseVisualBell.raise();
}
// Send a desktop toast notification if requested, but only if
// the pane isn't already in the belled state. This prevents
// sending repeated toasts for repeated BEL characters.
if (bellArgs.SendNotification() && !tab->_tabStatus.BellIndicator())
{
tab->TabToastNotificationRequested.raise(tab->Title(), L"", sender);
}
// Show the bell indicator in the tab header
tab->ShowBellIndicator(true);

View File

@@ -291,9 +291,11 @@ namespace winrt::TerminalApp::implementation
_control.BellLightOn();
}
// raise the event with the bool value corresponding to the taskbar flag
// raise the event with the bool values corresponding to the taskbar and notification flags
BellRequested.raise(*this,
*winrt::make_self<TerminalApp::implementation::BellEventArgs>(WI_IsFlagSet(_profile.BellStyle(), BellStyle::Taskbar)));
*winrt::make_self<TerminalApp::implementation::BellEventArgs>(
WI_IsFlagSet(_profile.BellStyle(), BellStyle::Taskbar),
WI_IsFlagSet(_profile.BellStyle(), BellStyle::Notification)));
}
}
}

View File

@@ -14,10 +14,11 @@ namespace winrt::TerminalApp::implementation
struct BellEventArgs : public BellEventArgsT<BellEventArgs>
{
public:
BellEventArgs(bool flashTaskbar) :
FlashTaskbar(flashTaskbar) {}
BellEventArgs(bool flashTaskbar, bool sendNotification) :
FlashTaskbar(flashTaskbar), SendNotification(sendNotification) {}
til::property<bool> FlashTaskbar;
til::property<bool> SendNotification;
};
struct NotificationEventArgs : public NotificationEventArgsT<NotificationEventArgs>

View File

@@ -574,7 +574,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
hstring ProfileViewModel::BellStylePreview() const
{
const auto bellStyle = BellStyle();
if (WI_AreAllFlagsSet(bellStyle, BellStyle::Audible | BellStyle::Window | BellStyle::Taskbar))
if (WI_AreAllFlagsSet(bellStyle, BellStyle::Audible | BellStyle::Window | BellStyle::Taskbar | BellStyle::Notification))
{
return RS_(L"Profile_BellStyleAll/Content");
}
@@ -584,7 +584,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
std::vector<hstring> resultList;
resultList.reserve(3);
resultList.reserve(4);
if (WI_IsFlagSet(bellStyle, BellStyle::Audible))
{
resultList.emplace_back(RS_(L"Profile_BellStyleAudible/Content"));
@@ -597,6 +597,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
resultList.emplace_back(RS_(L"Profile_BellStyleTaskbar/Content"));
}
if (WI_IsFlagSet(bellStyle, BellStyle::Notification))
{
resultList.emplace_back(RS_(L"Profile_BellStyleNotification/Content"));
}
// add in the commas
hstring result{};
@@ -640,6 +644,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
BellStyle(currentStyle);
}
void ProfileViewModel::SetBellStyleNotification(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = BellStyle();
WI_UpdateFlag(currentStyle, Model::BellStyle::Notification, winrt::unbox_value<bool>(on));
BellStyle(currentStyle);
}
// Method Description:
// - Construct _CurrentBellSounds by importing the _inherited_ value from the model
// - Adds a PropertyChanged handler to each BellSoundViewModel to propagate changes to the model

View File

@@ -46,6 +46,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void SetBellStyleAudible(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleWindow(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleNotification(winrt::Windows::Foundation::IReference<bool> on);
hstring BellSoundPreview();
void RequestAddBellSound(hstring path);

View File

@@ -49,6 +49,7 @@ namespace Microsoft.Terminal.Settings.Editor
void SetBellStyleAudible(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleWindow(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleNotification(Windows.Foundation.IReference<Boolean> on);
String BellSoundPreview { get; };
Windows.Foundation.Collections.IObservableVector<BellSoundViewModel> CurrentBellSounds { get; };

View File

@@ -111,6 +111,8 @@
IsChecked="{x:Bind Profile.IsBellStyleFlagSet(2), BindBack=Profile.SetBellStyleWindow, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_BellStyleTaskbar"
IsChecked="{x:Bind Profile.IsBellStyleFlagSet(4), BindBack=Profile.SetBellStyleTaskbar, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_BellStyleNotification"
IsChecked="{x:Bind Profile.IsBellStyleFlagSet(8), BindBack=Profile.SetBellStyleNotification, Mode=TwoWay}" />
</StackPanel>
</local:SettingContainer>

View File

@@ -1553,6 +1553,10 @@
<value>Flash window</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Desktop notification</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Add new</value>
<comment>Button label that creates a new color scheme.</comment>

View File

@@ -29,6 +29,7 @@ namespace Microsoft.Terminal.Settings.Model
Audible = 0x1,
Window = 0x2,
Taskbar = 0x4,
Notification = 0x8,
All = 0xffffffff
};

View File

@@ -90,12 +90,13 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Core::MatchMode)
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::BellStyle)
{
static constexpr std::array<pair_type, 6> mappings = {
static constexpr std::array<pair_type, 7> mappings = {
pair_type{ "none", AllClear },
pair_type{ "audible", ValueType::Audible },
pair_type{ "visual", ValueType::Window | ValueType::Taskbar },
pair_type{ "window", ValueType::Window },
pair_type{ "taskbar", ValueType::Taskbar },
pair_type{ "notification", ValueType::Notification },
pair_type{ "all", AllSet },
};