Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable changing the bell sound #11511

Merged
16 commits merged into from
Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions src/cascadia/TerminalApp/Pane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Wi

winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_focusedBorderBrush = { nullptr };
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr };
winrt::Windows::Media::Playback::MediaPlayer Pane::s_bellPlayer = { nullptr };
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFocused) :
_control{ control },
Expand Down Expand Up @@ -69,6 +70,36 @@ Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFo
_FocusFirstChild();
e.Handled(true);
});

if (!s_bellPlayer)
{
try
{
s_bellPlayer = winrt::Windows::Media::Playback::MediaPlayer();
if (s_bellPlayer)
{
// BODGY
//
// Manually leak a ref to the MediaPlayer we just instantiated.
// We're doing this just like the way we do in AppHost with the
// App itself.
//
// We have to do this because there's some bug in the OS with
// the way a MediaPlayer gets torn down. At time of writing (Nov
// 2021), if you search for `remove_SoundLevelChanged` in the OS
// repo, you'll find a pile of bugs.
//
// We tried moving the MediaPlayer singleton up to the
// TerminalPage, but alas, that teardown had the same problem.
// So _whatever_. We'll leak it here. It needs to last the
// lifetime of the app anyways, and it'll get cleaned up when the
// Terminal is closed, so whatever.
winrt::Windows::Media::Playback::MediaPlayer p{ s_bellPlayer };
::winrt::detach_abi(p);
}
}
CATCH_LOG();
}
}

Pane::Pane(std::shared_ptr<Pane> first,
Expand Down Expand Up @@ -1028,6 +1059,23 @@ void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundatio
}
}

winrt::fire_and_forget Pane::_playBellSound(winrt::Windows::Foundation::Uri uri)
{
auto weakThis{ shared_from_this() };

co_await winrt::resume_foreground(_root.Dispatcher());
if (auto pane{ weakThis.get() })
{
if (s_bellPlayer)
{
const auto source{ winrt::Windows::Media::Core::MediaSource::CreateFromUri(uri) };
const auto item{ winrt::Windows::Media::Playback::MediaPlaybackItem(source) };
s_bellPlayer.Source(item);
s_bellPlayer.Play();
}
}
}

// Method Description:
// - Plays a warning note when triggered by the BEL control character,
// using the sound configured for the "Critical Stop" system event.`
Expand All @@ -1051,8 +1099,18 @@ void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspect
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
{
// Audible is set, play the sound
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
auto sounds{ _profile.BellSound() };
if (sounds && sounds.Size() > 0)
{
winrt::hstring soundPath{ wil::ExpandEnvironmentStringsW<std::wstring>(sounds.GetAt(rand() % sounds.Size()).c_str()) };
winrt::Windows::Foundation::Uri uri{ soundPath };
_playBellSound(uri);
}
else
{
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
}

if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/Pane.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ class Pane : public std::enable_shared_from_this<Pane>

bool _zoomed{ false };

static winrt::Windows::Media::Playback::MediaPlayer s_bellPlayer;

bool _IsLeaf() const noexcept;
bool _HasFocusedChild() const noexcept;
void _SetupChildCloseHandlers();
Expand Down Expand Up @@ -292,6 +294,8 @@ class Pane : public std::enable_shared_from_this<Pane>

SplitState _convertAutomaticOrDirectionalSplitState(const winrt::Microsoft::Terminal::Settings::Model::SplitDirection& splitType) const;

winrt::fire_and_forget _playBellSound(winrt::Windows::Foundation::Uri uri);

// Function Description:
// - Returns true if the given direction can be used with the given split
// type.
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include <winrt/Windows.UI.Xaml.Markup.h>
#include <winrt/Windows.UI.Xaml.Media.h>
#include <winrt/Windows.UI.Xaml.Media.Animation.h>
#include <winrt/Windows.Media.h>
#include <winrt/Windows.Media.Core.h>
#include <winrt/Windows.Media.Playback.h>

#include <winrt/Microsoft.Toolkit.Win32.UI.XamlHost.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
Expand Down
15 changes: 12 additions & 3 deletions src/cascadia/TerminalSettingsModel/JsonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,16 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
val.reserve(json.size());

ConversionTrait<T> trait;
for (const auto& element : json)
if (json.isArray())
{
for (const auto& element : json)
{
val.push_back(trait.FromJson(element));
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}
}
else
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self: this is the place I should just check for null and skip

{
val.push_back(trait.FromJson(element));
val.push_back(trait.FromJson(json));
}

return val;
Expand All @@ -318,7 +325,9 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
bool CanConvert(const Json::Value& json) const
{
ConversionTrait<T> trait;
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) mutable -> bool { return trait.CanConvert(json); });
// If there's only one element provided, then see if we can convert
// that single element into a length-1 array
return (json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) mutable -> bool { return trait.CanConvert(json); })) || trait.CanConvert(json);
}

