Compare commits

..

1 Commits

Author SHA1 Message Date
Carlos Zamora
fbfc761450 Redesign new tab menu page -> dropdown 2026-05-08 13:21:22 -07:00
22 changed files with 474 additions and 368 deletions

View File

@@ -1075,7 +1075,6 @@ NOCONTEXTHELP
NOCOPYBITS
nodiscard
NODUP
NODEFAULT
noexcepts
NOFONT
NOHIDDENTEXT
@@ -1562,7 +1561,6 @@ SMARTQUOTE
SMTO
snapcx
snapcy
SND
snk
SOLIDBOX
Solutiondir

View File

@@ -2472,13 +2472,6 @@
},
"type": "array"
},
"safeUriSchemes": {
"description": "Specifies a list of URI schemes that are considered safe. No confirmation will be required to open URIs with these schemes.",
"items": {
"type": "string"
},
"type": "array"
},
"rendering.graphicsAPI": {
"description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.",
"type": "string",

View File

@@ -3307,15 +3307,13 @@ namespace winrt::TerminalApp::implementation
return true;
}
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri)
{
const auto& schemeName = parsedUri.SchemeName();
if (schemeName == L"http" || schemeName == L"https")
if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https")
{
return true;
}
if (schemeName == L"file")
if (parsedUri.SchemeName() == L"file")
{
static const auto pathext{ wil::TryGetEnvironmentVariableW<std::wstring>(L"PATHEXT") };
const auto filename = parsedUri.Path();
@@ -3329,16 +3327,6 @@ namespace winrt::TerminalApp::implementation
return true;
}
if (const auto& safeSchemes = _settings.GlobalSettings().SafeUriSchemes())
{
for (const auto& scheme : safeSchemes)
{
if (til::equals_insensitive_ascii(schemeName, scheme))
{
return true;
}
}
}
return false;
}

View File

@@ -438,7 +438,7 @@ namespace winrt::TerminalApp::implementation
safe_void_coroutine _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs);
static bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const;
static bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri);
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats);

View File

