mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-07 14:50:55 +00:00
Compare commits
9 Commits
dev/migrie
...
1.17
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
210414e5a8 | ||
|
|
2aefb30355 | ||
|
|
ffda8c4a95 | ||
|
|
2fd33ba510 | ||
|
|
2c165438ef | ||
|
|
0e86ce559e | ||
|
|
35b9e75574 | ||
|
|
da0a6d468a | ||
|
|
c2dd6143ac |
@@ -1,21 +1,28 @@
|
||||
[CmdletBinding(DefaultParameterSetName = 'AppX')]
|
||||
Param(
|
||||
[Parameter(Mandatory,
|
||||
HelpMessage="Path to Terminal AppX")]
|
||||
[Parameter(Mandatory, HelpMessage="Path to Terminal AppX", ParameterSetName = 'AppX')]
|
||||
[ValidateScript({Test-Path $_ -Type Leaf})]
|
||||
[string]
|
||||
$TerminalAppX,
|
||||
|
||||
[Parameter(Mandatory,
|
||||
HelpMessage="Path to Xaml AppX")]
|
||||
[Parameter(Mandatory, HelpMessage="Path to Terminal Layout Deployment", ParameterSetName='Layout')]
|
||||
[ValidateScript({Test-Path $_ -Type Container})]
|
||||
[string]
|
||||
$TerminalLayout,
|
||||
|
||||
[Parameter(Mandatory, HelpMessage="Path to Xaml AppX", ParameterSetName='AppX')]
|
||||
[Parameter(Mandatory, HelpMessage="Path to Xaml AppX", ParameterSetName='Layout')]
|
||||
[ValidateScript({Test-Path $_ -Type Leaf})]
|
||||
[string]
|
||||
$XamlAppX,
|
||||
|
||||
[Parameter(HelpMessage="Output Directory")]
|
||||
[Parameter(HelpMessage="Output Directory", ParameterSetName='AppX')]
|
||||
[Parameter(HelpMessage="Output Directory", ParameterSetName='Layout')]
|
||||
[string]
|
||||
$Destination = ".",
|
||||
|
||||
[Parameter(HelpMessage="Path to makeappx.exe")]
|
||||
[Parameter(HelpMessage="Path to makeappx.exe", ParameterSetName='AppX')]
|
||||
[Parameter(HelpMessage="Path to makeappx.exe", ParameterSetName='Layout')]
|
||||
[ValidateScript({Test-Path $_ -Type Leaf})]
|
||||
[string]
|
||||
$MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakeAppx.exe"
|
||||
@@ -36,14 +43,17 @@ $tempDir = Join-Path ([System.IO.Path]::GetTempPath()) "tmp$([Convert]::ToString
|
||||
New-Item -ItemType Directory -Path $tempDir | Out-Null
|
||||
|
||||
$XamlAppX = Get-Item $XamlAppX | Select-Object -Expand FullName
|
||||
$TerminalAppX = Get-Item $TerminalAppX | Select-Object -Expand FullName
|
||||
|
||||
########
|
||||
# Reading the AppX Manifest for preliminary info
|
||||
########
|
||||
|
||||
$appxManifestPath = Join-Path $tempDir AppxManifest.xml
|
||||
& tar.exe -x -f "$TerminalAppX" -C $tempDir AppxManifest.xml
|
||||
If ($TerminalAppX) {
|
||||
$appxManifestPath = Join-Path $tempDir AppxManifest.xml
|
||||
& tar.exe -x -f "$TerminalAppX" -C $tempDir AppxManifest.xml
|
||||
} ElseIf($TerminalLayout) {
|
||||
$appxManifestPath = Join-Path $TerminalLayout AppxManifest.xml
|
||||
}
|
||||
$manifest = [xml](Get-Content $appxManifestPath)
|
||||
$pfn = $manifest.Package.Identity.Name
|
||||
$version = $manifest.Package.Identity.Version
|
||||
@@ -57,13 +67,20 @@ $terminalDir = "terminal-{0}" -f ($version)
|
||||
########
|
||||
|
||||
$terminalAppPath = Join-Path $tempdir $terminalDir
|
||||
$xamlAppPath = Join-Path $tempdir "xaml"
|
||||
New-Item -ItemType Directory -Path $terminalAppPath | Out-Null
|
||||
New-Item -ItemType Directory -Path $xamlAppPath | Out-Null
|
||||
& $MakeAppxPath unpack /p $TerminalAppX /d $terminalAppPath /o | Out-Null
|
||||
If ($LASTEXITCODE -Ne 0) {
|
||||
Throw "Unpacking $TerminalAppX failed"
|
||||
|
||||
If ($TerminalAppX) {
|
||||
$TerminalAppX = Get-Item $TerminalAppX | Select-Object -Expand FullName
|
||||
New-Item -ItemType Directory -Path $terminalAppPath | Out-Null
|
||||
& $MakeAppxPath unpack /p $TerminalAppX /d $terminalAppPath /o | Out-Null
|
||||
If ($LASTEXITCODE -Ne 0) {
|
||||
Throw "Unpacking $TerminalAppX failed"
|
||||
}
|
||||
} ElseIf ($TerminalLayout) {
|
||||
Copy-Item -Recurse -Path $TerminalLayout -Destination $terminalAppPath
|
||||
}
|
||||
|
||||
$xamlAppPath = Join-Path $tempdir "xaml"
|
||||
New-Item -ItemType Directory -Path $xamlAppPath | Out-Null
|
||||
& $MakeAppxPath unpack /p $XamlAppX /d $xamlAppPath /o | Out-Null
|
||||
If ($LASTEXITCODE -Ne 0) {
|
||||
Throw "Unpacking $XamlAppX failed"
|
||||
@@ -105,13 +122,19 @@ $finalTerminalPriFile = Join-Path $terminalAppPath "resources.pri"
|
||||
-TerminalRoot $terminalAppPath `
|
||||
-XamlRoot $xamlAppPath `
|
||||
-OutputPath $finalTerminalPriFile `
|
||||
-Verbose:$Verbose
|
||||
-Verbose:$Verbose | Out-Host
|
||||
|
||||
########
|
||||
# Packaging
|
||||
########
|
||||
|
||||
New-Item -ItemType Directory -Path $Destination -ErrorAction:SilentlyContinue | Out-Null
|
||||
$outputZip = (Join-Path $Destination ("{0}.zip" -f ($distributionName)))
|
||||
& tar -c --format=zip -f $outputZip -C $tempDir $terminalDir
|
||||
Get-Item $outputZip
|
||||
If ($PSCmdlet.ParameterSetName -Eq "AppX") {
|
||||
# We only produce a ZIP when we're combining two AppX directories.
|
||||
New-Item -ItemType Directory -Path $Destination -ErrorAction:SilentlyContinue | Out-Null
|
||||
$outputZip = (Join-Path $Destination ("{0}.zip" -f ($distributionName)))
|
||||
& tar -c --format=zip -f $outputZip -C $tempDir $terminalDir
|
||||
Remove-Item -Recurse -Force $tempDir -EA:SilentlyContinue
|
||||
Get-Item $outputZip
|
||||
} ElseIf ($PSCmdlet.ParameterSetName -Eq "Layout") {
|
||||
Get-Item $terminalAppPath
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<!--
|
||||
These two properties are very important!
|
||||
@@ -141,6 +136,16 @@
|
||||
<!-- **END VC LIBS HACK** -->
|
||||
|
||||
<!-- This is required to get the package dependency in the AppXManifest. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
|
||||
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace winrt::SampleApp::implementation
|
||||
nullptr,
|
||||
32,
|
||||
80,
|
||||
winrt::guid(),
|
||||
winrt::guid()) };
|
||||
|
||||
// "Microsoft.Terminal.TerminalConnection.ConptyConnection"
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
@@ -157,6 +156,14 @@
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
By default, the PRI file will contain resource paths beginning with the
|
||||
project name. Since we enabled XBF embedding, this *also* includes App.xbf.
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
@@ -91,6 +90,14 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.7.3" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalThemeHelpers>true</TerminalThemeHelpers>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
@@ -143,6 +142,14 @@
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.3\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!-- Override GetPackagingOutputs to roll up all our dependencies.
|
||||
This ensures that when the WAP packaging project asks what files go into
|
||||
the package, we tell it.
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.7.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -1102,7 +1102,7 @@ namespace TerminalAppLocalTests
|
||||
// If you don't do this, the palette will just stay open, and the
|
||||
// next time we call _HandleNextTab, we'll continue traversing the
|
||||
// MRU list, instead of just hoping one entry.
|
||||
page->CommandPalette().Visibility(Visibility::Collapsed);
|
||||
page->LoadCommandPalette().Visibility(Visibility::Collapsed);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
@@ -1123,7 +1123,7 @@ namespace TerminalAppLocalTests
|
||||
// If you don't do this, the palette will just stay open, and the
|
||||
// next time we call _HandleNextTab, we'll continue traversing the
|
||||
// MRU list, instead of just hoping one entry.
|
||||
page->CommandPalette().Visibility(Visibility::Collapsed);
|
||||
page->LoadCommandPalette().Visibility(Visibility::Collapsed);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
@@ -1239,7 +1239,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"a", page->_mruTabs.GetAt(3).Title());
|
||||
});
|
||||
|
||||
const auto palette = winrt::get_self<winrt::TerminalApp::implementation::CommandPalette>(page->CommandPalette());
|
||||
const auto palette = winrt::get_self<winrt::TerminalApp::implementation::CommandPalette>(page->LoadCommandPalette());
|
||||
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::implementation::CommandPaletteMode::TabSwitchMode, palette->_currentMode, L"Verify we are in the tab switcher mode");
|
||||
// At this point, the contents of the command palette's _mruTabs list is
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace winrt::TerminalApp::implementation
|
||||
AboutDialog::AboutDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
_queueUpdateCheck();
|
||||
}
|
||||
|
||||
winrt::hstring AboutDialog::ApplicationDisplayName()
|
||||
@@ -74,7 +75,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_PropertyChangedHandlers(*this, WUX::Data::PropertyChangedEventArgs{ L"UpdatesAvailable" });
|
||||
}
|
||||
|
||||
winrt::fire_and_forget AboutDialog::QueueUpdateCheck()
|
||||
winrt::fire_and_forget AboutDialog::_queueUpdateCheck()
|
||||
{
|
||||
auto strongThis = get_strong();
|
||||
auto now{ std::chrono::system_clock::now() };
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::hstring ApplicationVersion();
|
||||
bool UpdatesAvailable() const;
|
||||
winrt::hstring PendingUpdateVersion() const;
|
||||
winrt::fire_and_forget QueueUpdateCheck();
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, CheckingForUpdates, _PropertyChangedHandlers, false);
|
||||
@@ -24,13 +23,13 @@ namespace winrt::TerminalApp::implementation
|
||||
private:
|
||||
friend struct AboutDialogT<AboutDialog>; // for Xaml to bind events
|
||||
|
||||
void _SetPendingUpdateVersion(const winrt::hstring& pendingUpdateVersion);
|
||||
|
||||
std::chrono::system_clock::time_point _lastUpdateCheck{};
|
||||
winrt::hstring _pendingUpdateVersion;
|
||||
|
||||
void _SetPendingUpdateVersion(const winrt::hstring& pendingUpdateVersion);
|
||||
void _ThirdPartyNoticesOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||
void _SendFeedbackOnClick(const IInspectable& sender, const Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs& eventArgs);
|
||||
winrt::fire_and_forget _queueUpdateCheck();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,5 @@ namespace TerminalApp
|
||||
Boolean CheckingForUpdates { get; };
|
||||
Boolean UpdatesAvailable { get; };
|
||||
String PendingUpdateVersion { get; };
|
||||
|
||||
void QueueUpdateCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock IsTextSelectionEnabled="True">
|
||||
<Run Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
|
||||
<Run AutomationProperties.HeadingLevel="1"
|
||||
Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
|
||||
<Run x:Uid="AboutDialog_VersionLabel" />
|
||||
<Run Text="{x:Bind ApplicationVersion}" />
|
||||
</TextBlock>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
<Application x:Class="TerminalApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:TA="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives"
|
||||
mc:Ignorable="d">
|
||||
<!--
|
||||
If you want to prove this works, then add `RequestedTheme="Light"` to
|
||||
@@ -46,8 +46,26 @@
|
||||
|
||||
<!-- Suppress top padding -->
|
||||
<Thickness x:Key="TabViewHeaderPadding">9,0,5,0</Thickness>
|
||||
|
||||
<Thickness x:Key="TabViewItemBorderThickness">1,1,1,0</Thickness>
|
||||
|
||||
<!--
|
||||
Disable the EntranceThemeTransition for our muxc:TabView, which would slowly slide in the tabs
|
||||
while the window opens. The difference is especially noticeable if window fade-in transitions are
|
||||
disabled system-wide. On my system this shaves off about 10% of the startup cost and looks better.
|
||||
-->
|
||||
<Style TargetType="primitives:TabViewListView">
|
||||
<Setter Property="ItemContainerTransitions">
|
||||
<Setter.Value>
|
||||
<TransitionCollection>
|
||||
<AddDeleteThemeTransition />
|
||||
<ContentThemeTransition />
|
||||
<ReorderThemeTransition />
|
||||
</TransitionCollection>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Shadow that can be used by any control. -->
|
||||
<ThemeShadow x:Name="SharedShadow" />
|
||||
|
||||
|
||||
@@ -613,10 +613,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<ToggleCommandPaletteArgs>())
|
||||
{
|
||||
CommandPalette().EnableCommandPaletteMode(realArgs.LaunchMode());
|
||||
CommandPalette().Visibility(CommandPalette().Visibility() == Visibility::Visible ?
|
||||
Visibility::Collapsed :
|
||||
Visibility::Visible);
|
||||
const auto p = LoadCommandPalette();
|
||||
const auto v = p.Visibility() == Visibility::Visible ? Visibility::Collapsed : Visibility::Visible;
|
||||
p.EnableCommandPaletteMode(realArgs.LaunchMode());
|
||||
p.Visibility(v);
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
@@ -799,9 +799,10 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleTabSearch(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
CommandPalette().SetTabs(_tabs, _mruTabs);
|
||||
CommandPalette().EnableTabSearchMode();
|
||||
CommandPalette().Visibility(Visibility::Visible);
|
||||
const auto p = LoadCommandPalette();
|
||||
p.SetTabs(_tabs, _mruTabs);
|
||||
p.EnableTabSearchMode();
|
||||
p.Visibility(Visibility::Visible);
|
||||
|
||||
args.Handled(true);
|
||||
}
|
||||
@@ -1144,6 +1145,35 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSelectCommand(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SelectCommandArgs>())
|
||||
{
|
||||
const auto res = _ApplyToActiveControls([&](auto& control) {
|
||||
control.SelectCommand(realArgs.Direction() == Settings::Model::SelectOutputDirection::Previous);
|
||||
});
|
||||
args.Handled(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
void TerminalPage::_HandleSelectOutput(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SelectOutputArgs>())
|
||||
{
|
||||
const auto res = _ApplyToActiveControls([&](auto& control) {
|
||||
control.SelectOutput(realArgs.Direction() == Settings::Model::SelectOutputDirection::Previous);
|
||||
});
|
||||
args.Handled(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleMarkMode(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
|
||||
@@ -145,8 +145,8 @@
|
||||
details.
|
||||
-->
|
||||
<x:Double x:Key="CaptionButtonHeightWindowed">40.0</x:Double>
|
||||
<!-- 32 + 1 to compensate for GH#10746 -->
|
||||
<x:Double x:Key="CaptionButtonHeightMaximized">33.0</x:Double>
|
||||
<!-- 32 + (1 to compensate for GH#10746) + (-1 for GH#15164) -->
|
||||
<x:Double x:Key="CaptionButtonHeightMaximized">32.0</x:Double>
|
||||
|
||||
<Style x:Key="CaptionButton"
|
||||
TargetType="Button">
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace winrt
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
#define ASSERT_UI_THREAD() assert(TabViewItem().Dispatcher().HasThreadAccess())
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
SettingsTab::SettingsTab(MainPage settingsUI,
|
||||
@@ -36,6 +38,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void SettingsTab::UpdateSettings(CascadiaSettings settings)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
auto settingsUI{ Content().as<MainPage>() };
|
||||
settingsUI.UpdateSettings(settings);
|
||||
|
||||
@@ -55,6 +59,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - The list of actions.
|
||||
std::vector<ActionAndArgs> SettingsTab::BuildStartupActions(const bool /*asContent*/) const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
ActionAndArgs action;
|
||||
action.Action(ShortcutAction::OpenSettings);
|
||||
OpenSettingsArgs args{ SettingsTarget::SettingsUI };
|
||||
@@ -71,6 +77,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void SettingsTab::Focus(WUX::FocusState focusState)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_focusState = focusState;
|
||||
|
||||
if (_focusState != FocusState::Unfocused)
|
||||
@@ -99,20 +107,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget SettingsTab::_CreateIcon()
|
||||
void SettingsTab::_CreateIcon()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
// This is the Setting icon (looks like a gear)
|
||||
static constexpr std::wstring_view glyph{ L"\xE713" };
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
auto glyph = L"\xE713"; // This is the Setting icon (looks like a gear)
|
||||
|
||||
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
||||
Icon(glyph);
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(glyph));
|
||||
}
|
||||
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
||||
Icon(winrt::hstring{ glyph });
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(glyph));
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Xaml::Media::Brush SettingsTab::_BackgroundBrush()
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
|
||||
|
||||
void _MakeTabViewItem() override;
|
||||
winrt::fire_and_forget _CreateIcon();
|
||||
void _CreateIcon();
|
||||
|
||||
virtual winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush() override;
|
||||
};
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace winrt
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
#define ASSERT_UI_THREAD() assert(TabViewItem().Dispatcher().HasThreadAccess())
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
WUX::FocusState TabBase::FocusState() const noexcept
|
||||
@@ -32,6 +34,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Prepares this tab for being removed from the UI hierarchy
|
||||
void TabBase::Shutdown()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
Content(nullptr);
|
||||
_ClosedHandlers(nullptr, nullptr);
|
||||
}
|
||||
@@ -159,6 +163,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TabBase::UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
TabViewIndex(idx);
|
||||
TabViewNumTabs(numTabs);
|
||||
_EnableCloseMenuItems();
|
||||
@@ -167,11 +173,15 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TabBase::SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_dispatch = dispatch;
|
||||
}
|
||||
|
||||
void TabBase::SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_actionMap = actionMap;
|
||||
_UpdateSwitchToTabKeyChord();
|
||||
}
|
||||
@@ -183,26 +193,18 @@ namespace winrt::TerminalApp::implementation
|
||||
// - keyChord - string representation of the key chord that switches to the current tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TabBase::_UpdateSwitchToTabKeyChord()
|
||||
void TabBase::_UpdateSwitchToTabKeyChord()
|
||||
{
|
||||
const auto keyChord = _actionMap ? _actionMap.GetKeyBindingForAction(ShortcutAction::SwitchToTab, SwitchToTabArgs{ _TabViewIndex }) : nullptr;
|
||||
const auto keyChordText = keyChord ? KeyChordSerialization::ToString(keyChord) : L"";
|
||||
|
||||
if (_keyChord == keyChordText)
|
||||
{
|
||||
co_return;
|
||||
return;
|
||||
}
|
||||
|
||||
_keyChord = keyChordText;
|
||||
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
_UpdateToolTip();
|
||||
}
|
||||
_UpdateToolTip();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -281,6 +283,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
std::optional<winrt::Windows::UI::Color> TabBase::GetTabColor()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -288,6 +292,8 @@ namespace winrt::TerminalApp::implementation
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_themeColor = focused;
|
||||
_unfocusedThemeColor = unfocused;
|
||||
_tabRowColor = tabRowColor;
|
||||
@@ -305,49 +311,37 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TabBase::_RecalculateAndApplyTabColor()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
// GetTabColor will return the color set by the color picker, or the
|
||||
// color specified in the profile. If neither of those were set,
|
||||
// then look to _themeColor to see if there's a value there.
|
||||
// Otherwise, clear our color, falling back to the TabView defaults.
|
||||
const auto currentColor = GetTabColor();
|
||||
if (currentColor.has_value())
|
||||
{
|
||||
_ApplyTabColorOnUIThread(currentColor.value());
|
||||
}
|
||||
else if (_themeColor != nullptr)
|
||||
{
|
||||
// Safely get the active control's brush.
|
||||
const Media::Brush terminalBrush{ _BackgroundBrush() };
|
||||
|
||||
TabViewItem().Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis]() {
|
||||
auto ptrTab = weakThis.get();
|
||||
if (!ptrTab)
|
||||
if (const auto themeBrush{ _themeColor.Evaluate(Application::Current().Resources(), terminalBrush, false) })
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto tab{ ptrTab };
|
||||
|
||||
// GetTabColor will return the color set by the color picker, or the
|
||||
// color specified in the profile. If neither of those were set,
|
||||
// then look to _themeColor to see if there's a value there.
|
||||
// Otherwise, clear our color, falling back to the TabView defaults.
|
||||
const auto currentColor = tab->GetTabColor();
|
||||
if (currentColor.has_value())
|
||||
{
|
||||
tab->_ApplyTabColorOnUIThread(currentColor.value());
|
||||
}
|
||||
else if (tab->_themeColor != nullptr)
|
||||
{
|
||||
// Safely get the active control's brush.
|
||||
const Media::Brush terminalBrush{ tab->_BackgroundBrush() };
|
||||
|
||||
if (const auto themeBrush{ tab->_themeColor.Evaluate(Application::Current().Resources(), terminalBrush, false) })
|
||||
{
|
||||
// ThemeColor.Evaluate will get us a Brush (because the
|
||||
// TermControl could have an acrylic BG, for example). Take
|
||||
// that brush, and get the color out of it. We don't really
|
||||
// want to have the tab items themselves be acrylic.
|
||||
tab->_ApplyTabColorOnUIThread(til::color{ ThemeColor::ColorFromBrush(themeBrush) });
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->_ClearTabBackgroundColor();
|
||||
}
|
||||
// ThemeColor.Evaluate will get us a Brush (because the
|
||||
// TermControl could have an acrylic BG, for example). Take
|
||||
// that brush, and get the color out of it. We don't really
|
||||
// want to have the tab items themselves be acrylic.
|
||||
_ApplyTabColorOnUIThread(til::color{ ThemeColor::ColorFromBrush(themeBrush) });
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->_ClearTabBackgroundColor();
|
||||
_ClearTabBackgroundColor();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_ClearTabBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _EnableCloseMenuItems();
|
||||
void _CloseTabsAfter();
|
||||
void _CloseOtherTabs();
|
||||
winrt::fire_and_forget _UpdateSwitchToTabKeyChord();
|
||||
void _UpdateSwitchToTabKeyChord();
|
||||
void _UpdateToolTip();
|
||||
|
||||
void _RecalculateAndApplyTabColor();
|
||||
|
||||
@@ -600,13 +600,14 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandPalette().SetTabs(_tabs, _mruTabs);
|
||||
const auto p = LoadCommandPalette();
|
||||
p.SetTabs(_tabs, _mruTabs);
|
||||
|
||||
// Otherwise, set up the tab switcher in the selected mode, with
|
||||
// the given ordering, and make it visible.
|
||||
CommandPalette().EnableTabSwitcherMode(index, tabSwitchMode);
|
||||
CommandPalette().Visibility(Visibility::Visible);
|
||||
CommandPalette().SelectNextItem(bMoveRight);
|
||||
p.EnableTabSwitcherMode(index, tabSwitchMode);
|
||||
p.Visibility(Visibility::Visible);
|
||||
p.SelectNextItem(bMoveRight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,7 +917,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_UpdatedSelectedTab(const winrt::TerminalApp::TabBase& tab)
|
||||
{
|
||||
// Unfocus all the tabs.
|
||||
for (auto tab : _tabs)
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
tab.Focus(FocusState::Unfocused);
|
||||
}
|
||||
@@ -936,7 +937,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// When the tab switcher is eventually dismissed, the focus will
|
||||
// get tossed back to the focused terminal control, so we don't
|
||||
// need to worry about focus getting lost.
|
||||
if (CommandPalette().Visibility() != Visibility::Visible)
|
||||
const auto p = CommandPaletteElement();
|
||||
if (!p || p.Visibility() != Visibility::Visible)
|
||||
{
|
||||
tab.Focus(FocusState::Programmatic);
|
||||
_UpdateMRUTab(tab);
|
||||
|
||||
@@ -12,9 +12,20 @@
|
||||
Background="{ThemeResource TabViewBackground}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<!-- GH#13143: Make sure that the Background is actually TabViewBackground here, not Transparent. This is load bearing, for showTabsInTitlebar=false. -->
|
||||
<!--
|
||||
GH#13143: Make sure that the Background is actually TabViewBackground
|
||||
here, not Transparent. This is load bearing, for showTabsInTitlebar=false.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Set the padding to -1 on the bottom. This prevents a small 1px gap that
|
||||
can appear on 150% scale displays between the tab item and the content.
|
||||
The 1 on top helps keep the tab the correct relative height within the
|
||||
tab row.
|
||||
-->
|
||||
|
||||
<mux:TabView x:Name="TabView"
|
||||
Padding="0,1,0,-1"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
AllowDropTabs="True"
|
||||
|
||||
@@ -113,13 +113,14 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_settings = settings;
|
||||
|
||||
// Make sure to _UpdateCommandsForPalette before
|
||||
// _RefreshUIForSettingsReload. _UpdateCommandsForPalette will make
|
||||
// sure the KeyChordText of Commands is updated, which needs to
|
||||
// happen before the Settings UI is reloaded and tries to re-read
|
||||
// those values.
|
||||
_UpdateCommandsForPalette();
|
||||
CommandPalette().SetActionMap(_settings.ActionMap());
|
||||
// Make sure to call SetCommands before _RefreshUIForSettingsReload.
|
||||
// SetCommands will make sure the KeyChordText of Commands is updated, which needs
|
||||
// to happen before the Settings UI is reloaded and tries to re-read those values.
|
||||
if (const auto p = CommandPaletteElement())
|
||||
{
|
||||
p.SetCommands(_settings.GlobalSettings().ActionMap().ExpandedCommands());
|
||||
p.SetActionMap(_settings.ActionMap());
|
||||
}
|
||||
|
||||
if (needRefreshUI)
|
||||
{
|
||||
@@ -255,20 +256,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_UpdateTabWidthMode();
|
||||
|
||||
// When the visibility of the command palette changes to "collapsed",
|
||||
// the palette has been closed. Toss focus back to the currently active
|
||||
// control.
|
||||
CommandPalette().RegisterPropertyChangedCallback(UIElement::VisibilityProperty(), [this](auto&&, auto&&) {
|
||||
if (CommandPalette().Visibility() == Visibility::Collapsed)
|
||||
{
|
||||
_FocusActiveControl(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
CommandPalette().DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
|
||||
CommandPalette().CommandLineExecutionRequested({ this, &TerminalPage::_OnCommandLineExecutionRequested });
|
||||
CommandPalette().SwitchToTabRequested({ this, &TerminalPage::_OnSwitchToTabRequested });
|
||||
CommandPalette().PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
|
||||
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
// want to create an animation.
|
||||
@@ -684,7 +671,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// Notes link, send feedback link and privacy policy link.
|
||||
void TerminalPage::_ShowAboutDialog()
|
||||
{
|
||||
AboutDialog().QueueUpdateCheck();
|
||||
_ShowDialogHelper(L"AboutDialog");
|
||||
}
|
||||
|
||||
@@ -1333,8 +1319,9 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_CommandPaletteButtonOnClick(const IInspectable&,
|
||||
const RoutedEventArgs&)
|
||||
{
|
||||
CommandPalette().EnableCommandPaletteMode(CommandPaletteLaunchMode::Action);
|
||||
CommandPalette().Visibility(Visibility::Visible);
|
||||
auto p = LoadCommandPalette();
|
||||
p.EnableCommandPaletteMode(CommandPaletteLaunchMode::Action);
|
||||
p.Visibility(Visibility::Visible);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1350,7 +1337,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when the users pressed keyBindings while CommandPalette is open.
|
||||
// - Called when the users pressed keyBindings while CommandPaletteElement is open.
|
||||
// - As of GH#8480, this is also bound to the TabRowControl's KeyUp event.
|
||||
// That should only fire when focus is in the tab row, which is hard to
|
||||
// do. Notably, that's possible:
|
||||
@@ -1421,7 +1408,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto p = CommandPalette(); p.Visibility() == Visibility::Visible && cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
if (const auto p = CommandPaletteElement(); p.Visibility() == Visibility::Visible && cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
{
|
||||
p.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
@@ -1745,6 +1732,40 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CommandPalette TerminalPage::LoadCommandPalette()
|
||||
{
|
||||
if (const auto p = CommandPaletteElement())
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
return _loadCommandPaletteSlowPath();
|
||||
}
|
||||
|
||||
CommandPalette TerminalPage::_loadCommandPaletteSlowPath()
|
||||
{
|
||||
const auto p = FindName(L"CommandPaletteElement").as<CommandPalette>();
|
||||
|
||||
p.SetCommands(_settings.GlobalSettings().ActionMap().ExpandedCommands());
|
||||
p.SetActionMap(_settings.ActionMap());
|
||||
|
||||
// When the visibility of the command palette changes to "collapsed",
|
||||
// the palette has been closed. Toss focus back to the currently active control.
|
||||
p.RegisterPropertyChangedCallback(UIElement::VisibilityProperty(), [this](auto&&, auto&&) {
|
||||
if (CommandPaletteElement().Visibility() == Visibility::Collapsed)
|
||||
{
|
||||
_FocusActiveControl(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
p.DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
|
||||
p.CommandLineExecutionRequested({ this, &TerminalPage::_OnCommandLineExecutionRequested });
|
||||
p.SwitchToTabRequested({ this, &TerminalPage::_OnSwitchToTabRequested });
|
||||
p.PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Warn the user that they are about to close all open windows, then
|
||||
// signal that we want to close everything.
|
||||
@@ -3140,21 +3161,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Repopulates the list of commands in the command palette with the
|
||||
// current commands in the settings. Also updates the keybinding labels to
|
||||
// reflect any matching keybindings.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateCommandsForPalette()
|
||||
{
|
||||
// Update the command palette when settings reload
|
||||
const auto& expanded{ _settings.GlobalSettings().ActionMap().ExpandedCommands() };
|
||||
CommandPalette().SetCommands(expanded);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the initial actions to process on startup. We'll make a copy of
|
||||
// this list, and process these actions when we're loaded.
|
||||
@@ -4828,5 +4834,4 @@ namespace winrt::TerminalApp::implementation
|
||||
// _RemoveTab will make sure to null out the _stashed.draggedTab
|
||||
_RemoveTab(*_stashed.draggedTab);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::hstring ApplicationDisplayName();
|
||||
winrt::hstring ApplicationVersion();
|
||||
|
||||
CommandPalette LoadCommandPalette();
|
||||
winrt::fire_and_forget RequestQuit();
|
||||
winrt::fire_and_forget CloseWindow(bool bypassDialog);
|
||||
|
||||
@@ -274,6 +275,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ConptyConnection::NewConnection_revoker _newConnectionRevoker;
|
||||
|
||||
__declspec(noinline) CommandPalette _loadCommandPaletteSlowPath();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowDialogHelper(const std::wstring_view& name);
|
||||
|
||||
void _ShowAboutDialog();
|
||||
@@ -312,7 +314,6 @@ namespace winrt::TerminalApp::implementation
|
||||
void _UpdateTabIcon(TerminalTab& tab);
|
||||
void _UpdateTabView();
|
||||
void _UpdateTabWidthMode();
|
||||
void _UpdateCommandsForPalette();
|
||||
void _SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance);
|
||||
|
||||
void _DuplicateFocusedTab();
|
||||
|
||||
@@ -97,7 +97,8 @@
|
||||
-->
|
||||
|
||||
<local:AboutDialog x:Name="AboutDialog"
|
||||
Grid.Row="2" />
|
||||
Grid.Row="2"
|
||||
x:Load="False" />
|
||||
|
||||
<ContentDialog x:Name="QuitDialog"
|
||||
x:Uid="QuitDialog"
|
||||
@@ -167,9 +168,10 @@
|
||||
</TextBlock>
|
||||
</ContentDialog>
|
||||
|
||||
<local:CommandPalette x:Name="CommandPalette"
|
||||
<local:CommandPalette x:Name="CommandPaletteElement"
|
||||
Grid.Row="2"
|
||||
VerticalAlignment="Stretch"
|
||||
x:Load="False"
|
||||
PreviewKeyDown="_KeyDownHandler"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace winrt
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
#define ASSERT_UI_THREAD() assert(TabViewItem().Dispatcher().HasThreadAccess())
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TerminalTab::TerminalTab(std::shared_ptr<Pane> rootPane)
|
||||
@@ -143,30 +145,23 @@ namespace winrt::TerminalApp::implementation
|
||||
_RecalculateAndApplyTabColor();
|
||||
}
|
||||
|
||||
winrt::fire_and_forget TerminalTab::_UpdateHeaderControlMaxWidth()
|
||||
void TerminalTab::_UpdateHeaderControlMaxWidth()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
try
|
||||
{
|
||||
try
|
||||
// Make sure to try/catch this, because the LocalTests won't be
|
||||
// able to use this helper.
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
if (settings.GlobalSettings().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
|
||||
{
|
||||
// Make sure to try/catch this, because the LocalTests won't be
|
||||
// able to use this helper.
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
if (settings.GlobalSettings().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
|
||||
{
|
||||
tab->_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthTitleLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthDefault);
|
||||
}
|
||||
_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthTitleLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthDefault);
|
||||
}
|
||||
CATCH_LOG()
|
||||
}
|
||||
CATCH_LOG()
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -182,6 +177,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// that was last focused.
|
||||
TermControl TerminalTab::GetActiveTerminalControl() const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (_activePane)
|
||||
{
|
||||
return _activePane->GetLastFocusedTerminalControl();
|
||||
@@ -198,6 +195,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::Initialize()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_rootPane->WalkTree([&](std::shared_ptr<Pane> pane) {
|
||||
// Attach event handlers to each new pane
|
||||
_AttachEventHandlersToPane(pane);
|
||||
@@ -217,6 +216,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::Focus(WUX::FocusState focusState)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_focusState = focusState;
|
||||
|
||||
if (_focusState != FocusState::Unfocused)
|
||||
@@ -249,6 +250,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// focused, else the GUID of the profile of the last control to be focused
|
||||
Profile TerminalTab::GetFocusedProfile() const noexcept
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _activePane->GetFocusedProfile();
|
||||
}
|
||||
|
||||
@@ -260,6 +263,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::UpdateSettings()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// The tabWidthMode may have changed, update the header control accordingly
|
||||
_UpdateHeaderControlMaxWidth();
|
||||
}
|
||||
@@ -270,12 +275,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// - iconPath: The new path string to use as the IconPath for our TabViewItem
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TerminalTab::UpdateIcon(const winrt::hstring iconPath)
|
||||
void TerminalTab::UpdateIcon(const winrt::hstring iconPath)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// Don't reload our icon if it hasn't changed.
|
||||
if (iconPath == _lastIconPath)
|
||||
{
|
||||
co_return;
|
||||
return;
|
||||
}
|
||||
|
||||
_lastIconPath = iconPath;
|
||||
@@ -284,19 +291,12 @@ namespace winrt::TerminalApp::implementation
|
||||
// for when we show the icon again)
|
||||
if (_iconHidden)
|
||||
{
|
||||
co_return;
|
||||
return;
|
||||
}
|
||||
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
||||
Icon(_lastIconPath);
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath));
|
||||
}
|
||||
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
||||
Icon(_lastIconPath);
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -304,28 +304,23 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Used when we want to show the progress ring, which should replace the icon
|
||||
// Arguments:
|
||||
// - hide: if true, we hide the icon; if false, we show the icon
|
||||
winrt::fire_and_forget TerminalTab::HideIcon(const bool hide)
|
||||
void TerminalTab::HideIcon(const bool hide)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
if (_iconHidden != hide)
|
||||
{
|
||||
if (tab->_iconHidden != hide)
|
||||
if (hide)
|
||||
{
|
||||
if (hide)
|
||||
{
|
||||
Icon({});
|
||||
TabViewItem().IconSource(IconSource{ nullptr });
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon(_lastIconPath);
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath));
|
||||
}
|
||||
tab->_iconHidden = hide;
|
||||
Icon({});
|
||||
TabViewItem().IconSource(IconSource{ nullptr });
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon(_lastIconPath);
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath));
|
||||
}
|
||||
_iconHidden = hide;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,37 +328,27 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Hide or show the bell indicator in the tab header
|
||||
// Arguments:
|
||||
// - show: if true, we show the indicator; if false, we hide the indicator
|
||||
winrt::fire_and_forget TerminalTab::ShowBellIndicator(const bool show)
|
||||
void TerminalTab::ShowBellIndicator(const bool show)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
_tabStatus.BellIndicator(show);
|
||||
}
|
||||
_tabStatus.BellIndicator(show);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Activates the timer for the bell indicator in the tab
|
||||
// - Called if a bell raised when the tab already has focus
|
||||
winrt::fire_and_forget TerminalTab::ActivateBellIndicatorTimer()
|
||||
void TerminalTab::ActivateBellIndicatorTimer()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
if (!_bellIndicatorTimer.has_value())
|
||||
{
|
||||
if (!tab->_bellIndicatorTimer.has_value())
|
||||
{
|
||||
DispatcherTimer bellIndicatorTimer;
|
||||
bellIndicatorTimer.Interval(std::chrono::milliseconds(2000));
|
||||
bellIndicatorTimer.Tick({ get_weak(), &TerminalTab::_BellIndicatorTimerTick });
|
||||
bellIndicatorTimer.Start();
|
||||
tab->_bellIndicatorTimer.emplace(std::move(bellIndicatorTimer));
|
||||
}
|
||||
DispatcherTimer bellIndicatorTimer;
|
||||
bellIndicatorTimer.Interval(std::chrono::milliseconds(2000));
|
||||
bellIndicatorTimer.Tick({ get_weak(), &TerminalTab::_BellIndicatorTimerTick });
|
||||
bellIndicatorTimer.Start();
|
||||
_bellIndicatorTimer.emplace(std::move(bellIndicatorTimer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,21 +381,18 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TerminalTab::UpdateTitle()
|
||||
void TerminalTab::UpdateTitle()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
co_await wil::resume_foreground(TabViewItem().Dispatcher());
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
const auto activeTitle = _GetActiveTitle();
|
||||
// Bubble our current tab text to anyone who's listening for changes.
|
||||
Title(activeTitle);
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// Update the control to reflect the changed title
|
||||
_headerControl.Title(activeTitle);
|
||||
Automation::AutomationProperties::SetName(tab->TabViewItem(), activeTitle);
|
||||
_UpdateToolTip();
|
||||
}
|
||||
const auto activeTitle = _GetActiveTitle();
|
||||
// Bubble our current tab text to anyone who's listening for changes.
|
||||
Title(activeTitle);
|
||||
|
||||
// Update the control to reflect the changed title
|
||||
_headerControl.Title(activeTitle);
|
||||
Automation::AutomationProperties::SetName(TabViewItem(), activeTitle);
|
||||
_UpdateToolTip();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -421,12 +403,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// - delta: a number of lines to move the viewport relative to the current viewport.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TerminalTab::Scroll(const int delta)
|
||||
void TerminalTab::Scroll(const int delta)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
auto control = GetActiveTerminalControl();
|
||||
|
||||
co_await wil::resume_foreground(control.Dispatcher());
|
||||
|
||||
const auto currentOffset = control.ScrollOffset();
|
||||
control.ScrollViewport(::base::ClampAdd(currentOffset, delta));
|
||||
}
|
||||
@@ -440,6 +421,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - A vector of commands
|
||||
std::vector<ActionAndArgs> TerminalTab::BuildStartupActions(const bool asContent) const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// Give initial ids (0 for the child created with this tab,
|
||||
// 1 for the child after the first split.
|
||||
auto state = _rootPane->BuildStartupActions(0, 1, asContent);
|
||||
@@ -513,6 +496,8 @@ namespace winrt::TerminalApp::implementation
|
||||
const float splitSize,
|
||||
std::shared_ptr<Pane> pane)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// Add the new event handlers to the new pane(s)
|
||||
// and update their ids.
|
||||
pane->WalkTree([&](auto p) {
|
||||
@@ -560,6 +545,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - The removed pane, if the remove succeeded.
|
||||
std::shared_ptr<Pane> TerminalTab::DetachPane()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// if we only have one pane, or the focused pane is the root, remove it
|
||||
// entirely and close this tab
|
||||
if (_rootPane == _activePane)
|
||||
@@ -587,6 +574,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - The root pane.
|
||||
std::shared_ptr<Pane> TerminalTab::DetachRoot()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// remove the closed event handler since we are closing the tab
|
||||
// manually.
|
||||
_rootPane->Closed(_rootClosedToken);
|
||||
@@ -613,6 +602,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::AttachPane(std::shared_ptr<Pane> pane)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// Add the new event handlers to the new pane(s)
|
||||
// and update their ids.
|
||||
pane->WalkTree([&](auto p) {
|
||||
@@ -658,6 +649,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::AttachColorPicker(TerminalApp::ColorPickupFlyout& colorPicker)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
_tabColorPickup = colorPicker;
|
||||
@@ -696,6 +689,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::ToggleSplitOrientation()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_rootPane->ToggleSplitOrientation();
|
||||
}
|
||||
|
||||
@@ -703,6 +698,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - See Pane::CalcSnappedDimension
|
||||
float TerminalTab::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _rootPane->CalcSnappedDimension(widthOrHeight, dimension);
|
||||
}
|
||||
|
||||
@@ -715,6 +712,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::ResizePane(const ResizeDirection& direction)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// NOTE: This _must_ be called on the root pane, so that it can propagate
|
||||
// throughout the entire tree.
|
||||
_rootPane->ResizePane(direction);
|
||||
@@ -730,6 +729,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// to the terminal when no other panes are present (GH#6219)
|
||||
bool TerminalTab::NavigateFocus(const FocusDirection& direction)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// NOTE: This _must_ be called on the root pane, so that it can propagate
|
||||
// throughout the entire tree.
|
||||
if (const auto newFocus = _rootPane->NavigateDirection(_activePane, direction, _mruPanes))
|
||||
@@ -760,6 +761,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - true if two panes were swapped.
|
||||
bool TerminalTab::SwapPane(const FocusDirection& direction)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// You cannot swap panes with the parent/child pane because of the
|
||||
// circular reference.
|
||||
if (direction == FocusDirection::Parent || direction == FocusDirection::Child)
|
||||
@@ -783,6 +786,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalTab::FocusPane(const uint32_t id)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (_rootPane == nullptr)
|
||||
{
|
||||
return false;
|
||||
@@ -797,6 +802,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Prepares this tab for being removed from the UI hierarchy by shutting down all active connections.
|
||||
void TerminalTab::Shutdown()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (_rootPane)
|
||||
{
|
||||
_rootPane->Shutdown();
|
||||
@@ -813,22 +820,30 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::ClosePane()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_activePane->Close();
|
||||
}
|
||||
|
||||
void TerminalTab::SetTabText(winrt::hstring title)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_runtimeTabText = title;
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
winrt::hstring TerminalTab::GetTabText() const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _runtimeTabText;
|
||||
}
|
||||
|
||||
void TerminalTab::ResetTabText()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_runtimeTabText = L"";
|
||||
UpdateTitle();
|
||||
}
|
||||
@@ -842,6 +857,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::ActivateTabRenamer()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_headerControl.BeginRename();
|
||||
}
|
||||
|
||||
@@ -889,7 +906,8 @@ namespace winrt::TerminalApp::implementation
|
||||
auto dispatcher = TabViewItem().Dispatcher();
|
||||
ControlEventTokens events{};
|
||||
|
||||
events.titleToken = control.TitleChanged([weakThis](auto&&, auto&&) {
|
||||
events.titleToken = control.TitleChanged([dispatcher, weakThis](auto&&, auto&&) -> winrt::fire_and_forget {
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
// Check if Tab's lifetime has expired
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
@@ -899,7 +917,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
events.colorToken = control.TabColorChanged([weakThis](auto&&, auto&&) {
|
||||
events.colorToken = control.TabColorChanged([dispatcher, weakThis](auto&&, auto&&) -> winrt::fire_and_forget {
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
// The control's tabColor changed, but it is not necessarily the
|
||||
@@ -918,14 +937,16 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
events.readOnlyToken = control.ReadOnlyChanged([weakThis](auto&&, auto&&) {
|
||||
events.readOnlyToken = control.ReadOnlyChanged([dispatcher, weakThis](auto&&, auto&&) -> winrt::fire_and_forget {
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_RecalculateAndApplyReadOnly();
|
||||
}
|
||||
});
|
||||
|
||||
events.focusToken = control.FocusFollowMouseRequested([weakThis](auto&& sender, auto&&) {
|
||||
events.focusToken = control.FocusFollowMouseRequested([dispatcher, weakThis](auto&& sender, auto&&) -> winrt::fire_and_forget {
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (const auto tab{ weakThis.get() })
|
||||
{
|
||||
if (tab->_focusState != FocusState::Unfocused)
|
||||
@@ -955,6 +976,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// progress percentage of all our panes.
|
||||
winrt::TerminalApp::TaskbarState TerminalTab::GetCombinedTaskbarState() const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
std::vector<winrt::TerminalApp::TaskbarState> states;
|
||||
if (_rootPane)
|
||||
{
|
||||
@@ -1114,13 +1137,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Add a Closed event handler to the Pane. If the pane closes out from
|
||||
// underneath us, and it's zoomed, we want to be able to make sure to
|
||||
// update our state accordingly to un-zoom that pane. See GH#7252.
|
||||
auto closedToken = pane->Closed([weakThis, weakPane](auto&& /*s*/, auto&& /*e*/) -> winrt::fire_and_forget {
|
||||
auto closedToken = pane->Closed([weakThis, weakPane](auto&& /*s*/, auto&& /*e*/) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
if (tab->_zoomedPane)
|
||||
{
|
||||
co_await wil::resume_foreground(tab->Content().Dispatcher());
|
||||
|
||||
tab->Content(tab->_rootPane->GetRootElement());
|
||||
tab->ExitZoom();
|
||||
}
|
||||
@@ -1133,7 +1154,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// did not actually change. Triggering
|
||||
if (pane != tab->_activePane && !tab->_activePane->_IsLeaf())
|
||||
{
|
||||
co_await wil::resume_foreground(tab->Content().Dispatcher());
|
||||
tab->_UpdateActivePane(tab->_activePane);
|
||||
}
|
||||
|
||||
@@ -1387,6 +1407,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - The tab's color, if any
|
||||
std::optional<winrt::Windows::UI::Color> TerminalTab::GetTabColor()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
std::optional<winrt::Windows::UI::Color> controlTabColor;
|
||||
if (const auto& control = GetActiveTerminalControl())
|
||||
{
|
||||
@@ -1425,6 +1447,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::SetRuntimeTabColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_runtimeTabColor.emplace(color);
|
||||
_RecalculateAndApplyTabColor();
|
||||
}
|
||||
@@ -1439,6 +1463,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::ResetRuntimeTabColor()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_runtimeTabColor.reset();
|
||||
_RecalculateAndApplyTabColor();
|
||||
}
|
||||
@@ -1462,6 +1488,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::RequestColorPicker()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_ColorPickerRequestedHandlers();
|
||||
}
|
||||
|
||||
@@ -1473,6 +1501,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - The total number of leaf panes hosted by this tab.
|
||||
int TerminalTab::GetLeafPaneCount() const noexcept
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _rootPane->GetLeafPaneCount();
|
||||
}
|
||||
|
||||
@@ -1490,6 +1520,8 @@ namespace winrt::TerminalApp::implementation
|
||||
const float splitSize,
|
||||
winrt::Windows::Foundation::Size availableSpace) const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _rootPane->PreCalculateCanSplit(_activePane, splitType, splitSize, availableSpace).value_or(std::nullopt);
|
||||
}
|
||||
|
||||
@@ -1501,6 +1533,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::UpdateZoom(std::shared_ptr<Pane> newFocus)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// clear the existing content so the old zoomed pane can be added back to the root tree
|
||||
Content(nullptr);
|
||||
_rootPane->Restore(_zoomedPane);
|
||||
@@ -1521,6 +1555,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalTab::ToggleZoom()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (_zoomedPane)
|
||||
{
|
||||
ExitZoom();
|
||||
@@ -1533,6 +1569,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TerminalTab::EnterZoom()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// Clear the content first, because with parent focusing it is possible
|
||||
// to zoom the root pane, but setting the content will not trigger the
|
||||
// property changed event since it is the same and you would end up with
|
||||
@@ -1546,6 +1584,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
void TerminalTab::ExitZoom()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
Content(nullptr);
|
||||
_rootPane->Restore(_zoomedPane);
|
||||
_zoomedPane = nullptr;
|
||||
@@ -1556,6 +1596,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalTab::IsZoomed()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _zoomedPane != nullptr;
|
||||
}
|
||||
|
||||
@@ -1565,6 +1607,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// the same read-only status.
|
||||
void TerminalTab::TogglePaneReadOnly()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
auto hasReadOnly = false;
|
||||
auto allReadOnly = true;
|
||||
_activePane->WalkTree([&](const auto& p) {
|
||||
@@ -1642,6 +1686,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
std::shared_ptr<Pane> TerminalTab::GetActivePane() const
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return _activePane;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override;
|
||||
|
||||
winrt::fire_and_forget Scroll(const int delta);
|
||||
void Scroll(const int delta);
|
||||
|
||||
std::shared_ptr<Pane> DetachRoot();
|
||||
std::shared_ptr<Pane> DetachPane();
|
||||
@@ -41,11 +41,11 @@ namespace winrt::TerminalApp::implementation
|
||||
std::shared_ptr<Pane> newPane);
|
||||
|
||||
void ToggleSplitOrientation();
|
||||
winrt::fire_and_forget UpdateIcon(const winrt::hstring iconPath);
|
||||
winrt::fire_and_forget HideIcon(const bool hide);
|
||||
void UpdateIcon(const winrt::hstring iconPath);
|
||||
void HideIcon(const bool hide);
|
||||
|
||||
winrt::fire_and_forget ShowBellIndicator(const bool show);
|
||||
winrt::fire_and_forget ActivateBellIndicatorTimer();
|
||||
void ShowBellIndicator(const bool show);
|
||||
void ActivateBellIndicatorTimer();
|
||||
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
@@ -58,7 +58,7 @@ namespace winrt::TerminalApp::implementation
|
||||
bool FocusPane(const uint32_t id);
|
||||
|
||||
void UpdateSettings();
|
||||
winrt::fire_and_forget UpdateTitle();
|
||||
void UpdateTitle();
|
||||
|
||||
void Shutdown() override;
|
||||
void ClosePane();
|
||||
@@ -155,7 +155,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _MakeTabViewItem() override;
|
||||
|
||||
winrt::fire_and_forget _UpdateHeaderControlMaxWidth();
|
||||
void _UpdateHeaderControlMaxWidth();
|
||||
|
||||
void _CreateContextMenu() override;
|
||||
virtual winrt::hstring _CreateToolTipTitle() override;
|
||||
|
||||
@@ -900,6 +900,12 @@ namespace winrt::TerminalApp::implementation
|
||||
if (!focusedObject)
|
||||
{
|
||||
focusedObject = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetParent(focusedElement);
|
||||
|
||||
// We were unable to find a focused object. Default to the xaml root so that the alt+space menu still works.
|
||||
if (!focusedObject)
|
||||
{
|
||||
focusedObject = _root.try_as<IInspectable>();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -908,6 +914,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
} while (focusedObject);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2182,6 +2182,90 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::SelectCommand(const bool goUp)
|
||||
{
|
||||
const til::point start = HasSelection() ? (goUp ? _terminal->GetSelectionAnchor() : _terminal->GetSelectionEnd()) :
|
||||
_terminal->GetTextBuffer().GetCursor().GetPosition();
|
||||
std::optional<DispatchTypes::ScrollMark> nearest{ std::nullopt };
|
||||
const auto& marks{ _terminal->GetScrollMarks() };
|
||||
|
||||
// Early return so we don't have to check for the validity of `nearest` below after the loop exits.
|
||||
if (marks.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static constexpr til::point worst{ til::CoordTypeMax, til::CoordTypeMax };
|
||||
til::point bestDistance{ worst };
|
||||
|
||||
for (const auto& m : marks)
|
||||
{
|
||||
if (!m.HasCommand())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto distance = goUp ? start - m.end : m.end - start;
|
||||
if ((distance > til::point{ 0, 0 }) && distance < bestDistance)
|
||||
{
|
||||
nearest = m;
|
||||
bestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (nearest.has_value())
|
||||
{
|
||||
const auto start = nearest->end;
|
||||
auto end = *nearest->commandEnd;
|
||||
|
||||
const auto bufferSize{ _terminal->GetTextBuffer().GetSize() };
|
||||
bufferSize.DecrementInBounds(end);
|
||||
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->SelectNewRegion(start, end);
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::SelectOutput(const bool goUp)
|
||||
{
|
||||
const til::point start = HasSelection() ? (goUp ? _terminal->GetSelectionAnchor() : _terminal->GetSelectionEnd()) :
|
||||
_terminal->GetTextBuffer().GetCursor().GetPosition();
|
||||
std::optional<DispatchTypes::ScrollMark> nearest{ std::nullopt };
|
||||
const auto& marks{ _terminal->GetScrollMarks() };
|
||||
|
||||
static constexpr til::point worst{ til::CoordTypeMax, til::CoordTypeMax };
|
||||
til::point bestDistance{ worst };
|
||||
|
||||
for (const auto& m : marks)
|
||||
{
|
||||
if (!m.HasOutput())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto distance = goUp ? start - *m.commandEnd : *m.commandEnd - start;
|
||||
if ((distance > til::point{ 0, 0 }) && distance < bestDistance)
|
||||
{
|
||||
nearest = m;
|
||||
bestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (nearest.has_value())
|
||||
{
|
||||
const auto start = *nearest->commandEnd;
|
||||
auto end = *nearest->outputEnd;
|
||||
|
||||
const auto bufferSize{ _terminal->GetTextBuffer().GetSize() };
|
||||
bufferSize.DecrementInBounds(end);
|
||||
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->SelectNewRegion(start, end);
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::ColorSelection(const Control::SelectionColor& fg, const Control::SelectionColor& bg, Core::MatchMode matchMode)
|
||||
{
|
||||
if (HasSelection())
|
||||
|
||||
@@ -152,7 +152,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
|
||||
|
||||
void SelectCommand(const bool goUp);
|
||||
void SelectOutput(const bool goUp);
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ITerminalInput
|
||||
|
||||
@@ -57,6 +57,8 @@ namespace Microsoft.Terminal.Control
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
void ScrollToMark(ScrollToMarkDirection direction);
|
||||
void SelectCommand(Boolean goUp);
|
||||
void SelectOutput(Boolean goUp);
|
||||
IVector<ScrollMark> ScrollMarks { get; };
|
||||
|
||||
};
|
||||
|
||||
@@ -961,11 +961,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
auto bufferHeight = _core.BufferHeight();
|
||||
|
||||
ScrollBar().Maximum(bufferHeight - bufferHeight);
|
||||
ScrollBar().Maximum(0);
|
||||
ScrollBar().Minimum(0);
|
||||
ScrollBar().Value(0);
|
||||
ScrollBar().ViewportSize(bufferHeight);
|
||||
ScrollBar().LargeChange(std::max(bufferHeight - 1, 0)); // scroll one "screenful" at a time when the scroll bar is clicked
|
||||
ScrollBar().LargeChange(bufferHeight); // scroll one "screenful" at a time when the scroll bar is clicked
|
||||
|
||||
// Set up blinking cursor
|
||||
int blinkTime = GetCaretBlinkTime();
|
||||
@@ -3316,6 +3316,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.ScrollMarks();
|
||||
}
|
||||
|
||||
void TermControl::SelectCommand(const bool goUp)
|
||||
{
|
||||
_core.SelectCommand(goUp);
|
||||
}
|
||||
|
||||
void TermControl::SelectOutput(const bool goUp)
|
||||
{
|
||||
_core.SelectOutput(goUp);
|
||||
}
|
||||
|
||||
void TermControl::ColorSelection(Control::SelectionColor fg, Control::SelectionColor bg, Core::MatchMode matchMode)
|
||||
{
|
||||
_core.ColorSelection(fg, bg, matchMode);
|
||||
|
||||
@@ -81,6 +81,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
|
||||
void SelectCommand(const bool goUp);
|
||||
void SelectOutput(const bool goUp);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
@@ -72,14 +72,21 @@
|
||||
latest ControlsV2 version of the template can be found at:
|
||||
https://github.com/microsoft/microsoft-ui-xaml/blob/main/dev/CommonStyles/ScrollBar_themeresources.xaml#L218
|
||||
|
||||
We're also removing the corner radius, cause that should be flush
|
||||
Additionally we have:
|
||||
* removed the corner radius, because that should be flush
|
||||
with the top of the window above the TermControl.
|
||||
* set ScrollBarExpandBeginTime to 0 so that the scrollbar, fades in instantly when it's expanded.
|
||||
This makes it feel much better with cursors compared to the questionable standard 400ms delay in
|
||||
the Win11-style WinUI ScrollView. If you also have the "Always show scrollbars" setting enabled in
|
||||
the settings app (do it if you haven't already), it avoids any and all animations during startup which
|
||||
makes the app start feel noticeably better and also shaves off another ~167ms of our "busy time".
|
||||
|
||||
We're also planning on making this adjustable in the future
|
||||
(GH#9218), where we might need this anyways.
|
||||
-->
|
||||
|
||||
<x:Double x:Key="ScrollBarSize">16</x:Double>
|
||||
<x:String x:Key="ScrollBarExpandBeginTime">0</x:String>
|
||||
|
||||
<Style x:Key="ForkedScrollbarTemplate"
|
||||
TargetType="ScrollBar">
|
||||
|
||||
@@ -186,7 +186,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
DependencyProperty Appearances::_AppearanceProperty{ nullptr };
|
||||
|
||||
Appearances::Appearances() :
|
||||
_ShowAllFonts{ false }
|
||||
_ShowAllFonts{ false },
|
||||
_ShowProportionalFontWarning{ false }
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -315,6 +316,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
const auto selectedItem{ e.AddedItems().GetAt(0) };
|
||||
const auto newFontFace{ unbox_value<Editor::Font>(selectedItem) };
|
||||
Appearance().FontFace(newFontFace.LocalizedName());
|
||||
if (!UsingMonospaceFont())
|
||||
{
|
||||
ShowProportionalFontWarning(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowProportionalFontWarning(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Appearances::_ViewModelChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
|
||||
@@ -376,6 +385,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentAdjustIndistinguishableColors" });
|
||||
}
|
||||
else if (settingName == L"ShowProportionalFontWarning")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"ShowProportionalFontWarning" });
|
||||
}
|
||||
// YOU THERE ADDING A NEW APPEARANCE SETTING
|
||||
// Make sure you add a block like
|
||||
//
|
||||
@@ -407,6 +420,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"UsingMonospaceFont" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentIntenseTextStyle" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentAdjustIndistinguishableColors" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"ShowProportionalFontWarning" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,4 +501,5 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// whereas SelectedItem identifies which one was selected by the user.
|
||||
return FontWeightComboBox().SelectedItem() == _CustomFontWeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -130,10 +130,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
DEPENDENCY_PROPERTY(Editor::AppearanceViewModel, Appearance);
|
||||
WINRT_PROPERTY(Editor::ProfileViewModel, SourceProfile, nullptr);
|
||||
WINRT_PROPERTY(IHostedInWindow, WindowRoot, nullptr);
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch, Appearance().BackgroundImageStretchMode);
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(IntenseTextStyle, Microsoft::Terminal::Settings::Model::IntenseStyle, Appearance().IntenseTextStyle);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowProportionalFontWarning, _PropertyChangedHandlers, nullptr);
|
||||
|
||||
private:
|
||||
bool _ShowAllFonts;
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
|
||||
Boolean UsingMonospaceFont { get; };
|
||||
Boolean ShowAllFonts;
|
||||
Boolean ShowProportionalFontWarning;
|
||||
|
||||
IInspectable CurrentCursorShape;
|
||||
Boolean IsVintageCursor { get; };
|
||||
|
||||
@@ -179,11 +179,13 @@
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Face -->
|
||||
|
||||
<local:SettingContainer x:Uid="Profile_FontFace"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearFontFace}"
|
||||
HasSettingValue="{x:Bind Appearance.HasFontFace, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.FontFaceOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.IsDefault, Mode=OneWay}">
|
||||
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<!--
|
||||
Binding the ItemsSource to a separate variable that switches between the
|
||||
@@ -210,6 +212,10 @@
|
||||
IsEnabled="{x:Bind UsingMonospaceFont, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
<muxc:InfoBar x:Uid="Profile_FontFace_ProportionalFontWarning"
|
||||
IsOpen="{x:Bind ShowProportionalFontWarning, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
|
||||
|
||||
<!-- Font Size -->
|
||||
<local:SettingContainer x:Uid="Profile_FontSize"
|
||||
|
||||
@@ -1608,5 +1608,13 @@
|
||||
<data name="Settings_PortableModeInfoLinkTextRun.Text" xml:space="preserve">
|
||||
<value>Learn more.</value>
|
||||
<comment>A hyperlink displayed near Settings_PortableModeNote.Text that the user can follow for more information.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFace_ProportionalFontWarning.Title" xml:space="preserve">
|
||||
<value>Warning:</value>
|
||||
<comment>Title for the warning info bar used when a non monospace font face is chosen to indicate that there may be visual artifacts</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFace_ProportionalFontWarning.Message" xml:space="preserve">
|
||||
<value>Choosing a non-monospaced font will likely result in visual artifacts. Use at your own discretion.</value>
|
||||
<comment>Warning info bar used when a non monospace font face is chosen to indicate that there may be visual artifacts</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -83,6 +83,8 @@ static constexpr std::string_view QuitKey{ "quit" };
|
||||
static constexpr std::string_view AdjustOpacityKey{ "adjustOpacity" };
|
||||
static constexpr std::string_view RestoreLastClosedKey{ "restoreLastClosed" };
|
||||
static constexpr std::string_view SelectAllKey{ "selectAll" };
|
||||
static constexpr std::string_view SelectCommandKey{ "selectCommand" };
|
||||
static constexpr std::string_view SelectOutputKey{ "selectOutput" };
|
||||
static constexpr std::string_view MarkModeKey{ "markMode" };
|
||||
static constexpr std::string_view ToggleBlockSelectionKey{ "toggleBlockSelection" };
|
||||
static constexpr std::string_view SwitchSelectionEndpointKey{ "switchSelectionEndpoint" };
|
||||
@@ -329,22 +331,24 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
winrt::hstring ActionAndArgs::GenerateName() const
|
||||
{
|
||||
// Sentinel used to indicate this command must ALWAYS be generated by GenerateName
|
||||
static const winrt::hstring MustGenerate{ L"" };
|
||||
// Use a magic static to initialize this map, because we won't be able
|
||||
// to load the resources at _init_, only at runtime.
|
||||
static const auto GeneratedActionNames = []() {
|
||||
return std::unordered_map<ShortcutAction, winrt::hstring>{
|
||||
{ ShortcutAction::AdjustFontSize, RS_(L"AdjustFontSizeCommandKey") },
|
||||
{ ShortcutAction::CloseOtherPanes, RS_(L"CloseOtherPanesCommandKey") },
|
||||
{ ShortcutAction::CloseOtherTabs, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::CloseOtherTabs, MustGenerate },
|
||||
{ ShortcutAction::ClosePane, RS_(L"ClosePaneCommandKey") },
|
||||
{ ShortcutAction::CloseTab, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::CloseTabsAfter, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::CloseTab, MustGenerate },
|
||||
{ ShortcutAction::CloseTabsAfter, MustGenerate },
|
||||
{ ShortcutAction::CloseWindow, RS_(L"CloseWindowCommandKey") },
|
||||
{ ShortcutAction::CopyText, RS_(L"CopyTextCommandKey") },
|
||||
{ ShortcutAction::DuplicateTab, RS_(L"DuplicateTabCommandKey") },
|
||||
{ ShortcutAction::ExecuteCommandline, RS_(L"ExecuteCommandlineCommandKey") },
|
||||
{ ShortcutAction::Find, RS_(L"FindCommandKey") },
|
||||
{ ShortcutAction::Invalid, L"" },
|
||||
{ ShortcutAction::Invalid, MustGenerate },
|
||||
{ ShortcutAction::MoveFocus, RS_(L"MoveFocusCommandKey") },
|
||||
{ ShortcutAction::MovePane, RS_(L"MovePaneCommandKey") },
|
||||
{ ShortcutAction::SwapPane, RS_(L"SwapPaneCommandKey") },
|
||||
@@ -369,25 +373,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::AddMark, RS_(L"AddMarkCommandKey") },
|
||||
{ ShortcutAction::ClearMark, RS_(L"ClearMarkCommandKey") },
|
||||
{ ShortcutAction::ClearAllMarks, RS_(L"ClearAllMarksCommandKey") },
|
||||
{ ShortcutAction::SendInput, L"" },
|
||||
{ ShortcutAction::SetColorScheme, L"" },
|
||||
{ ShortcutAction::SendInput, MustGenerate },
|
||||
{ ShortcutAction::SetColorScheme, MustGenerate },
|
||||
{ ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") },
|
||||
{ ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") },
|
||||
{ ShortcutAction::SwitchToTab, RS_(L"SwitchToTabCommandKey") },
|
||||
{ ShortcutAction::TabSearch, RS_(L"TabSearchCommandKey") },
|
||||
{ ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") },
|
||||
{ ShortcutAction::ToggleCommandPalette, L"" },
|
||||
{ ShortcutAction::ToggleCommandPalette, MustGenerate },
|
||||
{ ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") },
|
||||
{ ShortcutAction::SetFocusMode, L"" },
|
||||
{ ShortcutAction::SetFocusMode, MustGenerate },
|
||||
{ ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") },
|
||||
{ ShortcutAction::SetFullScreen, L"" },
|
||||
{ ShortcutAction::SetMaximized, L"" },
|
||||
{ ShortcutAction::SetFullScreen, MustGenerate },
|
||||
{ ShortcutAction::SetMaximized, MustGenerate },
|
||||
{ ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") },
|
||||
{ ShortcutAction::ToggleSplitOrientation, RS_(L"ToggleSplitOrientationCommandKey") },
|
||||
{ ShortcutAction::ToggleShaderEffects, RS_(L"ToggleShaderEffectsCommandKey") },
|
||||
{ ShortcutAction::MoveTab, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::MoveTab, MustGenerate },
|
||||
{ ShortcutAction::BreakIntoDebugger, RS_(L"BreakIntoDebuggerCommandKey") },
|
||||
{ ShortcutAction::FindMatch, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::FindMatch, MustGenerate },
|
||||
{ ShortcutAction::TogglePaneReadOnly, RS_(L"TogglePaneReadOnlyCommandKey") },
|
||||
{ ShortcutAction::EnablePaneReadOnly, RS_(L"EnablePaneReadOnlyCommandKey") },
|
||||
{ ShortcutAction::DisablePaneReadOnly, RS_(L"DisablePaneReadOnlyCommandKey") },
|
||||
@@ -396,21 +400,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::IdentifyWindows, RS_(L"IdentifyWindowsCommandKey") },
|
||||
{ ShortcutAction::RenameWindow, RS_(L"ResetWindowNameCommandKey") },
|
||||
{ ShortcutAction::OpenWindowRenamer, RS_(L"OpenWindowRenamerCommandKey") },
|
||||
{ ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::GlobalSummon, MustGenerate },
|
||||
{ ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") },
|
||||
{ ShortcutAction::FocusPane, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::FocusPane, MustGenerate },
|
||||
{ ShortcutAction::OpenSystemMenu, RS_(L"OpenSystemMenuCommandKey") },
|
||||
{ ShortcutAction::ExportBuffer, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::ClearBuffer, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::MultipleActions, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::ExportBuffer, MustGenerate },
|
||||
{ ShortcutAction::ClearBuffer, MustGenerate },
|
||||
{ ShortcutAction::MultipleActions, MustGenerate },
|
||||
{ ShortcutAction::Quit, RS_(L"QuitCommandKey") },
|
||||
{ ShortcutAction::AdjustOpacity, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::AdjustOpacity, MustGenerate },
|
||||
{ ShortcutAction::RestoreLastClosed, RS_(L"RestoreLastClosedCommandKey") },
|
||||
{ ShortcutAction::SelectCommand, MustGenerate },
|
||||
{ ShortcutAction::SelectOutput, MustGenerate },
|
||||
{ ShortcutAction::SelectAll, RS_(L"SelectAllCommandKey") },
|
||||
{ ShortcutAction::MarkMode, RS_(L"MarkModeCommandKey") },
|
||||
{ ShortcutAction::ToggleBlockSelection, RS_(L"ToggleBlockSelectionCommandKey") },
|
||||
{ ShortcutAction::SwitchSelectionEndpoint, RS_(L"SwitchSelectionEndpointCommandKey") },
|
||||
{ ShortcutAction::ColorSelection, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::ColorSelection, MustGenerate },
|
||||
{ ShortcutAction::ExpandSelectionToWord, RS_(L"ExpandSelectionToWordCommandKey") },
|
||||
};
|
||||
}();
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "ClearBufferArgs.g.cpp"
|
||||
#include "MultipleActionsArgs.g.cpp"
|
||||
#include "AdjustOpacityArgs.g.cpp"
|
||||
#include "SelectCommandArgs.g.cpp"
|
||||
#include "SelectOutputArgs.g.cpp"
|
||||
#include "ColorSelectionArgs.g.cpp"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
@@ -970,4 +972,27 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring SelectOutputArgs::GenerateName() const
|
||||
{
|
||||
switch (Direction())
|
||||
{
|
||||
case SelectOutputDirection::Next:
|
||||
return RS_(L"SelectOutputNextCommandKey");
|
||||
case SelectOutputDirection::Previous:
|
||||
return RS_(L"SelectOutputPreviousCommandKey");
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
winrt::hstring SelectCommandArgs::GenerateName() const
|
||||
{
|
||||
switch (Direction())
|
||||
{
|
||||
case SelectOutputDirection::Next:
|
||||
return RS_(L"SelectCommandNextCommandKey");
|
||||
case SelectOutputDirection::Previous:
|
||||
return RS_(L"SelectCommandPreviousCommandKey");
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include "ClearBufferArgs.g.h"
|
||||
#include "MultipleActionsArgs.g.h"
|
||||
#include "AdjustOpacityArgs.g.h"
|
||||
#include "SelectCommandArgs.g.h"
|
||||
#include "SelectOutputArgs.g.h"
|
||||
#include "ColorSelectionArgs.g.h"
|
||||
|
||||
#include "JsonUtils.h"
|
||||
@@ -250,6 +252,14 @@ private: \
|
||||
X(int32_t, Opacity, "opacity", false, 0) \
|
||||
X(bool, Relative, "relative", false, true)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define SELECT_COMMAND_ARGS(X) \
|
||||
X(SelectOutputDirection, Direction, "direction", false, SelectOutputDirection::Previous)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define SELECT_OUTPUT_ARGS(X) \
|
||||
X(SelectOutputDirection, Direction, "direction", false, SelectOutputDirection::Previous)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define COLOR_SELECTION_ARGS(X) \
|
||||
X(winrt::Microsoft::Terminal::Control::SelectionColor, Foreground, "foreground", false, nullptr) \
|
||||
@@ -778,6 +788,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
ACTION_ARGS_STRUCT(AdjustOpacityArgs, ADJUST_OPACITY_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(SelectCommandArgs, SELECT_COMMAND_ARGS);
|
||||
ACTION_ARGS_STRUCT(SelectOutputArgs, SELECT_OUTPUT_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(ColorSelectionArgs, COLOR_SELECTION_ARGS);
|
||||
|
||||
}
|
||||
@@ -814,4 +827,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
BASIC_FACTORY(ClearBufferArgs);
|
||||
BASIC_FACTORY(MultipleActionsArgs);
|
||||
BASIC_FACTORY(AdjustOpacityArgs);
|
||||
BASIC_FACTORY(SelectCommandArgs);
|
||||
BASIC_FACTORY(SelectOutputArgs);
|
||||
}
|
||||
|
||||
@@ -80,6 +80,12 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Previous
|
||||
};
|
||||
|
||||
enum SelectOutputDirection
|
||||
{
|
||||
Previous = 0,
|
||||
Next,
|
||||
};
|
||||
|
||||
enum CommandPaletteLaunchMode
|
||||
{
|
||||
Action = 0,
|
||||
@@ -388,4 +394,17 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Microsoft.Terminal.Control.SelectionColor Background;
|
||||
Microsoft.Terminal.Core.MatchMode MatchMode { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SelectCommandArgs : IActionArgs
|
||||
{
|
||||
SelectCommandArgs(SelectOutputDirection direction);
|
||||
SelectOutputDirection Direction { get; };
|
||||
}
|
||||
[default_interface] runtimeclass SelectOutputArgs : IActionArgs
|
||||
{
|
||||
SelectOutputArgs(SelectOutputDirection direction);
|
||||
SelectOutputDirection Direction { get; };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@
|
||||
ON_ALL_ACTIONS(AdjustOpacity) \
|
||||
ON_ALL_ACTIONS(RestoreLastClosed) \
|
||||
ON_ALL_ACTIONS(SelectAll) \
|
||||
ON_ALL_ACTIONS(SelectCommand) \
|
||||
ON_ALL_ACTIONS(SelectOutput) \
|
||||
ON_ALL_ACTIONS(MarkMode) \
|
||||
ON_ALL_ACTIONS(ToggleBlockSelection) \
|
||||
ON_ALL_ACTIONS(SwitchSelectionEndpoint) \
|
||||
@@ -142,4 +144,6 @@
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ClearBuffer) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(MultipleActions) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(AdjustOpacity) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SelectCommand) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SelectOutput) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ColorSelection)
|
||||
|
||||
@@ -675,4 +675,16 @@
|
||||
<data name="CloseOtherPanesCommandKey" xml:space="preserve">
|
||||
<value>Close all other panes</value>
|
||||
</data>
|
||||
<data name="SelectOutputNextCommandKey" xml:space="preserve">
|
||||
<value>Select next command output</value>
|
||||
</data>
|
||||
<data name="SelectOutputPreviousCommandKey" xml:space="preserve">
|
||||
<value>Select previous command output</value>
|
||||
</data>
|
||||
<data name="SelectCommandNextCommandKey" xml:space="preserve">
|
||||
<value>Select next command</value>
|
||||
</data>
|
||||
<data name="SelectCommandPreviousCommandKey" xml:space="preserve">
|
||||
<value>Select previous command</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -672,6 +672,14 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FolderEntryInlin
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::SelectOutputDirection)
|
||||
{
|
||||
JSON_MAPPINGS(2) = {
|
||||
pair_type{ "prev", ValueType::Previous },
|
||||
pair_type{ "next", ValueType::Next },
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<::winrt::Microsoft::Terminal::Control::SelectionColor>
|
||||
{
|
||||
|
||||
@@ -38,6 +38,9 @@ namespace ControlUnitTests
|
||||
TEST_METHOD(TestClearAll);
|
||||
TEST_METHOD(TestReadEntireBuffer);
|
||||
|
||||
TEST_METHOD(TestSelectCommandSimple);
|
||||
TEST_METHOD(TestSelectOutputSimple);
|
||||
|
||||
TEST_CLASS_SETUP(ModuleSetup)
|
||||
{
|
||||
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
||||
@@ -358,5 +361,142 @@ namespace ControlUnitTests
|
||||
VERIFY_ARE_EQUAL(L"This is some text\r\nwith varying amounts\r\nof whitespace\r\n",
|
||||
core->ReadEntireBuffer());
|
||||
}
|
||||
void _writePrompt(const winrt::com_ptr<MockConnection>& conn, const auto& path)
|
||||
{
|
||||
conn->WriteInput(L"\x1b]133;D\x7");
|
||||
conn->WriteInput(L"\x1b]133;A\x7");
|
||||
conn->WriteInput(L"\x1b]9;9;");
|
||||
conn->WriteInput(path);
|
||||
conn->WriteInput(L"\x7");
|
||||
conn->WriteInput(L"PWSH ");
|
||||
conn->WriteInput(path);
|
||||
conn->WriteInput(L"> ");
|
||||
conn->WriteInput(L"\x1b]133;B\x7");
|
||||
}
|
||||
|
||||
void ControlCoreTests::TestSelectCommandSimple()
|
||||
{
|
||||
auto [settings, conn] = _createSettingsAndConnection();
|
||||
Log::Comment(L"Create ControlCore object");
|
||||
auto core = createCore(*settings, *conn);
|
||||
VERIFY_IS_NOT_NULL(core);
|
||||
_standardInit(core);
|
||||
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
conn->WriteInput(L"Foo-bar");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n");
|
||||
conn->WriteInput(L"with varying amounts \r\n");
|
||||
conn->WriteInput(L"of whitespace \r\n");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
|
||||
Log::Comment(L"Check the buffer contents");
|
||||
const auto& buffer = core->_terminal->GetTextBuffer();
|
||||
const auto& cursor = buffer.GetCursor();
|
||||
|
||||
{
|
||||
const til::point expectedCursor{ 17, 4 };
|
||||
VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
|
||||
}
|
||||
|
||||
VERIFY_IS_FALSE(core->HasSelection());
|
||||
core->SelectCommand(true);
|
||||
VERIFY_IS_TRUE(core->HasSelection());
|
||||
{
|
||||
const auto& start = core->_terminal->GetSelectionAnchor();
|
||||
const auto& end = core->_terminal->GetSelectionEnd();
|
||||
const til::point expectedStart{ 17, 0 };
|
||||
const til::point expectedEnd{ 23, 0 };
|
||||
VERIFY_ARE_EQUAL(expectedStart, start);
|
||||
VERIFY_ARE_EQUAL(expectedEnd, end);
|
||||
}
|
||||
|
||||
core->_terminal->ClearSelection();
|
||||
conn->WriteInput(L"Boo-far");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
|
||||
VERIFY_IS_FALSE(core->HasSelection());
|
||||
{
|
||||
const til::point expectedCursor{ 24, 4 };
|
||||
VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
|
||||
}
|
||||
VERIFY_IS_FALSE(core->HasSelection());
|
||||
core->SelectCommand(true);
|
||||
VERIFY_IS_TRUE(core->HasSelection());
|
||||
{
|
||||
const auto& start = core->_terminal->GetSelectionAnchor();
|
||||
const auto& end = core->_terminal->GetSelectionEnd();
|
||||
const til::point expectedStart{ 17, 4 };
|
||||
const til::point expectedEnd{ 23, 4 };
|
||||
VERIFY_ARE_EQUAL(expectedStart, start);
|
||||
VERIFY_ARE_EQUAL(expectedEnd, end);
|
||||
}
|
||||
core->SelectCommand(true);
|
||||
VERIFY_IS_TRUE(core->HasSelection());
|
||||
{
|
||||
const auto& start = core->_terminal->GetSelectionAnchor();
|
||||
const auto& end = core->_terminal->GetSelectionEnd();
|
||||
const til::point expectedStart{ 17, 0 };
|
||||
const til::point expectedEnd{ 23, 0 };
|
||||
VERIFY_ARE_EQUAL(expectedStart, start);
|
||||
VERIFY_ARE_EQUAL(expectedEnd, end);
|
||||
}
|
||||
core->SelectCommand(false);
|
||||
VERIFY_IS_TRUE(core->HasSelection());
|
||||
{
|
||||
const auto& start = core->_terminal->GetSelectionAnchor();
|
||||
const auto& end = core->_terminal->GetSelectionEnd();
|
||||
const til::point expectedStart{ 17, 4 };
|
||||
const til::point expectedEnd{ 23, 4 };
|
||||
VERIFY_ARE_EQUAL(expectedStart, start);
|
||||
VERIFY_ARE_EQUAL(expectedEnd, end);
|
||||
}
|
||||
}
|
||||
void ControlCoreTests::TestSelectOutputSimple()
|
||||
{
|
||||
auto [settings, conn] = _createSettingsAndConnection();
|
||||
Log::Comment(L"Create ControlCore object");
|
||||
auto core = createCore(*settings, *conn);
|
||||
VERIFY_IS_NOT_NULL(core);
|
||||
_standardInit(core);
|
||||
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
conn->WriteInput(L"Foo-bar");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n");
|
||||
conn->WriteInput(L"with varying amounts \r\n");
|
||||
conn->WriteInput(L"of whitespace \r\n");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
|
||||
Log::Comment(L"Check the buffer contents");
|
||||
const auto& buffer = core->_terminal->GetTextBuffer();
|
||||
const auto& cursor = buffer.GetCursor();
|
||||
|
||||
{
|
||||
const til::point expectedCursor{ 17, 4 };
|
||||
VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
|
||||
}
|
||||
|
||||
VERIFY_IS_FALSE(core->HasSelection());
|
||||
core->SelectOutput(true);
|
||||
VERIFY_IS_TRUE(core->HasSelection());
|
||||
{
|
||||
const auto& start = core->_terminal->GetSelectionAnchor();
|
||||
const auto& end = core->_terminal->GetSelectionEnd();
|
||||
const til::point expectedStart{ 24, 0 }; // The character after the prompt
|
||||
const til::point expectedEnd{ 29, 3 }; // x = buffer.right
|
||||
VERIFY_ARE_EQUAL(expectedStart, start);
|
||||
VERIFY_ARE_EQUAL(expectedEnd, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,11 +32,11 @@ AppHost::AppHost(const winrt::TerminalApp::AppLogic& logic,
|
||||
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args,
|
||||
const Remoting::WindowManager& manager,
|
||||
const Remoting::Peasant& peasant) noexcept :
|
||||
_appLogic{ logic },
|
||||
_windowLogic{ nullptr }, // don't make one, we're going to take a ref on app's
|
||||
_windowManager{ manager },
|
||||
_peasant{ peasant },
|
||||
_appLogic{ logic }, // don't make one, we're going to take a ref on app's
|
||||
_windowLogic{ nullptr },
|
||||
_window{ nullptr }
|
||||
_desktopManager{ winrt::try_create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager)) }
|
||||
{
|
||||
_HandleCommandlineArgs(args);
|
||||
|
||||
@@ -851,30 +851,39 @@ void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable send
|
||||
_windowLogic.ExecuteCommandline(args.Commandline(), args.CurrentDirectory());
|
||||
}
|
||||
|
||||
winrt::fire_and_forget AppHost::_WindowActivated(bool activated)
|
||||
void AppHost::_WindowActivated(bool activated)
|
||||
{
|
||||
_windowLogic.WindowActivated(activated);
|
||||
|
||||
if (!activated)
|
||||
if (activated && _isWindowInitialized)
|
||||
{
|
||||
_peasantNotifyActivateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
winrt::fire_and_forget AppHost::_peasantNotifyActivateWindow()
|
||||
{
|
||||
const auto desktopManager = _desktopManager;
|
||||
const auto peasant = _peasant;
|
||||
const auto hwnd = _window->GetHandle();
|
||||
|
||||
co_await winrt::resume_background();
|
||||
|
||||
GUID currentDesktopGuid{};
|
||||
if (FAILED_LOG(desktopManager->GetWindowDesktopId(hwnd, ¤tDesktopGuid)))
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
co_await winrt::resume_background();
|
||||
|
||||
if (_peasant)
|
||||
{
|
||||
const auto currentDesktopGuid{ _CurrentDesktopGuid() };
|
||||
|
||||
// TODO: projects/5 - in the future, we'll want to actually get the
|
||||
// desktop GUID in IslandWindow, and bubble that up here, then down to
|
||||
// the Peasant. For now, we're just leaving space for it.
|
||||
Remoting::WindowActivatedArgs args{ _peasant.GetID(),
|
||||
(uint64_t)_window->GetHandle(),
|
||||
currentDesktopGuid,
|
||||
winrt::clock().now() };
|
||||
_peasant.ActivateWindow(args);
|
||||
}
|
||||
// TODO: projects/5 - in the future, we'll want to actually get the
|
||||
// desktop GUID in IslandWindow, and bubble that up here, then down to
|
||||
// the Peasant. For now, we're just leaving space for it.
|
||||
peasant.ActivateWindow({
|
||||
peasant.GetID(),
|
||||
reinterpret_cast<uint64_t>(hwnd),
|
||||
currentDesktopGuid,
|
||||
winrt::clock().now(),
|
||||
});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -907,30 +916,6 @@ winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> AppHost::_GetWindowL
|
||||
co_return layoutJson;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper to initialize our instance of IVirtualDesktopManager. If we already
|
||||
// got one, then this will just return true. Otherwise, we'll try and init a
|
||||
// new instance of one, and store that.
|
||||
// - This will return false if we weren't able to initialize one, which I'm not
|
||||
// sure is actually possible.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - true iff _desktopManager points to a non-null instance of IVirtualDesktopManager
|
||||
bool AppHost::_LazyLoadDesktopManager()
|
||||
{
|
||||
if (_desktopManager == nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
_desktopManager = winrt::create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager));
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
return _desktopManager != nullptr;
|
||||
}
|
||||
|
||||
void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const Remoting::SummonWindowBehavior& args)
|
||||
{
|
||||
@@ -938,7 +923,7 @@ void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*se
|
||||
|
||||
if (args != nullptr && args.MoveToCurrentDesktop())
|
||||
{
|
||||
if (_LazyLoadDesktopManager())
|
||||
if (_desktopManager)
|
||||
{
|
||||
// First thing - make sure that we're not on the current desktop. If
|
||||
// we are, then don't call MoveWindowToDesktop. This is to mitigate
|
||||
@@ -966,23 +951,6 @@ void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*se
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This gets the GUID of the desktop our window is currently on. It does NOT
|
||||
// get the GUID of the desktop that's currently active.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the GUID of the desktop our window is currently on
|
||||
GUID AppHost::_CurrentDesktopGuid()
|
||||
{
|
||||
GUID currentDesktopGuid{ 0 };
|
||||
if (_LazyLoadDesktopManager())
|
||||
{
|
||||
LOG_IF_FAILED(_desktopManager->GetWindowDesktopId(_window->GetHandle(), ¤tDesktopGuid));
|
||||
}
|
||||
return currentDesktopGuid;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when this window wants _all_ windows to display their
|
||||
// identification. We'll hop to the BG thread, and raise an event (eventually
|
||||
@@ -1264,8 +1232,9 @@ winrt::fire_and_forget AppHost::_WindowInitializedHandler(const winrt::Windows::
|
||||
// UI thread. This is shockingly load bearing - without this, then
|
||||
// sometimes, we'll _still_ show the HWND before the XAML island actually
|
||||
// paints.
|
||||
co_await winrt::resume_background();
|
||||
co_await wil::resume_foreground(_windowLogic.GetRoot().Dispatcher(), winrt::Windows::UI::Core::CoreDispatcherPriority::Low);
|
||||
|
||||
_isWindowInitialized = true;
|
||||
ShowWindow(_window->GetHandle(), nCmdShow);
|
||||
|
||||
// If we didn't start the window hidden (in one way or another), then try to
|
||||
@@ -1280,6 +1249,7 @@ winrt::fire_and_forget AppHost::_WindowInitializedHandler(const winrt::Windows::
|
||||
if (!noForeground)
|
||||
{
|
||||
SetForegroundWindow(_window->GetHandle());
|
||||
_peasantNotifyActivateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args,
|
||||
const winrt::Microsoft::Terminal::Remoting::WindowManager& manager,
|
||||
const winrt::Microsoft::Terminal::Remoting::Peasant& peasant) noexcept;
|
||||
virtual ~AppHost();
|
||||
~AppHost();
|
||||
|
||||
void AppTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, winrt::hstring newTitle);
|
||||
void LastTabClosed(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::LastTabClosedEventArgs& args);
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
winrt::Microsoft::Terminal::Remoting::Peasant _peasant{ nullptr };
|
||||
|
||||
winrt::com_ptr<IVirtualDesktopManager> _desktopManager{ nullptr };
|
||||
|
||||
bool _isWindowInitialized = false;
|
||||
bool _useNonClientArea{ false };
|
||||
winrt::Microsoft::Terminal::Settings::Model::LaunchMode _launchMode{};
|
||||
|
||||
@@ -70,7 +70,8 @@ private:
|
||||
void _RaiseVisualBell(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& arg);
|
||||
void _WindowMouseWheeled(const til::point coord, const int32_t delta);
|
||||
winrt::fire_and_forget _WindowActivated(bool activated);
|
||||
void _WindowActivated(bool activated);
|
||||
winrt::fire_and_forget _peasantNotifyActivateWindow();
|
||||
void _WindowMoved();
|
||||
|
||||
void _DispatchCommandline(winrt::Windows::Foundation::IInspectable sender,
|
||||
|
||||
@@ -580,5 +580,14 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes
|
||||
MarkCategory category{ MarkCategory::Info };
|
||||
// Other things we may want to think about in the future are listed in
|
||||
// GH#11000
|
||||
|
||||
bool HasCommand() const noexcept
|
||||
{
|
||||
return commandEnd.has_value() && *commandEnd != end;
|
||||
}
|
||||
bool HasOutput() const noexcept
|
||||
{
|
||||
return outputEnd.has_value() && *outputEnd != *commandEnd;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3173,6 +3173,18 @@ bool AdaptDispatch::DoConEmuAction(const std::wstring_view string)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 12: "Let ConEmu treat current cursor position as prompt start"
|
||||
//
|
||||
// Based on the official conemu docs:
|
||||
// * https://conemu.github.io/en/ShellWorkDir.html#connector-ps1
|
||||
// * https://conemu.github.io/en/ShellWorkDir.html#PowerShell
|
||||
//
|
||||
// This seems like basically the same as 133;B - the end of the prompt, the start of the commandline.
|
||||
else if (subParam == 12)
|
||||
{
|
||||
_api.MarkCommandStart();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user