Json::Value ToJson(const std::vector<T>& val)
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsModel/MTSMSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ Author(s):
X(CloseOnExitMode, CloseOnExit, "closeOnExit", CloseOnExitMode::Graceful) \
X(hstring, TabTitle, "tabTitle") \
X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible) \
X(bool, UseAtlasEngine, "experimental.useAtlasEngine", false)
X(bool, UseAtlasEngine, "experimental.useAtlasEngine", false) \
X(Windows::Foundation::Collections::IVector<winrt::hstring>, BellSound, "bellSound", nullptr)

#define MTSM_FONT_SETTINGS(X) \
X(hstring, FontFace, "face", DEFAULT_FONT_FACE) \
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalSettingsModel/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static constexpr std::string_view FontInfoKey{ "font" };
static constexpr std::string_view PaddingKey{ "padding" };
static constexpr std::string_view TabColorKey{ "tabColor" };
static constexpr std::string_view UnfocusedAppearanceKey{ "unfocusedAppearance" };
static constexpr std::string_view BellSoundKey{ "bellSound" };

Profile::Profile(guid guid) noexcept :
_Guid(guid)
Expand Down Expand Up @@ -104,6 +105,7 @@ winrt::com_ptr<Profile> Profile::CopySettings() const
profile->_Hidden = _Hidden;
profile->_TabColor = _TabColor;
profile->_Padding = _Padding;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this random newline seems unnecessary but meh haha

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that actually seems to be the case with most of this file.

profile->_Origin = _Origin;
profile->_FontInfo = *fontInfo;
profile->_DefaultAppearance = *defaultAppearance;
Expand Down Expand Up @@ -178,6 +180,7 @@ void Profile::LayerJson(const Json::Value& json)

#define PROFILE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
JsonUtils::GetValueForKey(json, jsonKey, _##name);

MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_LAYER_JSON)
#undef PROFILE_SETTINGS_LAYER_JSON

Expand Down Expand Up @@ -318,6 +321,7 @@ Json::Value Profile::ToJson() const

#define PROFILE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
JsonUtils::SetValueForKey(json, jsonKey, _##name);

MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_TO_JSON)
#undef PROFILE_SETTINGS_TO_JSON

Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/Profile.idl
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,6 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_PROFILE_SETTING(Boolean, AltGrAliasing);
INHERITABLE_PROFILE_SETTING(BellStyle, BellStyle);
INHERITABLE_PROFILE_SETTING(Boolean, UseAtlasEngine);
INHERITABLE_PROFILE_SETTING(Windows.Foundation.Collections.IVector<String>, BellSound);
}
}
2 changes: 1 addition & 1 deletion src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ void AppHost::Initialize()
_window->SetContent(_logic.GetRoot());
_window->OnAppInitialized();

// THIS IS A HACK
// BODGY
//
// We've got a weird crash that happens terribly inconsistently, but pretty
// readily on migrie's laptop, only in Debug mode. Apparently, there's some
Expand Down