@@ -71,6 +71,18 @@ namespace winrt::TerminalApp::implementation
_removeControlEvents();
_control.Close();
// Clear out our media player callbacks, and stop any playing media. This
// will prevent the callback from being triggered after we've closed, and
// also make sure that our sound stops when we're closed.
if (_bellPlayer)
{
_bellPlayer.Pause();
_bellPlayer.Source(nullptr);
_bellPlayer.Close();
_bellPlayer = nullptr;
_bellPlayerCreated = false;
}
}
winrt::hstring TerminalPaneContent::Icon() const
@@ -263,15 +275,14 @@ namespace winrt::TerminalApp::implementation
auto sounds{ _profile.BellSound() };
if (sounds && sounds.Size() > 0)
{
// Sound paths are resolved and validated by CascadiaSettings
// before we reach this point.
auto soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
PlaySoundW(soundPath.c_str(), nullptr, SND_FILENAME | SND_ASYNC | SND_SENTRY | SND_NODEFAULT);
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
winrt::Windows::Foundation::Uri uri{ soundPath };
_playBellSound(uri);
}
else
{
const auto soundAlias = reinterpret_cast<LPCWSTR>(SND_ALIAS_SYSTEMHAND);
PlaySoundW(soundAlias, nullptr, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
}
@@ -289,6 +300,33 @@ namespace winrt::TerminalApp::implementation
}
}
safe_void_coroutine TerminalPaneContent::_playBellSound(winrt::Windows::Foundation::Uri uri)
{
auto weakThis{ get_weak() };
co_await wil::resume_foreground(_control.Dispatcher());
if (auto pane{ weakThis.get() })
{
if (!_bellPlayerCreated)
{
// The MediaPlayer might not exist on Windows N SKU.
try
{
_bellPlayerCreated = true;
_bellPlayer = winrt::Windows::Media::Playback::MediaPlayer();
// GH#12258: The media keys (like play/pause) should have no effect on our bell sound.
_bellPlayer.CommandManager().IsEnabled(false);
}
CATCH_LOG();
}
if (_bellPlayer)
{
const auto source{ winrt::Windows::Media::Core::MediaSource::CreateFromUri(uri) };
const auto item{ winrt::Windows::Media::Playback::MediaPlaybackItem(source) };
_bellPlayer.Source(item);
_bellPlayer.Play();
}
}
}
void TerminalPaneContent::_closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{

View File

@@ -76,6 +76,9 @@ namespace winrt::TerminalApp::implementation
std::shared_ptr<TerminalSettingsCache> _cache{};
bool _isDefTermSession{ false };
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
bool _bellPlayerCreated{ false };
struct ControlEventTokens
{
winrt::Microsoft::Terminal::Control::TermControl::ConnectionStateChanged_revoker _ConnectionStateChanged;
@@ -93,6 +96,8 @@ namespace winrt::TerminalApp::implementation
void _setupControlEvents();
void _removeControlEvents();
safe_void_coroutine _playBellSound(winrt::Windows::Foundation::Uri uri);
safe_void_coroutine _controlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& e);

View File

@@ -925,7 +925,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Manually turn off acrylic if they turn off transparency.
_runtimeUseAcrylic = _settings.Opacity() < 1.0 && _settings.UseAcrylic();
const auto sizeChanged = _setFontSizeUnderLock(_settings.FontSize() + _accumulatedFontSizeDelta);
const auto sizeChanged = _setFontSizeUnderLock(_settings.FontSize());
// Update the terminal core with its new Core settings
_terminal->UpdateSettings(_settings);
@@ -1163,10 +1163,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - none
void ControlCore::ResetFontSize()
{
if (std::exchange(_accumulatedFontSizeDelta, 0.f) != 0.f)
const auto lock = _terminal->LockForWriting();
if (_setFontSizeUnderLock(_settings.FontSize()))
{
// No point in doing this if there was no delta.
AdjustFontSize(0);
_refreshSizeUnderLock();
}
}
@@ -1176,11 +1177,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - fontSizeDelta: The amount to increase or decrease the font size by.
void ControlCore::AdjustFontSize(float fontSizeDelta)
{
_accumulatedFontSizeDelta += fontSizeDelta;
const auto lock = _terminal->LockForWriting();
if (_setFontSizeUnderLock(_settings.FontSize() + _accumulatedFontSizeDelta))
if (_setFontSizeUnderLock(_desiredFont.GetFontSize() + fontSizeDelta))
{
_refreshSizeUnderLock();
}

View File

@@ -391,7 +391,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool _colorGlyphs = true;
CSSLengthPercentage _cellWidth;
CSSLengthPercentage _cellHeight;
float _accumulatedFontSizeDelta = 0.f; // Preserved across reloads to prevent user zoom from being overwritten.
// Rendering stuff.
winrt::handle _lastSwapChainHandle{ nullptr };

View File

@@ -98,6 +98,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
_answerbackMessage = settings.AnswerbackMessage();
_wordDelimiters = settings.WordDelimiters();
_suppressApplicationTitle = settings.SuppressApplicationTitle();
_startingTitle = settings.StartingTitle();
_trimBlockSelection = settings.TrimBlockSelection();
_autoMarkPrompts = settings.AutoMarkPrompts();
_rainbowSuggestions = settings.RainbowSuggestions();
@@ -123,11 +124,6 @@ void Terminal::UpdateSettings(ICoreSettings settings)
// Save the changes made above and in UpdateAppearance as the new default render settings.
GetRenderSettings().SaveDefaultSettings();
if (!_startingTitle)
{
_startingTitle = settings.StartingTitle();
}
if (!_startingTabColor && settings.StartingTabColor())
{
_startingTabColor = settings.StartingTabColor().Value();

View File

@@ -349,7 +349,7 @@ private:
::Microsoft::Console::VirtualTerminal::TerminalInput _terminalInput;
std::optional<std::wstring> _title;
std::optional<std::wstring> _startingTitle;
std::wstring _startingTitle;
std::optional<til::color> _startingTabColor;
std::vector<til::point_span> _searchHighlights;

View File

@@ -91,12 +91,8 @@ void Terminal::SetWindowTitle(const std::wstring_view title)
_assertLocked();
if (!_suppressApplicationTitle)
{
_title.reset();
if (!title.empty())
{
_title.emplace(title);
}
_pfnTitleChanged(GetConsoleTitle());
_title.emplace(title.empty() ? _startingTitle : title);
_pfnTitleChanged(_title.value());
}
}
@@ -116,13 +112,6 @@ bool Terminal::ResizeWindow(const til::CoordType width, const til::CoordType hei
return false;
}
const auto currentDimensions = _GetMutableViewport().Dimensions();
if (width == currentDimensions.width && height == currentDimensions.height)
{
return false;
}
if (_pfnWindowSizeChanged)
{
_pfnWindowSizeChanged(width, height);

View File

@@ -184,18 +184,11 @@ void Terminal::SelectNewRegion(const til::point coordStart, const til::point coo
std::wstring_view Terminal::GetConsoleTitle() const noexcept
{
_assertLocked();
if (_title)
if (_title.has_value())
{
return *_title;
}
if (_startingTitle)
{
return *_startingTitle;
}
return {};
return _startingTitle;
}
// Method Description:

View File

@@ -227,11 +227,27 @@
</ResourceDictionary>
</Page.Resources>
<Grid RowSpacing="12">
<Grid x:Name="RootGrid"
MaxWidth="{StaticResource StandardControlMaxWidth}"
ColumnSpacing="16"
RowSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ControlsColumn"
Width="*" />
<ColumnDefinition x:Name="PreviewColumn"
Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<!--
In the wide/medium (2-column) states, both PreviewArea and ControlsArea span
both rows so the row sizing here doesn't matter.
In the narrow (stacked) state, PreviewArea moves to row 0 and ControlsArea
moves to row 1, and the rows are resized via the visual state setters.
-->
<RowDefinition x:Name="PreviewRow"
Height="0" />
<RowDefinition x:Name="ControlsRow"
Height="*" />
</Grid.RowDefinitions>
<!-- Folder Picker Dialog: used to select a folder to move entries to -->
@@ -267,253 +283,390 @@
</muxc:TreeView>
</ContentDialog>
<!-- New Tab Menu Content -->
<StackPanel Grid.Row="0"
MaxWidth="{StaticResource StandardControlMaxWidth}"
Spacing="8">
<Border Height="300"
MaxWidth="{StaticResource StandardControlMaxWidth}"
Margin="0,12,0,0"
<Grid x:Name="PreviewArea"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Grid.ColumnSpan="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--
Invisible header placeholder so the preview's top edge aligns with the first
SettingContainer in the controls column
-->
<TextBlock x:Name="PreviewHeaderPlaceholder"
Grid.Row="0"
Margin="0,4,0,4"
AutomationProperties.AccessibilityView="Raw"
IsHitTestVisible="False"
Opacity="0"
Style="{StaticResource TextBlockSubHeaderStyle}"
Text="Preview" />
<!-- Preview Border: contains the ListView and the multi-select footer. -->
<Border Grid.Row="1"
MinHeight="300"
Margin="0,4,0,0"
VerticalAlignment="Stretch"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="1"
CornerRadius="{ThemeResource ControlCornerRadius}">
<ListView x:Name="NewTabMenuListView"
AllowDrop="True"
CanDragItems="True"
CanReorderItems="True"
ItemTemplateSelector="{StaticResource NewTabMenuEntryTemplateSelector}"
ItemsSource="{x:Bind ViewModel.CurrentView, Mode=OneWay}"
SelectionMode="Multiple" />
</Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- General Controls -->
<StackPanel Orientation="Horizontal"
Spacing="10">
<Button x:Name="MoveToFolderButton"
Click="MoveMultiple_Click"
IsEnabled="False">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8DE;" />
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
Margin="8,0,0,0" />
</StackPanel>
</Button>
<Button x:Name="DeleteMultipleButton"
Click="DeleteMultiple_Click"
IsEnabled="False"
Style="{StaticResource DeleteButtonStyle}">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE74D;" />
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
Margin="8,0,0,0" />
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
<!-- Folder View Controls -->
<StackPanel Grid.Row="1"
MaxWidth="{StaticResource StandardControlMaxWidth}"
Visibility="{x:Bind ViewModel.IsFolderView, Mode=OneWay}">
<TextBlock x:Uid="NewTabMenu_CurrentFolderTextBlock"
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Name -->
<local:SettingContainer x:Name="CurrentFolderName"
x:Uid="NewTabMenu_CurrentFolderName"
CurrentValue="{x:Bind ViewModel.CurrentFolderName, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<TextBox Style="{StaticResource TextBoxSettingStyle}"
Text="{x:Bind ViewModel.CurrentFolderName, Mode=TwoWay}" />
</local:SettingContainer>
<!-- Icon -->
<local:SettingContainer x:Name="CurrentFolderIcon"
x:Uid="NewTabMenu_CurrentFolderIcon"
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
<Grid>
<ContentControl Width="16"
Height="16"
Content="{x:Bind ViewModel.CurrentFolderIconPreview, Mode=OneWay}"
IsTabStop="False"
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.CurrentFolderUsingNoIcon), Mode=OneWay}" />
<TextBlock Margin="0,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
Visibility="{x:Bind ViewModel.CurrentFolderUsingNoIcon, Mode=OneWay}" />
</Grid>
</local:SettingContainer.CurrentValue>
<local:SettingContainer.Content>
<local:IconPicker CurrentIconPath="{x:Bind ViewModel.CurrentFolderIconPath, Mode=TwoWay}"
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
</local:SettingContainer.Content>
</local:SettingContainer>
<!-- Inlining -->
<local:SettingContainer x:Name="CurrentFolderInlining"
x:Uid="NewTabMenu_CurrentFolderInlining">
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderInlining, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Allow Empty -->
<local:SettingContainer x:Name="CurrentFolderAllowEmpty"
x:Uid="NewTabMenu_CurrentFolderAllowEmpty">
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderAllowEmpty, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
</StackPanel>
<!-- Add Entries -->
<StackPanel Grid.Row="2">
<TextBlock x:Uid="NewTabMenu_AddEntriesTextBlock"
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Add Profile -->
<local:SettingContainer x:Name="AddProfile"
x:Uid="NewTabMenu_AddProfile"
FontIconGlyph="&#xE756;"
Style="{StaticResource SettingContainerWithIcon}">
<StackPanel Orientation="Horizontal"
Spacing="4">
<!-- Select profile to add -->
<ComboBox x:Name="AddProfileComboBox"
MinWidth="{StaticResource StandardBoxMinWidth}"
ItemsSource="{x:Bind ViewModel.AvailableProfiles, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedProfile, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="model:Profile">
<Grid HorizontalAlignment="Stretch"
ColumnSpacing="8">
<ListView x:Name="NewTabMenuListView"
Grid.Row="0"
AllowDrop="True"
CanDragItems="True"
CanReorderItems="True"
ItemTemplateSelector="{StaticResource NewTabMenuEntryTemplateSelector}"
ItemsSource="{x:Bind ViewModel.CurrentView, Mode=OneWay}"
SelectionMode="Multiple" />
<!-- Preview Controls -->
<Border Grid.Row="1"
Padding="8"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,1,0,0">
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="MoveToFolderButton"
Grid.Column="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Click="MoveMultiple_Click"
IsEnabled="False">
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<!-- icon -->
<ColumnDefinition Width="16" />
<!-- profile name -->
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<IconSourceElement Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
<TextBlock Grid.Column="1"
Text="{x:Bind Name}" />
<FontIcon Grid.Column="0"
VerticalAlignment="Center"
FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8DE;" />
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
Grid.Column="1"
VerticalAlignment="Center"
TextWrapping="WrapWholeWords" />
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Button>
<Button x:Name="DeleteMultipleButton"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Click="DeleteMultiple_Click"
IsEnabled="False"
Style="{StaticResource DeleteButtonStyle}">
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<FontIcon Grid.Column="0"
VerticalAlignment="Center"
FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE74D;" />
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
Grid.Column="1"
VerticalAlignment="Center"
TextWrapping="WrapWholeWords" />
</Grid>
</Button>
</Grid>
</Border>
</Grid>
</Border>
</Grid>
<Button x:Name="AddProfileButton"
x:Uid="NewTabMenu_AddProfileButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddProfileButton_Clicked">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
<ScrollViewer x:Name="ControlsArea"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="1"
HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<!-- Folder View Controls -->
<StackPanel Margin="0,0,0,24"
Visibility="{x:Bind ViewModel.IsFolderView, Mode=OneWay}">
<TextBlock x:Uid="NewTabMenu_CurrentFolderTextBlock"
Margin="0,4,0,4"
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Name -->
<local:SettingContainer x:Name="CurrentFolderName"
x:Uid="NewTabMenu_CurrentFolderName"
CurrentValue="{x:Bind ViewModel.CurrentFolderName, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<TextBox Style="{StaticResource TextBoxSettingStyle}"
Text="{x:Bind ViewModel.CurrentFolderName, Mode=TwoWay}" />
</local:SettingContainer>
<!-- Icon -->
<local:SettingContainer x:Name="CurrentFolderIcon"
x:Uid="NewTabMenu_CurrentFolderIcon"
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
<Grid>
<ContentControl Width="16"
Height="16"
Content="{x:Bind ViewModel.CurrentFolderIconPreview, Mode=OneWay}"
IsTabStop="False"
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.CurrentFolderUsingNoIcon), Mode=OneWay}" />
<TextBlock Margin="0,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
Visibility="{x:Bind ViewModel.CurrentFolderUsingNoIcon, Mode=OneWay}" />
</Grid>
</local:SettingContainer.CurrentValue>
<local:SettingContainer.Content>
<local:IconPicker CurrentIconPath="{x:Bind ViewModel.CurrentFolderIconPath, Mode=TwoWay}"
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
</local:SettingContainer.Content>
</local:SettingContainer>
<!-- Inlining -->
<local:SettingContainer x:Name="CurrentFolderInlining"
x:Uid="NewTabMenu_CurrentFolderInlining">
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderInlining, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Allow Empty -->
<local:SettingContainer x:Name="CurrentFolderAllowEmpty"
x:Uid="NewTabMenu_CurrentFolderAllowEmpty">
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderAllowEmpty, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
</StackPanel>
</local:SettingContainer>
<!-- Add Separator -->
<local:SettingContainer x:Name="AddSeparator"
x:Uid="NewTabMenu_AddSeparator"
FontIconGlyph="&#xE76f;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddSeparatorButton"
x:Uid="NewTabMenu_AddSeparatorButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddSeparatorButton_Clicked">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
</local:SettingContainer>
<!-- Add Entries -->
<StackPanel>
<TextBlock x:Uid="NewTabMenu_AddEntriesTextBlock"
Margin="0,4,0,4"
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Add Folder -->
<local:SettingContainer x:Name="AddFolder"
x:Uid="NewTabMenu_AddFolder"
FontIconGlyph="&#xF12B;"
Style="{StaticResource SettingContainerWithIcon}">
<StackPanel Orientation="Horizontal"
Spacing="5">
<TextBox x:Name="FolderNameTextBox"
x:Uid="NewTabMenu_AddFolder_FolderName"
MinWidth="{StaticResource StandardBoxMinWidth}"
KeyDown="AddFolderNameTextBox_KeyDown"
Text="{x:Bind ViewModel.AddFolderName, Mode=TwoWay}"
TextChanged="AddFolderNameTextBox_TextChanged" />
<Button x:Name="AddFolderButton"
x:Uid="NewTabMenu_AddFolderButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddFolderButton_Clicked"
IsEnabled="False">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
<!-- Add Profile -->
<local:SettingContainer x:Name="AddProfile"
x:Uid="NewTabMenu_AddProfile"
FontIconGlyph="&#xE756;"
Style="{StaticResource SettingContainerWithIcon}">
<!-- Add Match Profiles -->
<local:SettingContainer x:Name="AddMatchProfiles"
x:Uid="NewTabMenu_AddMatchProfiles"
FontIconGlyph="&#xE748;"
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
<StackPanel Spacing="8">
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Source"
Text="{x:Bind ViewModel.ProfileMatcherSource, Mode=TwoWay}" />
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Commandline"
Text="{x:Bind ViewModel.ProfileMatcherCommandline, Mode=TwoWay}" />
<Button x:Name="AddMatchProfilesButton"
Click="AddMatchProfilesButton_Clicked">
<Button.Content>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="4">
<!-- Select profile to add -->
<ComboBox x:Name="AddProfileComboBox"
MinWidth="{StaticResource StandardBoxMinWidth}"
ItemsSource="{x:Bind ViewModel.AvailableProfiles, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedProfile, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="model:Profile">
<Grid HorizontalAlignment="Stretch"
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<!-- icon -->
<ColumnDefinition Width="16" />
<!-- profile name -->
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<IconSourceElement Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
<TextBlock Grid.Column="1"
Text="{x:Bind Name}" />
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button x:Name="AddProfileButton"
x:Uid="NewTabMenu_AddProfileButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddProfileButton_Clicked">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
<!-- Add Separator -->
<local:SettingContainer x:Name="AddSeparator"
x:Uid="NewTabMenu_AddSeparator"
FontIconGlyph="&#xE76f;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddSeparatorButton"
x:Uid="NewTabMenu_AddSeparatorButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddSeparatorButton_Clicked">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="NewTabMenu_AddMatchProfilesTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
</Button.Content>
</Button>
</local:SettingContainer>
<!-- Add Remaining Profiles -->
<local:SettingContainer x:Name="AddRemainingProfiles"
x:Uid="NewTabMenu_AddRemainingProfiles"
FontIconGlyph="&#xE902;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddRemainingProfilesButton"
x:Uid="NewTabMenu_AddRemainingProfilesButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddRemainingProfilesButton_Clicked"
IsEnabled="{x:Bind ViewModel.IsRemainingProfilesEntryMissing, Mode=OneWay}">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
</local:SettingContainer>
</StackPanel>
<!-- Add Folder -->
<local:SettingContainer x:Name="AddFolder"
x:Uid="NewTabMenu_AddFolder"
FontIconGlyph="&#xF12B;"
Style="{StaticResource SettingContainerWithIcon}">
<StackPanel Orientation="Horizontal"
Spacing="5">
<TextBox x:Name="FolderNameTextBox"
x:Uid="NewTabMenu_AddFolder_FolderName"
MinWidth="{StaticResource StandardBoxMinWidth}"
KeyDown="AddFolderNameTextBox_KeyDown"
Text="{x:Bind ViewModel.AddFolderName, Mode=TwoWay}"
TextChanged="AddFolderNameTextBox_TextChanged" />
<Button x:Name="AddFolderButton"
x:Uid="NewTabMenu_AddFolderButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddFolderButton_Clicked"
IsEnabled="False">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
<!-- Add Match Profiles -->
<local:SettingContainer x:Name="AddMatchProfiles"
x:Uid="NewTabMenu_AddMatchProfiles"
FontIconGlyph="&#xE748;"
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
<StackPanel Spacing="8">
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Source"
Text="{x:Bind ViewModel.ProfileMatcherSource, Mode=TwoWay}" />
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Commandline"
Text="{x:Bind ViewModel.ProfileMatcherCommandline, Mode=TwoWay}" />
<Button x:Name="AddMatchProfilesButton"
Click="AddMatchProfilesButton_Clicked">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="NewTabMenu_AddMatchProfilesTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
<!-- Add Remaining Profiles -->
<local:SettingContainer x:Name="AddRemainingProfiles"
x:Uid="NewTabMenu_AddRemainingProfiles"
FontIconGlyph="&#xE902;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddRemainingProfilesButton"
x:Uid="NewTabMenu_AddRemainingProfilesButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Click="AddRemainingProfilesButton_Clicked"
IsEnabled="{x:Bind ViewModel.IsRemainingProfilesEntryMissing, Mode=OneWay}">
<Button.Content>
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
</Button.Content>
</Button>
</local:SettingContainer>
</StackPanel>
</StackPanel>
</ScrollViewer>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<!-- Wide: 2 columns, controls on left with leading icons, preview on right. -->
<VisualState x:Name="Wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1200" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AddProfile.Style" Value="{StaticResource SettingContainerWithIcon}" />
<Setter Target="AddSeparator.Style" Value="{StaticResource SettingContainerWithIcon}" />
<Setter Target="AddFolder.Style" Value="{StaticResource SettingContainerWithIcon}" />
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyleWithIcon}" />
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource SettingContainerWithIcon}" />
</VisualState.Setters>
</VisualState>
<!-- Medium: 2 columns, controls on left WITHOUT leading icons, preview on right. -->
<VisualState x:Name="Medium">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="900" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AddProfile.Style" Value="{StaticResource DefaultSettingContainer}" />
<Setter Target="AddSeparator.Style" Value="{StaticResource DefaultSettingContainer}" />
<Setter Target="AddFolder.Style" Value="{StaticResource DefaultSettingContainer}" />
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource DefaultSettingContainer}" />
</VisualState.Setters>
</VisualState>
<!-- Narrow: single column, preview stacked on top, controls below, no icons. -->
<VisualState x:Name="Narrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<!-- Collapse the preview column and give the preview row real height so the rows are used instead of the columns. -->
<Setter Target="PreviewColumn.Width" Value="0" />
<Setter Target="PreviewRow.Height" Value="Auto" />
<!-- Move PreviewArea to row 0, spanning both columns. -->
<Setter Target="PreviewArea.(Grid.Row)" Value="0" />
<Setter Target="PreviewArea.(Grid.RowSpan)" Value="1" />
<Setter Target="PreviewArea.(Grid.Column)" Value="0" />
<Setter Target="PreviewArea.(Grid.ColumnSpan)" Value="2" />
<!-- Move ControlsArea to row 1, spanning both columns. -->
<Setter Target="ControlsArea.(Grid.Row)" Value="1" />
<Setter Target="ControlsArea.(Grid.RowSpan)" Value="1" />
<Setter Target="ControlsArea.(Grid.Column)" Value="0" />
<Setter Target="ControlsArea.(Grid.ColumnSpan)" Value="2" />
<!-- No icons in the narrow state either (progressive simplification). -->
<Setter Target="AddProfile.Style" Value="{StaticResource DefaultSettingContainer}" />
<Setter Target="AddSeparator.Style" Value="{StaticResource DefaultSettingContainer}" />
<Setter Target="AddFolder.Style" Value="{StaticResource DefaultSettingContainer}" />
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource DefaultSettingContainer}" />
<!-- Hide the preview header placeholder in stacked mode (no controls beside the preview to align with). -->
<Setter Target="PreviewHeaderPlaceholder.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</Page>

