Compare commits
12 commits
main
...
dev/migrie
Author | SHA1 | Date | |
---|---|---|---|
93937533bc | |||
02344048de | |||
fb1ed58d37 | |||
2eda14cc1b | |||
684956d848 | |||
9f4ed0ee18 | |||
2c895b2c18 | |||
0bb42efc0d | |||
cc9487e2b8 | |||
4c4fde9da3 | |||
8fbd32d3c3 | |||
be11388a04 |
|
@ -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_focusedBorderBrush = { nullptr };
|
||||||
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr };
|
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr };
|
||||||
|
winrt::Windows::Media::Playback::MediaPlayer Pane::s_bellPlayer = { nullptr };
|
||||||
|
|
||||||
Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFocused) :
|
Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFocused) :
|
||||||
_control{ control },
|
_control{ control },
|
||||||
|
@ -69,6 +70,36 @@ Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFo
|
||||||
_FocusFirstChild();
|
_FocusFirstChild();
|
||||||
e.Handled(true);
|
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 fo 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
|
||||||
|
// lifetim of the app anyways, and it'll get cleaned up when the
|
||||||
|
// Termnial 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,
|
Pane::Pane(std::shared_ptr<Pane> first,
|
||||||
|
@ -1108,6 +1139,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)
|
||||||
|
{
|
||||||
|
auto source{ winrt::Windows::Media::Core::MediaSource::CreateFromUri(uri) };
|
||||||
|
auto item{ winrt::Windows::Media::Playback::MediaPlaybackItem(source) };
|
||||||
|
s_bellPlayer.Source(item);
|
||||||
|
s_bellPlayer.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Plays a warning note when triggered by the BEL control character,
|
// - Plays a warning note when triggered by the BEL control character,
|
||||||
// using the sound configured for the "Critical Stop" system event.`
|
// using the sound configured for the "Critical Stop" system event.`
|
||||||
|
@ -1131,8 +1179,18 @@ void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspect
|
||||||
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
|
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
|
||||||
{
|
{
|
||||||
// Audible is set, play the sound
|
// Audible is set, play the sound
|
||||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
auto sounds{ _profile.BellSound() };
|
||||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
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))
|
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
|
||||||
|
|
|
@ -229,6 +229,8 @@ private:
|
||||||
|
|
||||||
bool _zoomed{ false };
|
bool _zoomed{ false };
|
||||||
|
|
||||||
|
static winrt::Windows::Media::Playback::MediaPlayer s_bellPlayer;
|
||||||
|
|
||||||
bool _IsLeaf() const noexcept;
|
bool _IsLeaf() const noexcept;
|
||||||
bool _HasFocusedChild() const noexcept;
|
bool _HasFocusedChild() const noexcept;
|
||||||
void _SetupChildCloseHandlers();
|
void _SetupChildCloseHandlers();
|
||||||
|
@ -282,6 +284,8 @@ private:
|
||||||
|
|
||||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> _preCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> _preCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
||||||
|
|
||||||
|
winrt::fire_and_forget _playBellSound(winrt::Windows::Foundation::Uri uri);
|
||||||
|
|
||||||
// Function Description:
|
// Function Description:
|
||||||
// - Returns true if the given direction can be used with the given split
|
// - Returns true if the given direction can be used with the given split
|
||||||
// type.
|
// type.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
//
|
//
|
||||||
// pch.h
|
// pch.h
|
||||||
|
@ -45,6 +45,9 @@
|
||||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Media.h>
|
#include <winrt/Windows.UI.Xaml.Media.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Media.Animation.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.Toolkit.Win32.UI.XamlHost.h>
|
||||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||||
|
|
|
@ -307,9 +307,16 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||||
val.reserve(json.size());
|
val.reserve(json.size());
|
||||||
|
|
||||||
ConversionTrait<T> trait;
|
ConversionTrait<T> trait;
|
||||||
for (const auto& element : json)
|
if (json.isArray())
|
||||||
{
|
{
|
||||||
val.push_back(trait.FromJson(element));
|
for (const auto& element : json)
|
||||||
|
{
|
||||||
|
val.push_back(trait.FromJson(element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val.push_back(trait.FromJson(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
|
@ -318,7 +325,9 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||||
bool CanConvert(const Json::Value& json) const
|
bool CanConvert(const Json::Value& json) const
|
||||||
{
|
{
|
||||||
ConversionTrait<T> trait;
|
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)
|
Json::Value ToJson(const std::vector<T>& val)
|
||||||
|
|
|
@ -74,7 +74,8 @@ Author(s):
|
||||||
X(CloseOnExitMode, CloseOnExit, "closeOnExit", CloseOnExitMode::Graceful) \
|
X(CloseOnExitMode, CloseOnExit, "closeOnExit", CloseOnExitMode::Graceful) \
|
||||||
X(hstring, TabTitle, "tabTitle") \
|
X(hstring, TabTitle, "tabTitle") \
|
||||||
X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible) \
|
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) \
|
#define MTSM_FONT_SETTINGS(X) \
|
||||||
X(hstring, FontFace, "face", DEFAULT_FONT_FACE) \
|
X(hstring, FontFace, "face", DEFAULT_FONT_FACE) \
|
||||||
|
|
|
@ -30,6 +30,7 @@ static constexpr std::string_view FontInfoKey{ "font" };
|
||||||
static constexpr std::string_view PaddingKey{ "padding" };
|
static constexpr std::string_view PaddingKey{ "padding" };
|
||||||
static constexpr std::string_view TabColorKey{ "tabColor" };
|
static constexpr std::string_view TabColorKey{ "tabColor" };
|
||||||
static constexpr std::string_view UnfocusedAppearanceKey{ "unfocusedAppearance" };
|
static constexpr std::string_view UnfocusedAppearanceKey{ "unfocusedAppearance" };
|
||||||
|
static constexpr std::string_view BellSoundKey{ "bellSound" };
|
||||||
|
|
||||||
Profile::Profile(guid guid) noexcept :
|
Profile::Profile(guid guid) noexcept :
|
||||||
_Guid(guid)
|
_Guid(guid)
|
||||||
|
@ -104,6 +105,7 @@ winrt::com_ptr<Profile> Profile::CopySettings() const
|
||||||
profile->_Hidden = _Hidden;
|
profile->_Hidden = _Hidden;
|
||||||
profile->_TabColor = _TabColor;
|
profile->_TabColor = _TabColor;
|
||||||
profile->_Padding = _Padding;
|
profile->_Padding = _Padding;
|
||||||
|
|
||||||
profile->_Origin = _Origin;
|
profile->_Origin = _Origin;
|
||||||
profile->_FontInfo = *fontInfo;
|
profile->_FontInfo = *fontInfo;
|
||||||
profile->_DefaultAppearance = *defaultAppearance;
|
profile->_DefaultAppearance = *defaultAppearance;
|
||||||
|
@ -178,6 +180,7 @@ void Profile::LayerJson(const Json::Value& json)
|
||||||
|
|
||||||
#define PROFILE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
#define PROFILE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
||||||
JsonUtils::GetValueForKey(json, jsonKey, _##name);
|
JsonUtils::GetValueForKey(json, jsonKey, _##name);
|
||||||
|
|
||||||
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_LAYER_JSON)
|
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_LAYER_JSON)
|
||||||
#undef PROFILE_SETTINGS_LAYER_JSON
|
#undef PROFILE_SETTINGS_LAYER_JSON
|
||||||
|
|
||||||
|
@ -318,6 +321,7 @@ Json::Value Profile::ToJson() const
|
||||||
|
|
||||||
#define PROFILE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
|
#define PROFILE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
|
||||||
JsonUtils::SetValueForKey(json, jsonKey, _##name);
|
JsonUtils::SetValueForKey(json, jsonKey, _##name);
|
||||||
|
|
||||||
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_TO_JSON)
|
MTSM_PROFILE_SETTINGS(PROFILE_SETTINGS_TO_JSON)
|
||||||
#undef PROFILE_SETTINGS_TO_JSON
|
#undef PROFILE_SETTINGS_TO_JSON
|
||||||
|
|
||||||
|
|
|
@ -80,5 +80,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
INHERITABLE_PROFILE_SETTING(Boolean, AltGrAliasing);
|
INHERITABLE_PROFILE_SETTING(Boolean, AltGrAliasing);
|
||||||
INHERITABLE_PROFILE_SETTING(BellStyle, BellStyle);
|
INHERITABLE_PROFILE_SETTING(BellStyle, BellStyle);
|
||||||
INHERITABLE_PROFILE_SETTING(Boolean, UseAtlasEngine);
|
INHERITABLE_PROFILE_SETTING(Boolean, UseAtlasEngine);
|
||||||
|
INHERITABLE_PROFILE_SETTING(Windows.Foundation.Collections.IVector<String>, BellSound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ void AppHost::Initialize()
|
||||||
_window->SetContent(_logic.GetRoot());
|
_window->SetContent(_logic.GetRoot());
|
||||||
_window->OnAppInitialized();
|
_window->OnAppInitialized();
|
||||||
|
|
||||||
// THIS IS A HACK
|
// BODGY
|
||||||
//
|
//
|
||||||
// We've got a weird crash that happens terribly inconsistently, but pretty
|
// 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
|
// readily on migrie's laptop, only in Debug mode. Apparently, there's some
|
||||||
|
|
Loading…
Reference in a new issue