Compare commits
7 commits
main
...
v1.9.1523.
Author | SHA1 | Date | |
---|---|---|---|
fd06b0ce60 | |||
c8ac63e78e | |||
414adf16a9 | |||
3533aa2661 | |||
fbc59b7a3b | |||
30f1c64e08 | |||
d9c93430a0 |
|
@ -1206,7 +1206,7 @@ namespace winrt::TerminalApp::implementation
|
|||
// in and be routed to an event with no handlers or a non-ready Page.
|
||||
if (_appArgs.IsHandoffListener())
|
||||
{
|
||||
SetInboundListener();
|
||||
_root->SetInboundListener(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1222,7 @@ namespace winrt::TerminalApp::implementation
|
|||
// - <none>
|
||||
void AppLogic::SetInboundListener()
|
||||
{
|
||||
_root->SetInboundListener();
|
||||
_root->SetInboundListener(false);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -165,6 +165,7 @@ namespace winrt::TerminalApp::implementation
|
|||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(IsQuakeWindowChanged, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IsQuakeWindowChanged);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class TerminalAppLocalTests::CommandlineTest;
|
||||
|
|
|
@ -92,5 +92,6 @@ namespace TerminalApp
|
|||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SettingsChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -329,6 +329,7 @@ void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundatio
|
|||
}
|
||||
|
||||
const auto newConnectionState = _control.ConnectionState();
|
||||
const auto previousConnectionState = std::exchange(_connectionState, newConnectionState);
|
||||
|
||||
if (newConnectionState < ConnectionState::Closed)
|
||||
{
|
||||
|
@ -336,6 +337,14 @@ void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundatio
|
|||
return;
|
||||
}
|
||||
|
||||
if (previousConnectionState < ConnectionState::Connected && newConnectionState >= ConnectionState::Failed)
|
||||
{
|
||||
// A failure to complete the connection (before it has _connected_) is not covered by "closeOnExit".
|
||||
// This is to prevent a misconfiguration (closeOnExit: always, startingDirectory: garbage) resulting
|
||||
// in Terminal flashing open and immediately closed.
|
||||
return;
|
||||
}
|
||||
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
auto paneProfile = settings.FindProfile(_profile.value());
|
||||
if (paneProfile)
|
||||
|
@ -709,6 +718,7 @@ void Pane::_CloseChild(const bool closeFirst)
|
|||
|
||||
// take the control, profile and id of the pane that _wasn't_ closed.
|
||||
_control = remainingChild->_control;
|
||||
_connectionState = remainingChild->_connectionState;
|
||||
_profile = remainingChild->_profile;
|
||||
_id = remainingChild->Id();
|
||||
|
||||
|
@ -1476,6 +1486,7 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitState
|
|||
// Move our control, guid into the first one.
|
||||
// Move the new guid, control into the second.
|
||||
_firstChild = std::make_shared<Pane>(_profile.value(), _control);
|
||||
_firstChild->_connectionState = std::exchange(_connectionState, ConnectionState::NotConnected);
|
||||
_profile = std::nullopt;
|
||||
_control = { nullptr };
|
||||
_secondChild = std::make_shared<Pane>(profile, control);
|
||||
|
|
|
@ -95,6 +95,7 @@ private:
|
|||
winrt::Windows::UI::Xaml::Controls::Grid _root{};
|
||||
winrt::Windows::UI::Xaml::Controls::Border _border{};
|
||||
winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr };
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
|
||||
static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_focusedBorderBrush;
|
||||
static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_unfocusedBorderBrush;
|
||||
|
||||
|
|
|
@ -356,7 +356,27 @@ namespace winrt::TerminalApp::implementation
|
|||
// we would be left with an empty terminal frame with no tabs.
|
||||
// Instead, crash out so COM sees the server die and things unwind
|
||||
// without a weird empty frame window.
|
||||
CATCH_FAIL_FAST()
|
||||
catch (...)
|
||||
{
|
||||
// However, we cannot always fail fast because of MSFT:33501832. Sometimes the COM catalog
|
||||
// tears the state between old and new versions and fails here for that reason.
|
||||
// As we're always becoming an inbound server in the monarch, even when COM didn't strictly
|
||||
// ask us yet...we might just crash always.
|
||||
// Instead... we're going to differentiate. If COM started us... we will fail fast
|
||||
// so it sees the process die and falls back.
|
||||
// If we were just starting normally as a Monarch and opportunistically listening for
|
||||
// inbound connections... then we'll just log the failure and move on assuming
|
||||
// the version state is torn and will fix itself whenever the packaging upgrade
|
||||
// tasks decide to clean up.
|
||||
if (_isEmbeddingInboundListener)
|
||||
{
|
||||
FAIL_FAST_CAUGHT_EXCEPTION();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1981,12 +2001,13 @@ namespace winrt::TerminalApp::implementation
|
|||
// listener for command-line tools attempting to join this Terminal
|
||||
// through the default application channel.
|
||||
// Arguments:
|
||||
// - <none> - Implicitly sets to true. Default page state is false.
|
||||
// - isEmbedding - True if COM started us to be a server. False if we're doing it of our own accord.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::SetInboundListener()
|
||||
void TerminalPage::SetInboundListener(bool isEmbedding)
|
||||
{
|
||||
_shouldStartInboundListener = true;
|
||||
_isEmbeddingInboundListener = isEmbedding;
|
||||
|
||||
// If the page has already passed the NotInitialized state,
|
||||
// then it is ready-enough for us to just start this immediately.
|
||||
|
@ -2319,6 +2340,9 @@ namespace winrt::TerminalApp::implementation
|
|||
{
|
||||
// TODO: GH 9458 will give us more context so we can try to choose a better profile.
|
||||
_OpenNewTab(nullptr, connection);
|
||||
|
||||
// Request a summon of this window to the foreground
|
||||
_SummonWindowRequestedHandlers(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace winrt::TerminalApp::implementation
|
|||
bool AlwaysOnTop() const;
|
||||
|
||||
void SetStartupActions(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);
|
||||
void SetInboundListener();
|
||||
void SetInboundListener(bool isEmbedding);
|
||||
static std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> ConvertExecuteCommandlineToActions(const Microsoft::Terminal::Settings::Model::ExecuteCommandlineArgs& args);
|
||||
|
||||
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
||||
|
@ -124,6 +124,7 @@ namespace winrt::TerminalApp::implementation
|
|||
TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable);
|
||||
TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs);
|
||||
TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable);
|
||||
TYPED_EVENT(SummonWindowRequested, IInspectable, IInspectable);
|
||||
|
||||
private:
|
||||
friend struct TerminalPageT<TerminalPage>; // for Xaml to bind events
|
||||
|
@ -174,6 +175,7 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::ActionAndArgs> _startupActions;
|
||||
bool _shouldStartInboundListener{ false };
|
||||
bool _isEmbeddingInboundListener{ false };
|
||||
|
||||
std::shared_ptr<Toast> _windowIdToast{ nullptr };
|
||||
std::shared_ptr<Toast> _windowRenameFailedToast{ nullptr };
|
||||
|
|
|
@ -56,5 +56,6 @@ namespace TerminalApp
|
|||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -251,6 +251,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||
void ConptyConnection::Start()
|
||||
try
|
||||
{
|
||||
_transitionToState(ConnectionState::Connecting);
|
||||
|
||||
if (!_inPipe)
|
||||
{
|
||||
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
|
||||
|
|
|
@ -1845,9 +1845,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// will take up.
|
||||
// TODO: MSFT:21254947 - use a static function to do this instead of
|
||||
// instantiating a DxEngine
|
||||
// GH#10211 - UNDER NO CIRCUMSTANCE should this fail. If it does, the
|
||||
// whole app will crash instantaneously on launch, which is no good.
|
||||
auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>();
|
||||
THROW_IF_FAILED(dxEngine->UpdateDpi(dpi));
|
||||
THROW_IF_FAILED(dxEngine->UpdateFont(desiredFont, actualFont));
|
||||
LOG_IF_FAILED(dxEngine->UpdateDpi(dpi));
|
||||
LOG_IF_FAILED(dxEngine->UpdateFont(desiredFont, actualFont));
|
||||
|
||||
const auto scale = dxEngine->GetScaling();
|
||||
const auto fontSize = actualFont.GetSize();
|
||||
|
|
|
@ -11,6 +11,26 @@
|
|||
<ResourceDictionary Source="SettingContainerStyle.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Style x:Key="SecondaryTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemBaseMediumColor}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Style x:Key="SecondaryTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemBaseMediumColor}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="SecondaryTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
<!-- Do not mess with the foreground color for High Contrast. Let it ride as is. -->
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<x:Double x:Key="StandardIconSize">14.0</x:Double>
|
||||
<Thickness x:Key="StandardIndentMargin">13,0,0,0</Thickness>
|
||||
<Thickness x:Key="StandardControlMargin">0,24,0,0</Thickness>
|
||||
|
|
|
@ -114,12 +114,12 @@
|
|||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Foreground="{StaticResource SystemBaseMediumColor}"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Author}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Foreground="{StaticResource SystemBaseMediumColor}"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Version}" />
|
||||
|
||||
</Grid>
|
||||
|
|
|
@ -11,7 +11,7 @@ using namespace winrt::Microsoft::Terminal::Settings;
|
|||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<Model::DefaultTerminal> DefaultTerminal::_available = winrt::single_threaded_vector<Model::DefaultTerminal>();
|
||||
std::optional<Model::DefaultTerminal> DefaultTerminal::_current;
|
||||
Model::DefaultTerminal DefaultTerminal::_current = nullptr;
|
||||
|
||||
DefaultTerminal::DefaultTerminal(DelegationConfig::DelegationPackage pkg) :
|
||||
_pkg(pkg)
|
||||
|
@ -81,7 +81,10 @@ Model::DefaultTerminal DefaultTerminal::Current()
|
|||
{
|
||||
Refresh();
|
||||
}
|
||||
return _current.value();
|
||||
|
||||
// The potential of returning nullptr feels weird, but XAML can handle that appropriately
|
||||
// and will select nothing as current in the dropdown.
|
||||
return _current;
|
||||
}
|
||||
|
||||
void DefaultTerminal::Current(const Model::DefaultTerminal& term)
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
private:
|
||||
DelegationConfig::DelegationPackage _pkg;
|
||||
static Windows::Foundation::Collections::IVector<Model::DefaultTerminal> _available;
|
||||
static std::optional<Model::DefaultTerminal> _current;
|
||||
static Model::DefaultTerminal _current;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -266,6 +266,7 @@ void AppHost::Initialize()
|
|||
_logic.RenameWindowRequested({ this, &AppHost::_RenameWindowRequested });
|
||||
_logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged });
|
||||
_logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged });
|
||||
_logic.SummonWindowRequested({ this, &AppHost::_SummonWindowRequested });
|
||||
|
||||
_window->UpdateTitle(_logic.Title());
|
||||
|
||||
|
@ -586,7 +587,7 @@ bool AppHost::HasWindow()
|
|||
// - args: the bundle of a commandline and working directory to use for this invocation.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*sender*/,
|
||||
void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable sender,
|
||||
Remoting::CommandlineArgs args)
|
||||
{
|
||||
const Remoting::SummonWindowBehavior summonArgs{};
|
||||
|
@ -595,7 +596,7 @@ void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*se
|
|||
summonArgs.ToMonitor(Remoting::MonitorBehavior::InPlace);
|
||||
// Summon the window whenever we dispatch a commandline to it. This will
|
||||
// make it obvious when a new tab/pane is created in a window.
|
||||
_window->SummonWindow(summonArgs);
|
||||
_HandleSummon(sender, summonArgs);
|
||||
_logic.ExecuteCommandline(args.Commandline(), args.CurrentDirectory());
|
||||
}
|
||||
|
||||
|
@ -925,3 +926,14 @@ void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectab
|
|||
{
|
||||
_window->IsQuakeWindow(_logic.IsQuakeWindow());
|
||||
}
|
||||
|
||||
void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable&)
|
||||
|
||||
{
|
||||
const Remoting::SummonWindowBehavior summonArgs{};
|
||||
summonArgs.MoveToCurrentDesktop(false);
|
||||
summonArgs.DropdownDuration(0);
|
||||
summonArgs.ToMonitor(Remoting::MonitorBehavior::InPlace);
|
||||
_HandleSummon(sender, summonArgs);
|
||||
}
|
||||
|
|
|
@ -82,4 +82,7 @@ private:
|
|||
|
||||
void _IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
};
|
||||
|
|
|
@ -1023,7 +1023,15 @@ winrt::fire_and_forget IslandWindow::SummonWindow(Remoting::SummonWindowBehavior
|
|||
{
|
||||
// On the foreground thread:
|
||||
co_await winrt::resume_foreground(_rootGrid.Dispatcher());
|
||||
_summonWindowRoutineBody(args);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - As above.
|
||||
// BODGY: ARM64 BUILD FAILED WITH fatal error C1001: Internal compiler error
|
||||
// when this was part of the coroutine body.
|
||||
void IslandWindow::_summonWindowRoutineBody(Remoting::SummonWindowBehavior args)
|
||||
{
|
||||
uint32_t actualDropdownDuration = args.DropdownDuration();
|
||||
// If the user requested an animation, let's check if animations are enabled in the OS.
|
||||
if (args.DropdownDuration() > 0)
|
||||
|
|
|
@ -111,6 +111,8 @@ protected:
|
|||
bool _isQuakeWindow{ false };
|
||||
void _enterQuakeMode();
|
||||
|
||||
void _summonWindowRoutineBody(winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior args);
|
||||
|
||||
private:
|
||||
// This minimum width allows for width the tabs fit
|
||||
static constexpr long minimumWidth = 460L;
|
||||
|
|
|
@ -185,11 +185,14 @@ try
|
|||
{
|
||||
packages.clear();
|
||||
|
||||
// Get consoles and terminals.
|
||||
// If we fail to look up any, we should still have ONE come back to us as the hardcoded default console host.
|
||||
// The errors aren't really useful except for debugging, so log only.
|
||||
std::vector<DelegationConsole> consoles;
|
||||
RETURN_IF_FAILED(s_GetAvailableConsoles(consoles));
|
||||
LOG_IF_FAILED(s_GetAvailableConsoles(consoles));
|
||||
|
||||
std::vector<DelegationTerminal> terminals;
|
||||
RETURN_IF_FAILED(s_GetAvailableTerminals(terminals));
|
||||
LOG_IF_FAILED(s_GetAvailableTerminals(terminals));
|
||||
|
||||
// TODO: I hate this algorithm (it's bad performance), but I couldn't
|
||||
// find an AppModel interface that would let me look up all the extensions
|
||||
|
|
|
@ -644,63 +644,77 @@ CATCH_RETURN()
|
|||
{
|
||||
// First attempt to find exactly what the user asked for.
|
||||
didFallback = false;
|
||||
auto face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace1> face{ nullptr };
|
||||
|
||||
// GH#10211 - wrap this all up in a try/catch. If the nearby fonts are
|
||||
// corrupted, then we don't want to throw out of this top half of this
|
||||
// method. We still want to fall back to a font that's reasonable, below.
|
||||
try
|
||||
{
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName, true);
|
||||
|
||||
if (!face)
|
||||
{
|
||||
// If we missed, try looking a little more by trimming the last word off the requested family name a few times.
|
||||
// Quite often, folks are specifying weights or something in the familyName and it causes failed resolution and
|
||||
// an unexpected error dialog. We theoretically could detect the weight words and convert them, but this
|
||||
// is the quick fix for the majority scenario.
|
||||
// The long/full fix is backlogged to GH#9744
|
||||
// Also this doesn't count as a fallback because we don't want to annoy folks with the warning dialog over
|
||||
// this resolution.
|
||||
while (!face && !familyName.empty())
|
||||
{
|
||||
const auto lastSpace = familyName.find_last_of(UNICODE_SPACE);
|
||||
|
||||
// value is unsigned and npos will be greater than size.
|
||||
// if we didn't find anything to trim, leave.
|
||||
if (lastSpace >= familyName.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// trim string down to just before the found space
|
||||
// (space found at 6... trim from 0 for 6 length will give us 0-5 as the new string)
|
||||
familyName = familyName.substr(0, lastSpace);
|
||||
|
||||
// Try to find it with the shortened family name
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// Alright, if our quick shot at trimming didn't work either...
|
||||
// move onto looking up a font from our hardcoded list of fonts
|
||||
// that should really always be available.
|
||||
if (!face)
|
||||
{
|
||||
// If we missed, try looking a little more by trimming the last word off the requested family name a few times.
|
||||
// Quite often, folks are specifying weights or something in the familyName and it causes failed resolution and
|
||||
// an unexpected error dialog. We theoretically could detect the weight words and convert them, but this
|
||||
// is the quick fix for the majority scenario.
|
||||
// The long/full fix is backlogged to GH#9744
|
||||
// Also this doesn't count as a fallback because we don't want to annoy folks with the warning dialog over
|
||||
// this resolution.
|
||||
while (!face && !familyName.empty())
|
||||
for (const auto fallbackFace : FALLBACK_FONT_FACES)
|
||||
{
|
||||
const auto lastSpace = familyName.find_last_of(UNICODE_SPACE);
|
||||
familyName = fallbackFace;
|
||||
// With these fonts, don't attempt the nearby lookup. We're looking
|
||||
// for system fonts only. If one of the nearby fonts is causing us
|
||||
// problems (like in GH#10211), then we don't want to go anywhere
|
||||
|
||||
// value is unsigned and npos will be greater than size.
|
||||
// if we didn't find anything to trim, leave.
|
||||
if (lastSpace >= familyName.size())
|
||||
// near it in this part.
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName, false);
|
||||
|
||||
if (face)
|
||||
{
|
||||
didFallback = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// trim string down to just before the found space
|
||||
// (space found at 6... trim from 0 for 6 length will give us 0-5 as the new string)
|
||||
familyName = familyName.substr(0, lastSpace);
|
||||
familyName = fallbackFace;
|
||||
weight = DWRITE_FONT_WEIGHT_NORMAL;
|
||||
stretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
style = DWRITE_FONT_STYLE_NORMAL;
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName, false);
|
||||
|
||||
// Try to find it with the shortened family name
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
}
|
||||
|
||||
// Alright, if our quick shot at trimming didn't work either...
|
||||
// move onto looking up a font from our hardcoded list of fonts
|
||||
// that should really always be available.
|
||||
if (!face)
|
||||
{
|
||||
for (const auto fallbackFace : FALLBACK_FONT_FACES)
|
||||
if (face)
|
||||
{
|
||||
familyName = fallbackFace;
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
|
||||
if (face)
|
||||
{
|
||||
didFallback = true;
|
||||
break;
|
||||
}
|
||||
|
||||
familyName = fallbackFace;
|
||||
weight = DWRITE_FONT_WEIGHT_NORMAL;
|
||||
stretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
style = DWRITE_FONT_STYLE_NORMAL;
|
||||
face = _FindFontFace(familyName, weight, stretch, style, localeName);
|
||||
|
||||
if (face)
|
||||
{
|
||||
didFallback = true;
|
||||
break;
|
||||
}
|
||||
didFallback = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -723,7 +737,8 @@ CATCH_RETURN()
|
|||
DWRITE_FONT_WEIGHT& weight,
|
||||
DWRITE_FONT_STRETCH& stretch,
|
||||
DWRITE_FONT_STYLE& style,
|
||||
std::wstring& localeName) const
|
||||
std::wstring& localeName,
|
||||
const bool withNearbyLookup) const
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace1> fontFace;
|
||||
|
||||
|
@ -735,7 +750,7 @@ CATCH_RETURN()
|
|||
THROW_IF_FAILED(fontCollection->FindFamilyName(familyName.data(), &familyIndex, &familyExists));
|
||||
|
||||
// If the system collection missed, try the files sitting next to our binary.
|
||||
if (!familyExists)
|
||||
if (withNearbyLookup && !familyExists)
|
||||
{
|
||||
auto&& nearbyCollection = NearbyCollection();
|
||||
|
||||
|
|
|
@ -71,7 +71,8 @@ namespace Microsoft::Console::Render
|
|||
DWRITE_FONT_WEIGHT& weight,
|
||||
DWRITE_FONT_STRETCH& stretch,
|
||||
DWRITE_FONT_STYLE& style,
|
||||
std::wstring& localeName) const;
|
||||
std::wstring& localeName,
|
||||
const bool withNearbyLookup) const;
|
||||
|
||||
[[nodiscard]] std::wstring _GetFontFamilyName(gsl::not_null<IDWriteFontFamily*> const fontFamily,
|
||||
std::wstring& localeName) const;
|
||||
|
|
Loading…
Reference in a new issue