View File

@@ -2398,8 +2398,8 @@
<comment>Accessible name for a control allowing the user to select the icon from a list of built in icons.</comment>
</data>
<data name="Nav_NewTabMenu.Content" xml:space="preserve">
<value>New Tab Menu</value>
<comment>Header for the "new tab menu" menu item. This navigates to a page that lets you see and modify settings related to the app's new tab menu (i.e. profile ordering, nested folders, dividers, etc.)</comment>
<value>Dropdown Menu</value>
<comment>Header for the "dropdown menu" menu item (formerly "new tab menu"). This navigates to a page that lets you see and modify settings related to the app's dropdown menu (i.e. profile ordering, nested folders, dividers, etc.)</comment>
</data>
<data name="NewTabMenuEntry_Separator.Text" xml:space="preserve">
<value>&lt;Separator&gt;</value>

View File

@@ -190,7 +190,8 @@
</DataTemplate>
<!-- A setting container for a setting that has no additional options -->
<Style TargetType="local:SettingContainer">
<Style x:Key="DefaultSettingContainer"
TargetType="local:SettingContainer">
<Setter Property="Margin" Value="0,4,0,0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="MaxWidth" Value="1000" />
@@ -228,6 +229,10 @@
</Setter>
</Style>
<!-- Implicit default style for SettingContainer; just an alias of DefaultSettingContainer so the named style can be referenced from VisualState setters. -->
<Style BasedOn="{StaticResource DefaultSettingContainer}"
TargetType="local:SettingContainer" />
<!-- A basic setting container displaying immutable text as content -->
<Style x:Key="SettingContainerWithTextContent"
TargetType="local:SettingContainer">

View File

@@ -102,14 +102,6 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
globals->_DisabledProfileSources->Append(src);
}
}
if (_SafeUriSchemes)
{
globals->_SafeUriSchemes = winrt::single_threaded_vector<hstring>();
for (const auto& src : *_SafeUriSchemes)
{
globals->_SafeUriSchemes->Append(src);
}
}
for (const auto& parent : _parents)
{

View File

@@ -114,7 +114,6 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
INHERITABLE_SETTING(Boolean, AllowHeadless);
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
INHERITABLE_SETTING(IVector<String>, SafeUriSchemes);
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
void AddColorScheme(ColorScheme scheme);

View File

@@ -63,7 +63,6 @@ Author(s):
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, SafeUriSchemes, "safeUriSchemes", nullptr) \
X(bool, ShowAdminShield, "showAdminShield", true) \
X(bool, TrimPaste, "trimPaste", true) \
X(bool, EnableColorSelection, "experimental.enableColorSelection", false) \

View File

@@ -467,7 +467,6 @@ namespace SettingsModelUnitTests
"$schema" : "https://aka.ms/terminal-profiles-schema",
"defaultProfile": "{61c54bbd-1111-5271-96e7-009a87ff44bf}",
"disabledProfileSources": [ "Windows.Terminal.Wsl" ],
"safeUriSchemes": [ "vscode" ],
"newTabMenu":
[
{

View File

@@ -123,7 +123,6 @@ class ScreenBufferTests
TEST_METHOD(VtResizePreservingAttributes);
TEST_METHOD(VtSoftResetCursorPosition);
TEST_METHOD(VtSoftResetAltBufferCursorState);
TEST_METHOD(VtScrollMarginsNewlineColor);
@@ -1511,30 +1510,6 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
}
void ScreenBufferTests::VtSoftResetAltBufferCursorState()
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
gci.LockConsole(); // Lock must be taken to manipulate buffer.
auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); });
auto& si = gci.GetActiveOutputBuffer();
auto& stateMachine = si.GetStateMachine();
Log::Comment(L"Move cursor on the main buffer.");
stateMachine.ProcessString(L"\x1b[4;7H");
VERIFY_ARE_EQUAL(til::point(6, 3), si.GetTextBuffer().GetCursor().GetPosition());
Log::Comment(L"Enter alt buffer, soft reset, and return to main buffer.");
stateMachine.ProcessString(L"\x1b[?1049h");
VERIFY_IS_TRUE(gci.GetActiveOutputBuffer()._IsAltBuffer());
stateMachine.ProcessString(L"\x1b[!p");
stateMachine.ProcessString(L"\x1b[?1049l");
VERIFY_IS_FALSE(gci.GetActiveOutputBuffer()._IsAltBuffer());
Log::Comment(L"Returning from alt buffer should restore the main cursor position.");
VERIFY_ARE_EQUAL(til::point(6, 3), gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor().GetPosition());
}
void ScreenBufferTests::VtScrollMarginsNewlineColor()
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();

View File

@@ -90,15 +90,7 @@ std::function<bool(wchar_t)> SixelParser::DefineImage(const VTInt macroParameter
_state = States::Normal;
_parameters.clear();
return [&](const auto ch) {
try
{
_parseCommandChar(ch);
}
catch (...)
{
// Ignore all further content.
return false;
}
_parseCommandChar(ch);
return true;
};
}
@@ -242,18 +234,10 @@ void SixelParser::_executeNextLine()
_executeCarriageReturn();
_imageLineCount++;
_maybeFlushImageBuffer();
// If we don't have any available pixel height, that means the image has
// extended beyond the bottom of the display and we haven't triggered a
// a scroll (because sixel display mode is enabled). In this state, there
// is no point in extending the image any further, because the additional
// content will never be seen, so we'll just be wasting memory.
if (_availablePixelHeight > 0)
{
_imageCursor.y += _sixelHeight;
_availablePixelHeight -= _sixelHeight;
_resizeImageBuffer(_sixelHeight);
_fillImageBackgroundWhenScrolled();
}
_imageCursor.y += _sixelHeight;
_availablePixelHeight -= _sixelHeight;
_resizeImageBuffer(_sixelHeight);
_fillImageBackgroundWhenScrolled();
}
void SixelParser::_executeMoveToHome()

View File

@@ -3002,15 +3002,17 @@ void AdaptDispatch::SoftReset()
SetGraphicsRendition({}); // Normal rendition.
SetCharacterProtectionAttribute({}); // Default (unprotected)
// Reset only the active saved cursor state.
// This matches xterm behavior when DECSTR is processed while using
// the alternate screen buffer (GH#19918).
_savedCursorState.at(_usingAltBuffer ? 1 : 0) = {};
// Reset the saved cursor state.
// Note that XTerm only resets the main buffer state, but that
// seems likely to be a bug. Most other terminals reset both.
_savedCursorState.at(0) = {}; // Main buffer
_savedCursorState.at(1) = {}; // Alt buffer
// The TerminalOutput state in this buffer must be reset to
// The TerminalOutput state in these buffers must be reset to
// the same state as the _termOutput instance, which is not
// necessarily equivalent to a full reset.
_savedCursorState.at(_usingAltBuffer ? 1 : 0).TermOutput = _termOutput;
_savedCursorState.at(0).TermOutput = _termOutput;
_savedCursorState.at(1).TermOutput = _termOutput;
// Soft reset the Sixel parser if in use.
if (_sixelParser)