mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-15 02:31:03 +00:00
Compare commits
1 Commits
v1.24.2372
...
msbuildcac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c77ac66c33 |
@@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"XamlStyler.Console": {
|
||||
"version": "3.2501.8",
|
||||
"version": "3.2311.2",
|
||||
"commands": [
|
||||
"xstyler"
|
||||
]
|
||||
|
||||
1
.github/actions/spelling/allow/apis.txt
vendored
1
.github/actions/spelling/allow/apis.txt
vendored
@@ -174,7 +174,6 @@ tokeninfo
|
||||
tolower
|
||||
toupper
|
||||
TRACKMOUSEEVENT
|
||||
ubrk
|
||||
UChar
|
||||
UFIELD
|
||||
ULARGE
|
||||
|
||||
1
.github/actions/spelling/allow/microsoft.txt
vendored
1
.github/actions/spelling/allow/microsoft.txt
vendored
@@ -34,7 +34,6 @@ issecret
|
||||
libucrt
|
||||
libucrtd
|
||||
LOCKFILE
|
||||
LTCG
|
||||
Lxss
|
||||
makepri
|
||||
microsoft
|
||||
|
||||
1
.github/actions/spelling/allow/names.txt
vendored
1
.github/actions/spelling/allow/names.txt
vendored
@@ -28,7 +28,6 @@ jerrysh
|
||||
Kaiyu
|
||||
leonardder
|
||||
lhecker
|
||||
Lovecraft
|
||||
masserano
|
||||
menger
|
||||
migrie
|
||||
|
||||
6
.github/actions/spelling/expect/expect.txt
vendored
6
.github/actions/spelling/expect/expect.txt
vendored
@@ -115,6 +115,7 @@ BKCOLOR
|
||||
BKGND
|
||||
BKMK
|
||||
Bksp
|
||||
blds
|
||||
Blt
|
||||
blu
|
||||
BLUESCROLL
|
||||
@@ -180,6 +181,7 @@ CLIPCHILDREN
|
||||
CLIPSIBLINGS
|
||||
closetest
|
||||
cloudconsole
|
||||
CLOUDT
|
||||
cloudvault
|
||||
CLSCTX
|
||||
clsids
|
||||
@@ -822,7 +824,6 @@ INPUTSCOPE
|
||||
INSERTMODE
|
||||
INTERACTIVITYBASE
|
||||
INTERCEPTCOPYPASTE
|
||||
internalevent
|
||||
INTERNALNAME
|
||||
intsafe
|
||||
INVALIDARG
|
||||
@@ -961,7 +962,6 @@ lstatus
|
||||
lstrcmp
|
||||
lstrcmpi
|
||||
LTEXT
|
||||
lto
|
||||
ltsc
|
||||
LUID
|
||||
luma
|
||||
@@ -1710,7 +1710,6 @@ titlebars
|
||||
TITLEISLINKNAME
|
||||
TLDP
|
||||
TLEN
|
||||
Tlgg
|
||||
TMAE
|
||||
TMPF
|
||||
tmultiple
|
||||
@@ -1973,7 +1972,6 @@ WRITECONSOLEOUTPUT
|
||||
WRITECONSOLEOUTPUTSTRING
|
||||
wrkstr
|
||||
WRL
|
||||
wrl
|
||||
wrp
|
||||
WRunoff
|
||||
WSLENV
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"Microsoft.VisualStudio.Component.AppInsights.Tools",
|
||||
"Microsoft.Net.Component.4.8.TargetingPack",
|
||||
"Microsoft.VisualStudio.Component.DiagnosticTools",
|
||||
"Microsoft.NetCore.Component.Runtime.6.0",
|
||||
"Microsoft.VisualStudio.Component.ClassDesigner",
|
||||
"Microsoft.VisualStudio.Component.GraphDocument",
|
||||
"Microsoft.VisualStudio.Component.CodeMap",
|
||||
|
||||
@@ -33,6 +33,17 @@
|
||||
A:\;
|
||||
E:\;
|
||||
$(windir)\**;
|
||||
$(MSBuildBinPath)\**;
|
||||
$(MSBuildToolsPath32)\**;
|
||||
</MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
|
||||
|
||||
<!--
|
||||
Unit tests may write to TEMP, but should not be considered outputs. However, $(Temp) is using the DOS path (C:\Users\CLOUDT~1\AppData\Local\Temp), which
|
||||
isn't accounted for in these globs. So we're building up to TEMP using $(LOCALAPPDATA) instead.
|
||||
-->
|
||||
<MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
|
||||
$(MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns);
|
||||
$(LOCALAPPDATA)\Temp\**;
|
||||
</MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
|
||||
|
||||
<!--
|
||||
@@ -46,6 +57,15 @@
|
||||
-->
|
||||
<MSBuildCacheIdenticalDuplicateOutputPatterns>$(MSBuildCacheIdenticalDuplicateOutputPatterns);obj\*\vcpkg\**</MSBuildCacheIdenticalDuplicateOutputPatterns>
|
||||
|
||||
<!--
|
||||
Ensure the MSBuildCache ignores collecting outputs under vcpkg's build tree, which is a working directory used to build vcpkg packages and not intended to be consumed by anything else in the build.
|
||||
Note: We cannot use $(VcpkgInstalledDir) directly since it differs between projects, so use a pattern which encompasses all possibilities.
|
||||
-->
|
||||
<MSBuildCacheIgnoredOutputPatterns>
|
||||
$(MSBuildCacheIgnoredOutputPatterns);
|
||||
$(SolutionDir)\obj\*\vcpkg*\vcpkg\blds\**;
|
||||
</MSBuildCacheIgnoredOutputPatterns>
|
||||
|
||||
<!-- version of MSBuildCache is not part of the cache key -->
|
||||
<PackagesConfigFile>$(MSBuildThisFileDirectory)\dep\nuget\packages.config</PackagesConfigFile>
|
||||
<MSBuildCacheIgnoredInputPatterns>$(MSBuildCacheIgnoredInputPatterns);$(PackagesConfigFile)</MSBuildCacheIgnoredInputPatterns>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<clear />
|
||||
<!-- Dependencies that we can turn on to force override for testing purposes before uploading. -->
|
||||
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
|
||||
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies%40Local/nuget/v3/index.json" />
|
||||
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies/nuget/v3/index.json" />
|
||||
</packageSources>
|
||||
<disabledPackageSources>
|
||||
<clear />
|
||||
|
||||
@@ -56,9 +56,9 @@ This is an open source project and we welcome community participation. To partic
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Version __VERSION_NUMBER__
|
||||
|
||||
- A whole new Extensions page that shows what has been installed into your Terminal
|
||||
- Command Palette now shows up in your native language as well as English
|
||||
- New VT features such as synchronized rendering, new color schemes, configuration for quick mouse actions like zooming, and more
|
||||
- We've added dozens of settings to the UI that once only existed in the JSON file, including a new page for customizing the layout of your New Tab menu!
|
||||
- We have rearchitected window management to improve reliability; please file any bugs you encounter with the wt.exe alias
|
||||
- Profiles now show an icon if they've been hidden or refer to programs which were uninstalled.
|
||||
|
||||
Please see our GitHub releases page for additional details.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -54,11 +54,14 @@ This is an open source project and we welcome community participation. To partic
|
||||
<!-- _locComment_text="{MaxLength=255} App DevStudio" -->
|
||||
</DevStudio>
|
||||
<ReleaseNotes _locID="App_ReleaseNotes">
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__}{Locked=wt.exe} App Release Note" -->Version __VERSION_NUMBER__
|
||||
<!-- _locComment_text="{MaxLength=1500} {Locked=__VERSION_NUMBER__} App Release Note" -->Version __VERSION_NUMBER__
|
||||
|
||||
- We've added dozens of settings to the UI that once only existed in the JSON file, including a new page for customizing the layout of your New Tab menu!
|
||||
- We have rearchitected window management to improve reliability; please file any bugs you encounter with the wt.exe alias
|
||||
- Profiles now show an icon if they've been hidden or refer to programs which were uninstalled.
|
||||
- We've rewritten how console applications are hosted inside Terminal! Please report any bugs you encounter.
|
||||
- Terminal now supports Sixels!
|
||||
- You can now open a docked panel containing snippets of commands you have saved to use later
|
||||
- Command Prompt users on the latest Windows 11 release may see a "quick tip" icon that suggests installable software from WinGet
|
||||
- Selected text will now be much more visible (and customizable!)
|
||||
- A number of reliabilty bugs, convenience issues and annoyances have been fixed.
|
||||
|
||||
Please see our GitHub releases page for additional details.
|
||||
</ReleaseNotes>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"MatchedPath": [
|
||||
"WpfTerminalControl/net472/Microsoft.Terminal.Wpf.dll",
|
||||
"WpfTerminalControl/net8.0-windows/Microsoft.Terminal.Wpf.dll"
|
||||
"WpfTerminalControl/net6.0-windows/Microsoft.Terminal.Wpf.dll"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
|
||||
@@ -14,21 +14,21 @@
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2306.22001.0"
|
||||
Version="8.2305.5001.0"
|
||||
ProcessorArchitecture="x64"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.5/Microsoft.UI.Xaml.2.8.x64.appx" />
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x64.appx" />
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2306.22001.0"
|
||||
Version="8.2305.5001.0"
|
||||
ProcessorArchitecture="x86"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.5/Microsoft.UI.Xaml.2.8.x86.appx" />
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x86.appx" />
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2306.22001.0"
|
||||
Version="8.2305.5001.0"
|
||||
ProcessorArchitecture="arm64"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.5/Microsoft.UI.Xaml.2.8.arm64.appx" />
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.arm64.appx" />
|
||||
</Dependencies>
|
||||
|
||||
<UpdateSettings>
|
||||
|
||||
@@ -84,7 +84,7 @@ stages:
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
${{ if eq(variables['System.PullRequest.IsFork'], 'False') }}:
|
||||
enableCaching: true
|
||||
enableMsBuildCaching: true
|
||||
|
||||
- ${{ if eq(parameters.runTests, true) }}:
|
||||
- stage: Test_${{ platform }}
|
||||
|
||||
@@ -25,6 +25,8 @@ pr:
|
||||
variables:
|
||||
- name: runCodesignValidationInjectionBG
|
||||
value: false
|
||||
- name: EnablePipelineCache
|
||||
value: true
|
||||
|
||||
# 0.0.yyMM.dd##
|
||||
# 0.0.1904.0900
|
||||
@@ -45,6 +47,10 @@ parameters:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: enableMsBuildCaching
|
||||
type: boolean
|
||||
displayName: "Enable MSBuild Caching"
|
||||
default: true
|
||||
|
||||
stages:
|
||||
- ${{ if eq(parameters.auditMode, true) }}:
|
||||
@@ -87,6 +93,8 @@ stages:
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
${{ if eq(variables['System.PullRequest.IsFork'], 'False') }}:
|
||||
enableMsBuildCaching: ${{ parameters.enableMsBuildCaching }}
|
||||
|
||||
- ${{ if eq(parameters.runTests, true) }}:
|
||||
- stage: Test_${{ platform }}
|
||||
|
||||
@@ -68,7 +68,7 @@ parameters:
|
||||
- name: signingIdentity
|
||||
type: object
|
||||
default: {}
|
||||
- name: enableCaching
|
||||
- name: enableMsBuildCaching
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
@@ -144,7 +144,7 @@ jobs:
|
||||
}
|
||||
displayName: Prepare Build and Sign Targets
|
||||
|
||||
- ${{ if eq(parameters.enableCaching, true) }}:
|
||||
- ${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
||||
- pwsh: |-
|
||||
$MSBuildCacheParameters = ""
|
||||
$MSBuildCacheParameters += " -graph"
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
configuration: $(BuildConfiguration)
|
||||
msbuildArchitecture: x64
|
||||
maximumCpuCount: true
|
||||
${{ if eq(parameters.enableCaching, true) }}:
|
||||
${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
|
||||
@@ -192,7 +192,7 @@ jobs:
|
||||
artifact: logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
condition: always()
|
||||
displayName: Publish Build Log
|
||||
- ${{ if eq(parameters.enableCaching, true) }}:
|
||||
- ${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
||||
- publish: $(Build.SourcesDirectory)\MSBuildCacheLogs
|
||||
artifact: logs-msbuildcache-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
condition: always()
|
||||
@@ -203,7 +203,7 @@ jobs:
|
||||
inputs:
|
||||
contents: $(Build.SourcesDirectory)/msbuild.binlog
|
||||
TargetFolder: $(Terminal.BinDir)
|
||||
- ${{ if eq(parameters.enableCaching, true) }}:
|
||||
- ${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy MSBuildCache Logs
|
||||
inputs:
|
||||
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
$MachineToken = $env:SYSTEM_ACCESSTOKEN | ConvertTo-SecureString -AsPlainText -Force
|
||||
$Credential = [PSCredential]::new("ONEBRANCH_TOKEN", $MachineToken)
|
||||
$MachineToken = $null
|
||||
$Feed = "https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies%40Local/nuget/v3/index.json"
|
||||
$Feed = "https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies/nuget/v3/index.json"
|
||||
Register-PSResourceRepository -Name "PSGalleryUpstream" -Uri $Feed -Trusted
|
||||
Get-PSResourceRepository
|
||||
|
||||
|
||||
@@ -69,3 +69,10 @@ jobs:
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: 'Publish VPack Manifest to Drop'
|
||||
|
||||
- task: PkgESFCIBGit@12
|
||||
displayName: 'Submit VPack Manifest to Windows'
|
||||
inputs:
|
||||
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
prTimeOut: 5
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<!-- Native packages -->
|
||||
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.93.240607003" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.8.250811004" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.7.230706001" targetFramework="native" />
|
||||
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
|
||||
@@ -20,7 +20,7 @@
|
||||
<package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" />
|
||||
|
||||
<!-- MSBuildCache -->
|
||||
<package id="Microsoft.MSBuildCache.AzurePipelines" version="0.1.283-preview" />
|
||||
<package id="Microsoft.MSBuildCache.Local" version="0.1.283-preview" />
|
||||
<package id="Microsoft.MSBuildCache.SharedCompilation" version="0.1.283-preview" />
|
||||
<package id="Microsoft.MSBuildCache.AzurePipelines" version="0.1.318-preview" />
|
||||
<package id="Microsoft.MSBuildCache.Local" version="0.1.318-preview" />
|
||||
<package id="Microsoft.MSBuildCache.SharedCompilation" version="0.1.318-preview" />
|
||||
</packages>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -942,12 +942,12 @@ void ROW::_resizeChars(uint16_t colEndDirty, uint16_t chBegDirty, size_t chEndDi
|
||||
}
|
||||
}
|
||||
|
||||
RowAttributes& ROW::Attributes() noexcept
|
||||
til::small_rle<TextAttribute, uint16_t, 1>& ROW::Attributes() noexcept
|
||||
{
|
||||
return _attr;
|
||||
}
|
||||
|
||||
const RowAttributes& ROW::Attributes() const noexcept
|
||||
const til::small_rle<TextAttribute, uint16_t, 1>& ROW::Attributes() const noexcept
|
||||
{
|
||||
return _attr;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,6 @@
|
||||
class ROW;
|
||||
class TextBuffer;
|
||||
|
||||
// Because MarkKind::Output gets set only on the actually written text,
|
||||
// most rows will end up having at least 2 runs: The start of the line
|
||||
// with MarkKind::Output and the rest of the line with MarkKind::None.
|
||||
using RowAttributes = til::small_rle<TextAttribute, uint16_t, 2>;
|
||||
|
||||
enum class DelimiterClass
|
||||
{
|
||||
ControlChar,
|
||||
@@ -154,8 +149,8 @@ public:
|
||||
void ReplaceText(RowWriteState& state);
|
||||
void CopyTextFrom(RowCopyTextFromState& state);
|
||||
|
||||
RowAttributes& Attributes() noexcept;
|
||||
const RowAttributes& Attributes() const noexcept;
|
||||
til::small_rle<TextAttribute, uint16_t, 1>& Attributes() noexcept;
|
||||
const til::small_rle<TextAttribute, uint16_t, 1>& Attributes() const noexcept;
|
||||
TextAttribute GetAttrByColumn(til::CoordType column) const;
|
||||
std::vector<uint16_t> GetHyperlinks() const;
|
||||
ImageSlice* SetImageSlice(ImageSlice::Pointer imageSlice) noexcept;
|
||||
@@ -303,7 +298,7 @@ private:
|
||||
std::span<uint16_t> _charOffsets;
|
||||
// _attr is a run-length-encoded vector of TextAttribute with a decompressed
|
||||
// length equal to _columnCount (= 1 TextAttribute per column).
|
||||
RowAttributes _attr;
|
||||
til::small_rle<TextAttribute, uint16_t, 1> _attr;
|
||||
// The width of the row in visual columns.
|
||||
uint16_t _columnCount = 0;
|
||||
// Stores double-width/height (DECSWL/DECDWL/DECDHL) attributes.
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace TerminalAppLocalTests
|
||||
_value{ value } {}
|
||||
|
||||
winrt::hstring Name() { return _value; }
|
||||
winrt::hstring Subtitle() { return {}; }
|
||||
winrt::hstring KeyChordText() { return {}; }
|
||||
winrt::hstring Icon() { return {}; }
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<!-- TerminalCppWinrt is intentionally not set -->
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
<TerminalThemeHelpers>true</TerminalThemeHelpers>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(SolutionDir)\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
@@ -548,9 +548,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
|
||||
{
|
||||
const auto copyFormatting = realArgs.CopyFormatting();
|
||||
const auto format = copyFormatting ? copyFormatting.Value() : _settings.GlobalSettings().CopyFormatting();
|
||||
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.WithControlSequences(), format);
|
||||
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.WithControlSequences(), realArgs.CopyFormatting());
|
||||
args.Handled(handled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,19 +135,12 @@ namespace winrt::TerminalApp::implementation
|
||||
_isElevated = ::Microsoft::Console::Utils::IsRunningElevated();
|
||||
_canDragDrop = ::Microsoft::Console::Utils::CanUwpDragDrop();
|
||||
|
||||
_reloadSettings = std::make_shared<ThrottledFunc<>>(
|
||||
DispatcherQueue::GetForCurrentThread(),
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 100 },
|
||||
.debounce = true,
|
||||
.trailing = true,
|
||||
},
|
||||
[weakSelf = get_weak()]() {
|
||||
if (auto self{ weakSelf.get() })
|
||||
{
|
||||
self->ReloadSettings();
|
||||
}
|
||||
});
|
||||
_reloadSettings = std::make_shared<ThrottledFuncTrailing<>>(winrt::Windows::System::DispatcherQueue::GetForCurrentThread(), std::chrono::milliseconds(100), [weakSelf = get_weak()]() {
|
||||
if (auto self{ weakSelf.get() })
|
||||
{
|
||||
self->ReloadSettings();
|
||||
}
|
||||
});
|
||||
|
||||
_languageProfileNotifier = winrt::make_self<LanguageProfileNotifier>([this]() {
|
||||
_reloadSettings->Run();
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace winrt::TerminalApp::implementation
|
||||
bool _hasSettingsStartupActions{ false };
|
||||
::TerminalApp::AppCommandlineArgs _settingsAppArgs;
|
||||
|
||||
std::shared_ptr<ThrottledFunc<>> _reloadSettings;
|
||||
std::shared_ptr<ThrottledFuncTrailing<>> _reloadSettings;
|
||||
|
||||
std::vector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> _warnings{};
|
||||
|
||||
|
||||
267
src/cascadia/TerminalApp/ColorHelper.cpp
Normal file
267
src/cascadia/TerminalApp/ColorHelper.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
#include "ColorHelper.h"
|
||||
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
// Method Description:
|
||||
// Determines whether or not a given color is light
|
||||
// Arguments:
|
||||
// - color: this color is going to be examined whether it
|
||||
// is light or not
|
||||
// Return Value:
|
||||
// - true if light, false if dark
|
||||
bool ColorHelper::IsBrightColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
// https://www.w3.org/TR/AERT#color-contrast
|
||||
auto brightness = (color.R * 299 + color.G * 587 + color.B * 114) / 1000.f;
|
||||
return brightness > 128.f;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Converts a rgb color to an hsl one
|
||||
// Arguments:
|
||||
// - color: the rgb color, which is going to be converted
|
||||
// Return Value:
|
||||
// - a hsl color with the following ranges
|
||||
// - H: [0.f -360.f]
|
||||
// - L: [0.f - 1.f] (rounded to the third decimal place)
|
||||
// - S: [0.f - 1.f] (rounded to the third decimal place)
|
||||
HSL ColorHelper::RgbToHsl(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
// https://www.rapidtables.com/convert/color/rgb-to-hsl.html
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
auto r = color.R / 255.f;
|
||||
auto g = color.G / 255.f;
|
||||
auto b = color.B / 255.f;
|
||||
|
||||
auto max = std::max(r, std::max(g, b));
|
||||
auto min = std::min(r, std::min(g, b));
|
||||
|
||||
auto delta = max - min;
|
||||
|
||||
auto h = 0.f;
|
||||
auto s = 0.f;
|
||||
auto l = (max + min) / 2;
|
||||
|
||||
if (delta < epsilon || max < epsilon) /* delta == 0 || max == 0*/
|
||||
{
|
||||
l = std::roundf(l * 1000) / 1000;
|
||||
return HSL{ h, s, l };
|
||||
}
|
||||
|
||||
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
||||
|
||||
if (max - r < epsilon) // max == r
|
||||
{
|
||||
h = (g - b) / delta + (g < b ? 6 : 0);
|
||||
}
|
||||
else if (max - g < epsilon) // max == g
|
||||
{
|
||||
h = (b - r) / delta + 2;
|
||||
}
|
||||
else if (max - b < epsilon) // max == b
|
||||
{
|
||||
h = (r - g) / delta + 4;
|
||||
}
|
||||
|
||||
// three decimal places after the comma ought
|
||||
// to be enough for everybody - Bill Gates, 1981
|
||||
auto finalH = std::roundf(h * 60);
|
||||
auto finalS = std::roundf(s * 1000) / 1000;
|
||||
auto finalL = std::roundf(l * 1000) / 1000;
|
||||
|
||||
return HSL{ finalH, finalS, finalL };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Converts a hsl color to rgb one
|
||||
// Arguments:
|
||||
// - color: the hsl color, which is going to be converted
|
||||
// Return Value:
|
||||
// - the rgb color (r,g,b - [0, 255] range)
|
||||
winrt::Windows::UI::Color ColorHelper::HslToRgb(const HSL& color)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
auto h = (color.H - 1.f > epsilon) ? color.H / 360.f : color.H;
|
||||
auto s = (color.S - 1.f > epsilon) ? color.S / 100.f : color.S;
|
||||
auto l = (color.L - 1.f > epsilon) ? color.L / 100.f : color.L;
|
||||
|
||||
auto r = l;
|
||||
auto g = l;
|
||||
auto b = l;
|
||||
|
||||
if (s > epsilon)
|
||||
{
|
||||
auto q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
auto p = 2 * l - q;
|
||||
r = HueToRgb(p, q, h + 1.f / 3.f);
|
||||
g = HueToRgb(p, q, h);
|
||||
b = HueToRgb(p, q, h - 1.f / 3.f);
|
||||
}
|
||||
|
||||
auto finalR = static_cast<uint8_t>(std::roundf(r * 255));
|
||||
auto finalG = static_cast<uint8_t>(std::roundf(g * 255));
|
||||
auto finalB = static_cast<uint8_t>(std::roundf(b * 255));
|
||||
uint8_t finalA = 255; //opaque
|
||||
|
||||
return winrt::Windows::UI::ColorHelper::FromArgb(finalA, finalR, finalG, finalB);
|
||||
}
|
||||
|
||||
float ColorHelper::HueToRgb(float p, float q, float t)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
if (t < 0)
|
||||
t += 1;
|
||||
if (t > 1)
|
||||
t -= 1;
|
||||
if (t - (1.f / 6.f) < epsilon)
|
||||
return p + (q - p) * 6 * t;
|
||||
if (t - .5f < epsilon)
|
||||
return q;
|
||||
if (t - 2.f / 3.f < epsilon)
|
||||
return p + (q - p) * (2.f / 3.f - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Lightens a color by a given amount
|
||||
// Arguments:
|
||||
// - color: the color which is going to be lightened
|
||||
// - amount: the lighten amount (0-100)
|
||||
// Return Value:
|
||||
// - the lightened color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::Lighten(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
|
||||
{
|
||||
auto hsl = RgbToHsl(color);
|
||||
hsl.L += amount / 100;
|
||||
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
|
||||
return HslToRgb(hsl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Darkens a color by a given amount
|
||||
// Arguments:
|
||||
// - color: the color which is going to be darkened
|
||||
// - amount: the darken amount (0-100)
|
||||
// Return Value:
|
||||
// - the darkened color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::Darken(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
|
||||
{
|
||||
auto hsl = RgbToHsl(color);
|
||||
hsl.L -= amount / 100;
|
||||
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
|
||||
return HslToRgb(hsl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets an accent color to a given color. Basically, generates
|
||||
// 16 shades of the color and finds the first which has a good
|
||||
// contrast according to https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Readability ratio of 3.5 seems to look quite nicely
|
||||
// Arguments:
|
||||
// - color: the color for which we need an accent
|
||||
// Return Value:
|
||||
// - the accent color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::GetAccentColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
auto accentColor = RgbToHsl(color);
|
||||
|
||||
if (accentColor.S < 0.15)
|
||||
{
|
||||
accentColor.S = 0.15f;
|
||||
}
|
||||
|
||||
constexpr auto shadeCount = 16;
|
||||
constexpr auto shadeStep = 1.f / shadeCount;
|
||||
auto shades = std::map<float, HSL>();
|
||||
for (auto i = 0; i < 15; i++)
|
||||
{
|
||||
auto shade = HSL{ accentColor.H, accentColor.S, i * shadeStep };
|
||||
auto contrast = GetReadability(shade, accentColor);
|
||||
shades.insert(std::make_pair(contrast, shade));
|
||||
}
|
||||
|
||||
// 3f is quite nice if the whole non-client area is painted
|
||||
constexpr auto readability = 1.75f;
|
||||
for (auto shade : shades)
|
||||
{
|
||||
if (shade.first >= readability)
|
||||
{
|
||||
return HslToRgb(shade.second);
|
||||
}
|
||||
}
|
||||
return HslToRgb(shades.end()->second);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets the readability of two colors according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Arguments:
|
||||
// - firstColor: the first color for the readability check (hsl)
|
||||
// - secondColor: the second color for the readability check (hsl)
|
||||
// Return Value:
|
||||
// - the readability of the colors according to (WCAG Version 2)
|
||||
float ColorHelper::GetReadability(const HSL& first, const HSL& second)
|
||||
{
|
||||
return GetReadability(HslToRgb(first), HslToRgb(second));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets the readability of two colors according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Arguments:
|
||||
// - firstColor: the first color for the readability check (rgb)
|
||||
// - secondColor: the second color for the readability check (rgb)
|
||||
// Return Value:
|
||||
// - the readability of the colors according to (WCAG Version 2)
|
||||
float ColorHelper::GetReadability(const winrt::Windows::UI::Color& first, const winrt::Windows::UI::Color& second)
|
||||
{
|
||||
auto l1 = GetLuminance(first);
|
||||
auto l2 = GetLuminance(second);
|
||||
|
||||
return (std::max(l1, l2) + 0.05f) / std::min(l1, l2) + 0.05f;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Calculates the luminance of a given color according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
// Arguments:
|
||||
// - color: its luminance is going to be calculated
|
||||
// Return Value:
|
||||
// - the luminance of the color
|
||||
float ColorHelper::GetLuminance(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
float R, G, B;
|
||||
auto RsRGB = color.R / 255.f;
|
||||
auto GsRGB = color.G / 255.f;
|
||||
auto BsRGB = color.B / 255.f;
|
||||
|
||||
if (RsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
R = RsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
R = std::pow(((RsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
if (GsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
G = GsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
G = std::pow(((GsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
if (BsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
B = BsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
B = std::pow(((BsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
auto luminance = (0.2126f * R) + (0.7152f * G) + (0.0722f * B);
|
||||
return std::roundf(luminance * 10000) / 10000.f;
|
||||
}
|
||||
31
src/cascadia/TerminalApp/ColorHelper.h
Normal file
31
src/cascadia/TerminalApp/ColorHelper.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.UI.h>
|
||||
|
||||
namespace winrt::TerminalApp
|
||||
{
|
||||
class HSL
|
||||
{
|
||||
public:
|
||||
float H;
|
||||
float S;
|
||||
float L;
|
||||
};
|
||||
|
||||
class ColorHelper
|
||||
{
|
||||
public:
|
||||
static bool IsBrightColor(const Windows::UI::Color& color);
|
||||
static HSL RgbToHsl(const Windows::UI::Color& color);
|
||||
static Windows::UI::Color HslToRgb(const HSL& color);
|
||||
static Windows::UI::Color Lighten(const Windows::UI::Color& color, float amount = 10.f);
|
||||
static Windows::UI::Color Darken(const Windows::UI::Color& color, float amount = 10.f);
|
||||
static Windows::UI::Color GetAccentColor(const Windows::UI::Color& color);
|
||||
static float GetLuminance(const Windows::UI::Color& color);
|
||||
static float GetReadability(const Windows::UI::Color& first, const Windows::UI::Color& second);
|
||||
static float GetReadability(const HSL& first, const HSL& second);
|
||||
|
||||
private:
|
||||
static float HueToRgb(float p, float q, float t);
|
||||
};
|
||||
}
|
||||
@@ -44,12 +44,6 @@
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SubtitleTextStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemBaseMediumColor}" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="ListItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<ListViewItem HorizontalContentAlignment="Stretch"
|
||||
@@ -77,19 +71,11 @@
|
||||
Height="16"
|
||||
Content="{x:Bind Item.ResolvedIcon, Mode=OneWay}" />
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Vertical">
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind SubtitleHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Subtitle, Mode=OneWay}"
|
||||
TextBlockStyle="{StaticResource SubtitleTextStyle}"
|
||||
Visibility="{x:Bind HasSubtitle, Mode=OneWay}" />
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
|
||||
</StackPanel>
|
||||
<!--
|
||||
The block for the key chord is only visible
|
||||
when there's actual text set as the label.
|
||||
@@ -136,19 +122,10 @@
|
||||
Height="16"
|
||||
Content="{x:Bind Item.ResolvedIcon, Mode=OneWay}" />
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Vertical">
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind SubtitleHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Subtitle, Mode=OneWay}"
|
||||
TextBlockStyle="{StaticResource SubtitleTextStyle}"
|
||||
Visibility="{x:Bind HasSubtitle, Mode=OneWay}" />
|
||||
|
||||
</StackPanel>
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
|
||||
<!--
|
||||
The block for the key chord is only visible
|
||||
|
||||
@@ -17,31 +17,6 @@ namespace winrt::TerminalApp::implementation
|
||||
ActionPaletteItem(const Microsoft::Terminal::Settings::Model::Command& command, const winrt::hstring keyChordText) :
|
||||
_Command{ command }, _name{ command.Name() }, _keyChordText{ keyChordText }
|
||||
{
|
||||
static bool shouldShowSubtitles = [] {
|
||||
try
|
||||
{
|
||||
const auto context{ winrt::Windows::ApplicationModel::Resources::Core::ResourceContext::GetForViewIndependentUse() };
|
||||
const auto qualifiers{ context.QualifierValues() };
|
||||
if (const auto language{ qualifiers.TryLookup(L"language") })
|
||||
{
|
||||
return !til::starts_with_insensitive_ascii(*language, L"en-");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (shouldShowSubtitles)
|
||||
{
|
||||
const auto subtitle = _Command.LanguageNeutralName();
|
||||
if (subtitle != _name)
|
||||
{
|
||||
_subtitle = std::move(subtitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring Name()
|
||||
@@ -49,11 +24,6 @@ namespace winrt::TerminalApp::implementation
|
||||
return _name;
|
||||
}
|
||||
|
||||
winrt::hstring Subtitle()
|
||||
{
|
||||
return _subtitle;
|
||||
}
|
||||
|
||||
winrt::hstring KeyChordText()
|
||||
{
|
||||
return _keyChordText;
|
||||
@@ -61,7 +31,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::hstring Icon()
|
||||
{
|
||||
return _Command.Icon().Resolved();
|
||||
return _Command.IconPath();
|
||||
}
|
||||
|
||||
WINRT_PROPERTY(Microsoft::Terminal::Settings::Model::Command, Command, nullptr);
|
||||
@@ -69,7 +39,6 @@ namespace winrt::TerminalApp::implementation
|
||||
private:
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _commandChangedRevoker;
|
||||
winrt::hstring _name;
|
||||
winrt::hstring _subtitle;
|
||||
winrt::hstring _keyChordText;
|
||||
};
|
||||
|
||||
@@ -85,11 +54,6 @@ namespace winrt::TerminalApp::implementation
|
||||
return _CommandLine;
|
||||
}
|
||||
|
||||
winrt::hstring Subtitle()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring KeyChordText()
|
||||
{
|
||||
return {};
|
||||
@@ -123,11 +87,6 @@ namespace winrt::TerminalApp::implementation
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring Subtitle()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring KeyChordText()
|
||||
{
|
||||
return {};
|
||||
|
||||
@@ -26,16 +26,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Recompute the highlighted name if the item name changes
|
||||
// Our Item will not change, so we don't need to update the revoker if it does.
|
||||
_itemChangedRevoker = _Item.as<winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged>().PropertyChanged(winrt::auto_revoke, [=](auto& /*sender*/, auto& e) {
|
||||
const auto property{ e.PropertyName() };
|
||||
if (property == L"Name")
|
||||
_itemChangedRevoker = _Item.as<winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged>().PropertyChanged(winrt::auto_revoke, [weakThis{ get_weak() }](auto& /*sender*/, auto& e) {
|
||||
auto filteredCommand{ weakThis.get() };
|
||||
if (filteredCommand && e.PropertyName() == L"Name")
|
||||
{
|
||||
_update();
|
||||
}
|
||||
else if (property == L"Subtitle")
|
||||
{
|
||||
_update();
|
||||
PropertyChanged.raise(*this, winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"HasSubtitle" });
|
||||
filteredCommand->_update();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -51,11 +46,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
bool FilteredCommand::HasSubtitle()
|
||||
{
|
||||
return !_Item.Subtitle().empty();
|
||||
}
|
||||
|
||||
static std::tuple<std::vector<winrt::TerminalApp::HighlightedRun>, int32_t> _matchedSegmentsAndWeight(const std::shared_ptr<fzf::matcher::Pattern>& pattern, const winrt::hstring& haystack)
|
||||
{
|
||||
std::vector<winrt::TerminalApp::HighlightedRun> segments;
|
||||
@@ -78,17 +68,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void FilteredCommand::_update()
|
||||
{
|
||||
auto itemName = _Item.Name();
|
||||
auto [segments, weight] = _matchedSegmentsAndWeight(_pattern, itemName);
|
||||
decltype(segments) subtitleSegments;
|
||||
|
||||
if (HasSubtitle())
|
||||
{
|
||||
auto itemSubtitle = _Item.Subtitle();
|
||||
int32_t subtitleWeight = 0;
|
||||
std::tie(subtitleSegments, subtitleWeight) = _matchedSegmentsAndWeight(_pattern, itemSubtitle);
|
||||
weight = std::max(weight, subtitleWeight);
|
||||
}
|
||||
auto [segments, weight] = _matchedSegmentsAndWeight(_pattern, _Item.Name());
|
||||
|
||||
if (segments.empty())
|
||||
{
|
||||
@@ -99,15 +79,6 @@ namespace winrt::TerminalApp::implementation
|
||||
NameHighlights(winrt::single_threaded_vector(std::move(segments)));
|
||||
}
|
||||
|
||||
if (subtitleSegments.empty())
|
||||
{
|
||||
SubtitleHighlights(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
SubtitleHighlights(winrt::single_threaded_vector(std::move(subtitleSegments)));
|
||||
}
|
||||
|
||||
Weight(weight);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
static int Compare(const winrt::TerminalApp::FilteredCommand& first, const winrt::TerminalApp::FilteredCommand& second);
|
||||
|
||||
bool HasSubtitle();
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::IPaletteItem, Item, PropertyChanged.raise, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::HighlightedRun>, NameHighlights, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::HighlightedRun>, SubtitleHighlights, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(int, Weight, PropertyChanged.raise);
|
||||
|
||||
private:
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace TerminalApp
|
||||
|
||||
IPaletteItem Item { get; };
|
||||
IVector<HighlightedRun> NameHighlights { get; };
|
||||
IVector<HighlightedRun> SubtitleHighlights { get; };
|
||||
Boolean HasSubtitle { get; };
|
||||
Int32 Weight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace TerminalApp
|
||||
{
|
||||
PaletteItemType Type { get; };
|
||||
String Name { get; };
|
||||
String Subtitle { get; };
|
||||
String KeyChordText { get; };
|
||||
String Icon { get; };
|
||||
Windows.UI.Xaml.Controls.IconElement ResolvedIcon { get; };
|
||||
|
||||
@@ -19,6 +19,41 @@ DEFINE_PROPERTYKEY(PKEY_AppUserModel_DestListLogoUri, 0x9F4C2855, 0x9F79, 0x4B39
|
||||
{ 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 }, 29 \
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - This function guesses whether a string is a file path.
|
||||
static constexpr bool _isProbableFilePath(std::wstring_view path)
|
||||
{
|
||||
// "C:X", "C:\X", "\\?", "\\."
|
||||
// _this function rejects \??\ as a path_
|
||||
if (path.size() >= 3)
|
||||
{
|
||||
const auto firstColon{ path.find(L':') };
|
||||
if (firstColon == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto prefix{ path.substr(0, 2) };
|
||||
return prefix == LR"(//)" || prefix == LR"(\\)";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - DestListLogoUri cannot take paths that are separated by / unless they're URLs.
|
||||
// This function uses std::filesystem to normalize strings that appear to be file
|
||||
// paths to have the "correct" slash direction.
|
||||
static std::wstring _normalizeIconPath(std::wstring_view path)
|
||||
{
|
||||
const auto fullPath{ wil::ExpandEnvironmentStringsW<std::wstring>(path.data()) };
|
||||
if (_isProbableFilePath(fullPath))
|
||||
{
|
||||
std::filesystem::path asPath{ fullPath };
|
||||
return asPath.make_preferred().wstring();
|
||||
}
|
||||
return std::wstring{ fullPath };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Updates the items of the Jumplist based on the given settings.
|
||||
// Arguments:
|
||||
@@ -89,7 +124,7 @@ void Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows:
|
||||
auto args = fmt::format(FMT_COMPILE(L"-p {}"), to_hstring(profile.Guid()));
|
||||
|
||||
// Create the shell link object for the profile
|
||||
const auto normalizedIconPath{ profile.Icon().Resolved() };
|
||||
const auto normalizedIconPath{ _normalizeIconPath(profile.Icon()) };
|
||||
const auto shLink = _createShellLink(profile.Name(), normalizedIconPath, args);
|
||||
THROW_IF_FAILED(jumplistItems->AddObject(shLink.get()));
|
||||
}
|
||||
|
||||
@@ -35,23 +35,17 @@ namespace winrt::TerminalApp::implementation
|
||||
// (which should be the default, see:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-trackmouseevent#remarks)
|
||||
unsigned int hoverTimeoutMillis{ 400 };
|
||||
if (FAILED(SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hoverTimeoutMillis, 0)))
|
||||
{
|
||||
hoverTimeoutMillis = 400;
|
||||
}
|
||||
LOG_IF_WIN32_BOOL_FALSE(SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hoverTimeoutMillis, 0));
|
||||
const auto toolTipInterval = std::chrono::milliseconds(hoverTimeoutMillis);
|
||||
|
||||
// Create a ThrottledFunc for opening the tooltip after the hover
|
||||
// timeout. If we hover another button, we should make sure to call
|
||||
// Run() with the new button. Calling `_displayToolTip.Run(nullptr)`,
|
||||
// which will cause us to not display a tooltip, which is used when we
|
||||
// leave the control entirely.
|
||||
_displayToolTip = std::make_shared<ThrottledFunc<Controls::Button>>(
|
||||
_displayToolTip = std::make_shared<ThrottledFuncTrailing<Controls::Button>>(
|
||||
dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ hoverTimeoutMillis },
|
||||
.debounce = true,
|
||||
.trailing = true,
|
||||
},
|
||||
toolTipInterval,
|
||||
[weakThis = get_weak()](Controls::Button button) {
|
||||
// If we provide a button, then open the tooltip on that button.
|
||||
// We can "dismiss" this throttled func by calling it with null,
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> MaximizeClick;
|
||||
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> CloseClick;
|
||||
|
||||
std::shared_ptr<ThrottledFunc<winrt::Windows::UI::Xaml::Controls::Button>> _displayToolTip{ nullptr };
|
||||
std::shared_ptr<ThrottledFuncTrailing<winrt::Windows::UI::Xaml::Controls::Button>> _displayToolTip{ nullptr };
|
||||
std::optional<CaptionButton> _lastPressedButton{ std::nullopt };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1161,12 +1161,10 @@ void Pane::SetActive()
|
||||
// focused, else the profile of the last control to be focused
|
||||
Profile Pane::GetFocusedProfile()
|
||||
{
|
||||
if (auto lastFocused{ GetActivePane() })
|
||||
auto lastFocused = GetActivePane();
|
||||
if (const auto& terminalPane{ lastFocused->_getTerminalContent() })
|
||||
{
|
||||
if (const auto& terminalPane{ lastFocused->_getTerminalContent() })
|
||||
{
|
||||
return terminalPane.GetProfile();
|
||||
}
|
||||
return terminalPane.GetProfile();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -270,9 +270,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Registerkarte kopieren</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Mindestens eine in den Einstellungen angegebene Ressource (z. B. icon oder backgroundImage) wurde nicht gefunden.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>Profil mit einem ungültigen "backgroundImage" gefunden. Dieses Profil hat standardmäßig kein Hintergrundbild. Stellen Sie sicher, dass beim Festlegen eines "backgroundImage" der Wert ein gültiger Dateipfad zu einem Bild ist.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Profil mit einem ungültigen "icon" gefunden. Dieses Profil hat standardmäßig kein Symbol. Stellen Sie sicher, dass beim Festlegen eines "icon" der Wert ein gültiger Dateipfad zu einem Bild ist.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Beim Analysieren Ihrer Tastenzuordnungen wurden Warnungen gefunden:</value>
|
||||
|
||||
@@ -271,9 +271,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Duplicate tab</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>One or more resources (such as icon or backgroundImage) specified in your settings could not be found.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>Found a profile with an invalid "backgroundImage". Defaulting that profile to have no background image. Make sure that when setting a "backgroundImage", the value is a valid file path to an image.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Found a profile with an invalid "icon". Defaulting that profile to have no icon. Make sure that when setting an "icon", the value is a valid file path to an image.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Warnings were found while parsing your keybindings:</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Duplicar pestaña</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>No se encontraron uno o varios recursos (como icon o backgroundImage) especificados en la configuración.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>Se encontró un perfil con un "backgroundImage" no válido. Si se predetermina que ese perfil no tiene imagen de fondo. Asegúrese de que al establecer "backgroundImage", el valor sea una ruta de acceso de archivo válida a una imagen.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Se encontró un perfil con un "icon" no válido. Estableciendo ese perfil para no tener icono. Asegúrese de que, al establecer un "icon", el valor es una ruta de acceso de archivo válida a una imagen.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Se encontraron advertencias al analizar los enlaces de teclado:</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Dupliquer l’onglet</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Une ou plusieurs ressources (telles que icon ou backgroundImage) spécifiées dans vos paramètres sont introuvables.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>Profil détecté avec une "backgroundImage" non valide. Par défaut, ce profil ne possède pas d’image d’arrière-plan. Assurez-vous que lorsque vous définissez une "backgroundImage", la valeur est un chemin d’accès de fichier valide vers une image.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Profil détecté avec une "icon" non valide. Par défaut, ce profil ne possède pas d’icône. Assurez-vous que lorsque vous définissez une "icon", la valeur est un chemin d’accès de fichier valide vers une image.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Des avertissements ont été détectés lors de l’analyse de vos combinaisons de touches :</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Duplica scheda</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Impossibile trovare una o più risorse, ad esempio icon o backgroundImage, specificate nelle impostazioni.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>È stato trovato un profilo con un "backgroundImage" non valido. Impostazione predefinita per il profilo non è disponibile un'immagine di sfondo. Accertarsi che quando si imposta un "backgroundImage", il valore è un percorso di file valido per un'immagine.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Trovato un profilo con "icon" non valida. Impostare il profilo senza icon. Assicurarsi che, quando si imposta una "icon", il valore abbia un percorso file valido per un'immagine.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Sono stati trovati avvisi durante l'analisi delle associazioni di tasti:</value>
|
||||
|
||||
@@ -268,9 +268,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>タブを複製する</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>設定で指定された 1 つ以上のリソース (icon や backgroundImage など) が見つかりませんでした。</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>無効な "backgroundImage" を持つプロファイルが見つかりました。既定では、そのプロファイルに背景画像はありません。"backgroundImage" を設定するときに、値が画像への有効なファイル パスとなっていることをご確認ください。</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>無効な "icon" を持つプロファイルが見つかりました。既定では、そのプロファイルにアイコンはありません。"icon" を設定するときに、値が画像への有効なファイル パスとなっていることをご確認ください。</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>キー バインドの解析中に警告が検出されました:</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>탭 복제</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>설정에 지정된 하나 이상의 리소스(예: icon 또는 backgroundImage)를 찾을 수 없습니다.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>잘못된 "backgroundImage" 프로필을 찾았습니다. 해당 프로필을 배경 이미지가 없는 기본값으로 설정합니다. "backgroundImage"를 설정할 때 값이 이미지에 대한 유효한 파일 경로인지 확인합니다.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>잘못된 "icon"이 있는 프로필을 발견했습니다. 해당 프로필에 아이콘이 없도록 기본값을 설정합니다. "icon" 설정 시 값이 이미지에 대한 올바른 파일 경로인지 확인합니다.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>키 바인딩 구문을 분석하는 동안 경고를 발견했습니다.</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Duplicar guia</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Um ou mais recursos (como icon ou backgroundImage) especificados em suas configurações não foram encontrados.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>Foi encontrado um perfil com um "backgroundImage" inválido. O perfil deve ser o padrão para que não haja nenhuma imagem de tela de fundo. Certifique-se de que, ao definir um "backgroundImage", o valor é um caminho de arquivo válido para uma imagem.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Foi encontrado um perfil com um "icon" inválido. Padronize esse perfil para ele não ter ícone. Certifique-se de que, ao definir um "icon", o valor seja um caminho de arquivo válido para uma imagem.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Os avisos foram encontrados durante a análise das suas ligações de teclas:</value>
|
||||
|
||||
@@ -271,9 +271,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Ďϋφľіčάтέ τàв !!! </value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Ωňę бг mθгě яėŝǿüґсėş (šυćн âş icon ōя backgroundImage) ŝрěçìƒįєð ίπ ýőūŕ ŝėтťīлġš ċòŭĺð йöŧ вέ ƒòúпď. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>₣σúŋδ ą φѓοƒĩļé ẃϊţħ äй ïηνàĺìď "backgroundImage". Đēƒãųŀŧϊпğ ťнªт φѓőƒĭļè το нªνе πō ьąçќġгθúпδ ιмãġė. Маĸē śμѓē ŧћäţ ẁђēή šêťτϊлġ å "backgroundImage", ţĥě νаłųё ïŝ ά νάľîď ƒĩŀê φąťħ ţŏ άń ΐмąġė. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>₣ǿũиđ à рřöƒϊℓз ŵĩţн аñ įņνàŀїδ "icon". Ðěƒаúľτīŋğ ţħаτ ρřόƒìŀё тб ђâνє пǿ íčой. Мàĸë ŝùřë ŧĥаţ ωĥĕл ŝеτŧīлĝ ăй "icon", τħε νāłϋë ïŝ ă νàľīđ ƒïŀè рªтн ţő äи ïмäģё. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Щαѓńΐňģš ώĕřе ƒбŭπδ ώħīļë рăяşìⁿġ ўσυŕ κёỳвĩиðīήġş: !!! !!! !!! !!! !!!</value>
|
||||
|
||||
@@ -271,9 +271,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Ďϋφľіčάтέ τàв !!! </value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Ωňę бг mθгě яėŝǿüґсėş (šυćн âş icon ōя backgroundImage) ŝрěçìƒįєð ίπ ýőūŕ ŝėтťīлġš ċòŭĺð йöŧ вέ ƒòúпď. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>₣σúŋδ ą φѓοƒĩļé ẃϊţħ äй ïηνàĺìď "backgroundImage". Đēƒãųŀŧϊпğ ťнªт φѓőƒĭļè το нªνе πō ьąçќġгθúпδ ιмãġė. Маĸē śμѓē ŧћäţ ẁђēή šêťτϊлġ å "backgroundImage", ţĥě νаłųё ïŝ ά νάľîď ƒĩŀê φąťħ ţŏ άń ΐмąġė. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>₣ǿũиđ à рřöƒϊℓз ŵĩţн аñ įņνàŀїδ "icon". Ðěƒаúľτīŋğ ţħаτ ρřόƒìŀё тб ђâνє пǿ íčой. Мàĸë ŝùřë ŧĥаţ ωĥĕл ŝеτŧīлĝ ăй "icon", τħε νāłϋë ïŝ ă νàľīđ ƒïŀè рªтн ţő äи ïмäģё. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Щαѓńΐňģš ώĕřе ƒбŭπδ ώħīļë рăяşìⁿġ ўσυŕ κёỳвĩиðīήġş: !!! !!! !!! !!! !!!</value>
|
||||
|
||||
@@ -271,9 +271,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Ďϋφľіčάтέ τàв !!! </value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Ωňę бг mθгě яėŝǿüґсėş (šυćн âş icon ōя backgroundImage) ŝрěçìƒįєð ίπ ýőūŕ ŝėтťīлġš ċòŭĺð йöŧ вέ ƒòúпď. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>₣σúŋδ ą φѓοƒĩļé ẃϊţħ äй ïηνàĺìď "backgroundImage". Đēƒãųŀŧϊпğ ťнªт φѓőƒĭļè το нªνе πō ьąçќġгθúпδ ιмãġė. Маĸē śμѓē ŧћäţ ẁђēή šêťτϊлġ å "backgroundImage", ţĥě νаłųё ïŝ ά νάľîď ƒĩŀê φąťħ ţŏ άń ΐмąġė. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>₣ǿũиđ à рřöƒϊℓз ŵĩţн аñ įņνàŀїδ "icon". Ðěƒаúľτīŋğ ţħаτ ρřόƒìŀё тб ђâνє пǿ íčой. Мàĸë ŝùřë ŧĥаţ ωĥĕл ŝеτŧīлĝ ăй "icon", τħε νāłϋë ïŝ ă νàľīđ ƒïŀè рªтн ţő äи ïмäģё. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>Щαѓńΐňģš ώĕřе ƒбŭπδ ώħīļë рăяşìⁿġ ўσυŕ κёỳвĩиðīήġş: !!! !!! !!! !!! !!!</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>Дублировать вкладку</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>Не удалось найти один или несколько ресурсов (icon или backgroundImage), указанных в параметрах.</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>Найден профиль с недопустимым объектом "backgroundImage". По умолчанию для этого профиля не используется фоновое изображение. Убедитесь, что значение, заданное для "backgroundImage", является допустимым путем файла к изображению.</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>Найден профиль с недопустимым объектом "icon". По умолчанию для этого профиля не используется значок. Убедитесь, что значение, заданное для "icon", является допустимым путем файла к изображению.</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>При анализе настраиваемых сочетаний клавиш найдены предупреждения:</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>复制标签页</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>找不到设置中指定的一个或多个资源 (,如 icon 或 backgroundImage)。</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>找到一个具有无效 "backgroundImage" 的配置文件。将该配置文件设置为默认设置为不包含背景图像。请确保在设置 "backgroundImage" 时,该值是指向图像的有效文件路径。</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>找到一个带有无效 "icon" 的配置文件。将该配置文件默认为无图标。确保设置 "icon" 时,该值是图像的有效文件路径。</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>分析键绑定时发现警告:</value>
|
||||
|
||||
@@ -267,9 +267,13 @@
|
||||
<data name="DuplicateTabText" xml:space="preserve">
|
||||
<value>複製索引標籤</value>
|
||||
</data>
|
||||
<data name="InvalidMediaResource" xml:space="preserve">
|
||||
<value>找不到一或多個資源 (,例如在您的設定中指定的 icon 或 backgroundImage)。</value>
|
||||
<comment>{Locked="icon","backgroundImage"} Indicates that something has gone wrong while reading a user's settings.</comment>
|
||||
<data name="InvalidBackgroundImage" xml:space="preserve">
|
||||
<value>找到具有無效 "backgroundImage" 的設定檔。將該設定檔的預設值設為沒有背景影像。請確定設定 "backgroundImage" 時,該值是影像的有效檔案路徑。</value>
|
||||
<comment>{Locked="\"backgroundImage\""}</comment>
|
||||
</data>
|
||||
<data name="InvalidIcon" xml:space="preserve">
|
||||
<value>已發現具有無效 "icon" 的設定檔。將該設定檔預設為無圖示。設定 "icon" 時,請確認值是有效的影像檔案路徑。</value>
|
||||
<comment>{Locked="\"icon\""} The word "icon" in quotes is locked, the word icon OUTSIDE of quotes should be localized.</comment>
|
||||
</data>
|
||||
<data name="AtLeastOneKeybindingWarning" xml:space="preserve">
|
||||
<value>剖析金鑰繫結時發現警告:</value>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "Tab.g.cpp"
|
||||
#include "Utils.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "AppLogic.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@@ -1035,49 +1035,27 @@ namespace winrt::TerminalApp::implementation
|
||||
void Tab::_AttachEventHandlersToContent(const uint32_t paneId, const TerminalApp::IPaneContent& content)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
auto dispatcher = DispatcherQueue::GetForCurrentThread();
|
||||
auto dispatcher = TabViewItem().Dispatcher();
|
||||
ContentEventTokens events{};
|
||||
|
||||
auto throttledTitleChanged = std::make_shared<ThrottledFunc<>>(
|
||||
dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 200 },
|
||||
.leading = true,
|
||||
.trailing = true,
|
||||
},
|
||||
[weakThis]() {
|
||||
if (const auto tab = weakThis.get())
|
||||
{
|
||||
tab->UpdateTitle();
|
||||
}
|
||||
});
|
||||
|
||||
events.TitleChanged = content.TitleChanged(
|
||||
winrt::auto_revoke,
|
||||
[func = std::move(throttledTitleChanged)](auto&&, auto&&) {
|
||||
func->Run();
|
||||
});
|
||||
|
||||
auto throttledTaskbarProgressChanged = std::make_shared<ThrottledFunc<>>(
|
||||
dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 200 },
|
||||
.leading = true,
|
||||
.trailing = true,
|
||||
},
|
||||
[weakThis]() {
|
||||
if (const auto tab = weakThis.get())
|
||||
[dispatcher, weakThis](auto&&, auto&&) -> safe_void_coroutine {
|
||||
// The lambda lives in the `std::function`-style container owned by `control`. That is, when the
|
||||
// `control` gets destroyed the lambda struct also gets destroyed. In other words, we need to
|
||||
// copy `weakThis` onto the stack, because that's the only thing that gets captured in coroutines.
|
||||
// See: https://devblogs.microsoft.com/oldnewthing/20211103-00/?p=105870
|
||||
const auto weakThisCopy = weakThis;
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
// Check if Tab's lifetime has expired
|
||||
if (auto tab{ weakThisCopy.get() })
|
||||
{
|
||||
tab->_UpdateProgressState();
|
||||
// The title of the control changed, but not necessarily the title of the tab.
|
||||
// Set the tab's text to the active panes' text.
|
||||
tab->UpdateTitle();
|
||||
}
|
||||
});
|
||||
|
||||
events.TaskbarProgressChanged = content.TaskbarProgressChanged(
|
||||
winrt::auto_revoke,
|
||||
[func = std::move(throttledTaskbarProgressChanged)](auto&&, auto&&) {
|
||||
func->Run();
|
||||
});
|
||||
|
||||
events.TabColorChanged = content.TabColorChanged(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](auto&&, auto&&) -> safe_void_coroutine {
|
||||
@@ -1093,6 +1071,18 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
events.TaskbarProgressChanged = content.TaskbarProgressChanged(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](auto&&, auto&&) -> safe_void_coroutine {
|
||||
const auto weakThisCopy = weakThis;
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
// Check if Tab's lifetime has expired
|
||||
if (auto tab{ weakThisCopy.get() })
|
||||
{
|
||||
tab->_UpdateProgressState();
|
||||
}
|
||||
});
|
||||
|
||||
events.ConnectionStateChanged = content.ConnectionStateChanged(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](auto&&, auto&&) -> safe_void_coroutine {
|
||||
@@ -2127,9 +2117,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - The value to populate in the title run of the tool tip
|
||||
winrt::hstring Tab::_CreateToolTipTitle()
|
||||
{
|
||||
if (const auto profile{ GetFocusedProfile() })
|
||||
if (const auto& control{ GetActiveTerminalControl() })
|
||||
{
|
||||
const auto profileName{ profile.Name() };
|
||||
const auto profileName{ control.Settings().ProfileName() };
|
||||
if (profileName != Title())
|
||||
{
|
||||
return winrt::hstring{ fmt::format(FMT_COMPILE(L"{}: {}"), profileName, Title()) };
|
||||
@@ -2285,13 +2275,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// the background color
|
||||
// - This method should only be called on the UI thread.
|
||||
// Arguments:
|
||||
// - uiColor: the color the user picked for their tab
|
||||
// - color: the color the user picked for their tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Tab::_ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& uiColor)
|
||||
void Tab::_ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
const til::color color{ uiColor };
|
||||
Media::SolidColorBrush selectedTabBrush{};
|
||||
Media::SolidColorBrush deselectedTabBrush{};
|
||||
Media::SolidColorBrush fontBrush{};
|
||||
@@ -2304,7 +2292,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// calculate the luminance of the current color and select a font
|
||||
// color based on that
|
||||
// see https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||
if (ColorFix::GetLightness(color) >= lightnessThreshold)
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(color))
|
||||
{
|
||||
auto subtleFillColorSecondary = winrt::Windows::UI::Colors::Black();
|
||||
subtleFillColorSecondary.A = 0x09;
|
||||
@@ -2324,8 +2312,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// The tab font should be based on the evaluated appearance of the tab color layered on tab row.
|
||||
const auto layeredTabColor = color.layer_over(_tabRowColor);
|
||||
if (ColorFix::GetLightness(layeredTabColor) >= lightnessThreshold)
|
||||
const auto layeredTabColor = til::color{ color }.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(layeredTabColor))
|
||||
{
|
||||
fontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
auto secondaryFontColor = winrt::Windows::UI::Colors::Black();
|
||||
@@ -2345,7 +2333,8 @@ namespace winrt::TerminalApp::implementation
|
||||
selectedTabBrush.Color(color);
|
||||
|
||||
// Start with the current tab color, set to Opacity=.3
|
||||
auto deselectedTabColor = color.with_alpha(77); // 255 * .3 = 77
|
||||
til::color deselectedTabColor{ color };
|
||||
deselectedTabColor = deselectedTabColor.with_alpha(77); // 255 * .3 = 77
|
||||
|
||||
// If we DON'T have a color set from the color picker, or the profile's
|
||||
// tabColor, but we do have a unfocused color in the theme, use the
|
||||
@@ -2387,7 +2376,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// We don't want that to result in white text on a white tab row for
|
||||
// inactive tabs.
|
||||
const auto deselectedActualColor = deselectedTabColor.layer_over(_tabRowColor);
|
||||
if (ColorFix::GetLightness(deselectedActualColor) >= lightnessThreshold)
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(deselectedActualColor))
|
||||
{
|
||||
deselectedFontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace TerminalApp
|
||||
UInt32 TabViewIndex;
|
||||
UInt32 TabViewNumTabs;
|
||||
|
||||
void Focus(Windows.UI.Xaml.FocusState focusState);
|
||||
void Shutdown();
|
||||
overridable void Focus(Windows.UI.Xaml.FocusState focusState);
|
||||
overridable void Shutdown();
|
||||
|
||||
void SetDispatch(ShortcutActionDispatch dispatch);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "TabRowControl.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "..\TerminalSettingsModel\FileUtils.h"
|
||||
|
||||
@@ -999,7 +1000,10 @@ namespace winrt::TerminalApp::implementation
|
||||
tab.TabViewItem().StartBringIntoView();
|
||||
|
||||
// Raise an event that our title changed
|
||||
TitleChanged.raise(*this, nullptr);
|
||||
if (_settings.GlobalSettings().ShowTitleInTitlebar())
|
||||
{
|
||||
TitleChanged.raise(*this, tab.Title());
|
||||
}
|
||||
|
||||
_updateThemeColors();
|
||||
|
||||
@@ -1009,8 +1013,6 @@ namespace winrt::TerminalApp::implementation
|
||||
auto profile = tabImpl->GetFocusedProfile();
|
||||
_UpdateBackground(profile);
|
||||
}
|
||||
|
||||
_adjustProcessPriorityThrottled->Run();
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
<TerminalWinGetInterop>true</TerminalWinGetInterop>
|
||||
<TerminalThemeHelpers>true</TerminalThemeHelpers>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
@@ -135,6 +134,7 @@
|
||||
<ClInclude Include="FilteredCommand.h" />
|
||||
<ClInclude Include="Pane.h" />
|
||||
<ClInclude Include="fzf/fzf.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ShortcutActionDispatch.h">
|
||||
<DependentUpon>ShortcutActionDispatch.idl</DependentUpon>
|
||||
@@ -174,7 +174,9 @@
|
||||
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Toast.h" />
|
||||
<ClInclude Include="TerminalSettingsCache.h" />
|
||||
<ClInclude Include="TerminalSettingsCache.h">
|
||||
<DependentUpon>TerminalSettingsCache.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SuggestionsControl.h">
|
||||
<DependentUpon>SuggestionsControl.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -245,6 +247,9 @@
|
||||
<ClCompile Include="FilteredCommand.cpp" />
|
||||
<ClCompile Include="Pane.cpp" />
|
||||
<ClCompile Include="Pane.LayoutSizeNode.cpp" />
|
||||
<ClCompile Include="ColorHelper.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DebugTapConnection.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
@@ -287,7 +292,9 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="Toast.cpp" />
|
||||
<ClCompile Include="TerminalSettingsCache.cpp" />
|
||||
<ClCompile Include="TerminalSettingsCache.cpp">
|
||||
<DependentUpon>TerminalSettingsCache.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SuggestionsControl.cpp">
|
||||
<DependentUpon>SuggestionsControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -362,6 +369,7 @@
|
||||
<DependentUpon>TaskPaneContent.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="TerminalSettingsCache.idl" />
|
||||
<Midl Include="MarkdownPaneContent.idl">
|
||||
<DependentUpon>MarkdownPaneContent.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppCommandlineArgs.cpp" />
|
||||
<ClCompile Include="Commandline.cpp" />
|
||||
<ClCompile Include="ColorHelper.cpp" />
|
||||
<ClCompile Include="DebugTapConnection.cpp" />
|
||||
<ClCompile Include="Jumplist.cpp" />
|
||||
<ClCompile Include="FilteredCommand.cpp">
|
||||
@@ -47,6 +48,7 @@
|
||||
<ClInclude Include="AppCommandlineArgs.h" />
|
||||
<ClInclude Include="Commandline.h" />
|
||||
<ClInclude Include="DebugTapConnection.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="Jumplist.h" />
|
||||
<ClInclude Include="FilteredCommand.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
@@ -90,6 +92,7 @@
|
||||
<Midl Include="TerminalWindow.idl" />
|
||||
<Midl Include="TaskbarState.idl" />
|
||||
<Midl Include="IPaneContent.idl" />
|
||||
<Midl Include="TerminalSettingsCache.idl" />
|
||||
<Midl Include="Monarch.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,26 +6,24 @@
|
||||
#include "TerminalPage.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
#include <TerminalThemeHelpers.h>
|
||||
#include <Utils.h>
|
||||
#include <TerminalCore/ControlKeyStates.hpp>
|
||||
#include <Utils.h>
|
||||
|
||||
#include "App.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "MarkdownPaneContent.h"
|
||||
#include "Remoting.h"
|
||||
#include "ScratchpadContent.h"
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "SnippetsPaneContent.h"
|
||||
#include "TabRowControl.h"
|
||||
#include "TerminalSettingsCache.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "App.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "ScratchpadContent.h"
|
||||
#include "SnippetsPaneContent.h"
|
||||
#include "MarkdownPaneContent.h"
|
||||
#include "TabRowControl.h"
|
||||
#include "Remoting.h"
|
||||
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "TerminalPage.g.cpp"
|
||||
#include "RenameWindowRequestedArgs.g.cpp"
|
||||
#include "RequestMoveContentArgs.g.cpp"
|
||||
#include "TerminalPage.g.cpp"
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Microsoft::Management::Deployment;
|
||||
@@ -58,121 +56,6 @@ namespace winrt
|
||||
using VirtualKeyModifiers = Windows::System::VirtualKeyModifiers;
|
||||
}
|
||||
|
||||
namespace clipboard
|
||||
{
|
||||
wil::unique_close_clipboard_call open(HWND hwnd)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// OpenClipboard may fail to acquire the internal lock --> retry.
|
||||
for (DWORD sleep = 10;; sleep *= 2)
|
||||
{
|
||||
if (OpenClipboard(hwnd))
|
||||
{
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
// 10 iterations
|
||||
if (sleep > 10000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(sleep);
|
||||
}
|
||||
|
||||
return wil::unique_close_clipboard_call{ success };
|
||||
}
|
||||
|
||||
void write(wil::zwstring_view text, std::string_view html, std::string_view rtf)
|
||||
{
|
||||
static const auto regular = [](const UINT format, const void* src, const size_t bytes) {
|
||||
wil::unique_hglobal handle{ THROW_LAST_ERROR_IF_NULL(GlobalAlloc(GMEM_MOVEABLE, bytes)) };
|
||||
|
||||
const auto locked = GlobalLock(handle.get());
|
||||
memcpy(locked, src, bytes);
|
||||
GlobalUnlock(handle.get());
|
||||
|
||||
THROW_LAST_ERROR_IF_NULL(SetClipboardData(format, handle.get()));
|
||||
handle.release();
|
||||
};
|
||||
static const auto registered = [](const wchar_t* format, const void* src, size_t bytes) {
|
||||
const auto id = RegisterClipboardFormatW(format);
|
||||
if (!id)
|
||||
{
|
||||
LOG_LAST_ERROR();
|
||||
return;
|
||||
}
|
||||
regular(id, src, bytes);
|
||||
};
|
||||
|
||||
EmptyClipboard();
|
||||
|
||||
if (!text.empty())
|
||||
{
|
||||
// As per: https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
|
||||
// CF_UNICODETEXT: [...] A null character signals the end of the data.
|
||||
// --> We add +1 to the length. This works because .c_str() is null-terminated.
|
||||
regular(CF_UNICODETEXT, text.c_str(), (text.size() + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
if (!html.empty())
|
||||
{
|
||||
registered(L"HTML Format", html.data(), html.size());
|
||||
}
|
||||
|
||||
if (!rtf.empty())
|
||||
{
|
||||
registered(L"Rich Text Format", rtf.data(), rtf.size());
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring read()
|
||||
{
|
||||
// This handles most cases of pasting text as the OS converts most formats to CF_UNICODETEXT automatically.
|
||||
if (const auto handle = GetClipboardData(CF_UNICODETEXT))
|
||||
{
|
||||
const wil::unique_hglobal_locked lock{ handle };
|
||||
const auto str = static_cast<const wchar_t*>(lock.get());
|
||||
if (!str)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto maxLen = GlobalSize(handle) / sizeof(wchar_t);
|
||||
const auto len = wcsnlen(str, maxLen);
|
||||
return winrt::hstring{ str, gsl::narrow_cast<uint32_t>(len) };
|
||||
}
|
||||
|
||||
// We get CF_HDROP when a user copied a file with Ctrl+C in Explorer and pastes that into the terminal (among others).
|
||||
if (const auto handle = GetClipboardData(CF_HDROP))
|
||||
{
|
||||
const wil::unique_hglobal_locked lock{ handle };
|
||||
const auto drop = static_cast<HDROP>(lock.get());
|
||||
if (!drop)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto cap = DragQueryFileW(drop, 0, nullptr, 0);
|
||||
if (cap == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto buffer = winrt::impl::hstring_builder{ cap };
|
||||
const auto len = DragQueryFileW(drop, 0, buffer.data(), cap + 1);
|
||||
if (len == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return buffer.to_hstring();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
} // namespace clipboard
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TerminalPage::TerminalPage(TerminalApp::WindowProperties properties, const TerminalApp::ContentManager& manager) :
|
||||
@@ -219,17 +102,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// before restoring previous tabs in that scenario.
|
||||
}
|
||||
}
|
||||
|
||||
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
|
||||
DispatcherQueue::GetForCurrentThread(),
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 100 },
|
||||
.debounce = true,
|
||||
.trailing = true,
|
||||
},
|
||||
[=]() {
|
||||
_adjustProcessPriority();
|
||||
});
|
||||
_hostingHwnd = hwnd;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -241,7 +113,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_settings == nullptr)
|
||||
{
|
||||
// Create this only on the first time we load the settings.
|
||||
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings, *_bindings);
|
||||
_terminalSettingsCache = TerminalApp::TerminalSettingsCache{ settings, *_bindings };
|
||||
}
|
||||
_settings = settings;
|
||||
|
||||
@@ -673,32 +545,22 @@ namespace winrt::TerminalApp::implementation
|
||||
_WindowProperties.VirtualEnvVars(env);
|
||||
}
|
||||
|
||||
// The current TerminalWindow & TerminalPage architecture is rather instable
|
||||
// and fails to start up if the first tab isn't created synchronously.
|
||||
//
|
||||
// While that's a fair assumption in on itself, simultaneously WinUI will
|
||||
// not assign tab contents a size if they're not shown at least once,
|
||||
// which we need however in order to initialize ControlCore with a size.
|
||||
//
|
||||
// So, we do two things here:
|
||||
// * DO NOT suspend if this is the first tab.
|
||||
// * DO suspend between the creation of panes (or tabs) in order to allow
|
||||
// WinUI to layout the new controls and for ControlCore to get a size.
|
||||
//
|
||||
// This same logic is also applied to CreateTabFromConnection.
|
||||
//
|
||||
// See GH#13136.
|
||||
auto suspend = _tabs.Size() > 0;
|
||||
|
||||
for (size_t i = 0; i < actions.size(); ++i)
|
||||
{
|
||||
if (suspend)
|
||||
if (i != 0)
|
||||
{
|
||||
// Each action may rely on the XAML layout of a preceding action.
|
||||
// Most importantly, this is the case for the combination of NewTab + SplitPane,
|
||||
// as the former appears to only have a layout size after at least 1 resume_foreground,
|
||||
// while the latter relies on that information. This is also why it uses Low priority.
|
||||
//
|
||||
// Curiously, this does not seem to be required when using startupActions, but only when
|
||||
// tearing out a tab (this currently creates a new window with injected startup actions).
|
||||
// This indicates that this is really more of an architectural issue and not a fundamental one.
|
||||
co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Low);
|
||||
}
|
||||
|
||||
_actionDispatch->DoAction(actions[i]);
|
||||
suspend = true;
|
||||
}
|
||||
|
||||
// GH#6586: now that we're done processing all startup commands,
|
||||
@@ -713,16 +575,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
safe_void_coroutine TerminalPage::CreateTabFromConnection(ITerminalConnection connection)
|
||||
void TerminalPage::CreateTabFromConnection(ITerminalConnection connection)
|
||||
{
|
||||
const auto strong = get_strong();
|
||||
|
||||
// This is the exact same logic as in ProcessStartupActions.
|
||||
if (_tabs.Size() > 0)
|
||||
{
|
||||
co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Low);
|
||||
}
|
||||
|
||||
NewTerminalArgs newTerminalArgs;
|
||||
|
||||
if (const auto conpty = connection.try_as<ConptyConnection>())
|
||||
@@ -737,7 +591,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// elevated version of the Terminal with that profile... that's a
|
||||
// recipe for disaster. We won't ever open up a tab in this window.
|
||||
newTerminalArgs.Elevate(false);
|
||||
|
||||
const auto newPane = _MakePane(newTerminalArgs, nullptr, std::move(connection));
|
||||
newPane->WalkTree([](const auto& pane) {
|
||||
pane->FinalizeConfigurationGivenDefault();
|
||||
@@ -1070,7 +923,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto folderEntryItems = _CreateNewTabFlyoutItems(folderEntries);
|
||||
|
||||
// If the folder should auto-inline and there is only one item, do so.
|
||||
if (folderEntry.Inlining() == FolderEntryInlining::Auto && folderEntryItems.size() == 1)
|
||||
if (folderEntry.Inlining() == FolderEntryInlining::Auto && folderEntries.Size() == 1)
|
||||
{
|
||||
for (auto const& folderEntryItem : folderEntryItems)
|
||||
{
|
||||
@@ -1084,7 +937,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto folderItem = WUX::Controls::MenuFlyoutSubItem{};
|
||||
folderItem.Text(folderEntry.Name());
|
||||
|
||||
auto icon = _CreateNewTabFlyoutIcon(folderEntry.Icon().Resolved());
|
||||
auto icon = _CreateNewTabFlyoutIcon(folderEntry.Icon());
|
||||
folderItem.Icon(icon);
|
||||
|
||||
for (const auto& folderEntryItem : folderEntryItems)
|
||||
@@ -1134,7 +987,7 @@ namespace winrt::TerminalApp::implementation
|
||||
break;
|
||||
}
|
||||
|
||||
auto profileItem = _CreateNewTabFlyoutProfile(profileEntry.Profile(), profileEntry.ProfileIndex(), profileEntry.Icon().Resolved());
|
||||
auto profileItem = _CreateNewTabFlyoutProfile(profileEntry.Profile(), profileEntry.ProfileIndex(), profileEntry.Icon());
|
||||
items.push_back(profileItem);
|
||||
break;
|
||||
}
|
||||
@@ -1144,7 +997,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto actionId = actionEntry.ActionId();
|
||||
if (_settings.ActionMap().GetActionByID(actionId))
|
||||
{
|
||||
auto actionItem = _CreateNewTabFlyoutAction(actionId, actionEntry.Icon().Resolved());
|
||||
auto actionItem = _CreateNewTabFlyoutAction(actionId, actionEntry.Icon());
|
||||
items.push_back(actionItem);
|
||||
}
|
||||
|
||||
@@ -1183,7 +1036,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// If a custom icon path has been specified, set it as the icon for
|
||||
// this flyout item. Otherwise, if an icon is set for this profile, set that icon
|
||||
// for this flyout item.
|
||||
const auto& iconPath = iconPathOverride.empty() ? profile.Icon().Resolved() : iconPathOverride;
|
||||
const auto& iconPath = iconPathOverride.empty() ? profile.EvaluatedIcon() : iconPathOverride;
|
||||
if (!iconPath.empty())
|
||||
{
|
||||
const auto icon = _CreateNewTabFlyoutIcon(iconPath);
|
||||
@@ -1269,7 +1122,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// If a custom icon path has been specified, set it as the icon for
|
||||
// this flyout item. Otherwise, if an icon is set for this action, set that icon
|
||||
// for this flyout item.
|
||||
const auto& iconPath = iconPathOverride.empty() ? action.Icon().Resolved() : iconPathOverride;
|
||||
const auto& iconPath = iconPathOverride.empty() ? action.IconPath() : iconPathOverride;
|
||||
if (!iconPath.empty())
|
||||
{
|
||||
const auto icon = _CreateNewTabFlyoutIcon(iconPath);
|
||||
@@ -1904,9 +1757,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: the Tab to update the title for.
|
||||
void TerminalPage::_UpdateTitle(const Tab& tab)
|
||||
{
|
||||
auto newTabTitle = tab.Title();
|
||||
|
||||
if (tab == _GetFocusedTab())
|
||||
{
|
||||
TitleChanged.raise(*this, nullptr);
|
||||
TitleChanged.raise(*this, newTabTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1921,7 +1776,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
term.RaiseNotice({ this, &TerminalPage::_ControlNoticeRaisedHandler });
|
||||
|
||||
term.WriteToClipboard({ get_weak(), &TerminalPage::_copyToClipboard });
|
||||
// Add an event handler when the terminal wants to paste data from the Clipboard.
|
||||
term.PasteFromClipboard({ this, &TerminalPage::_PasteFromClipboardHandler });
|
||||
|
||||
term.OpenHyperlink({ this, &TerminalPage::_OpenHyperlinkHandler });
|
||||
@@ -1943,7 +1798,9 @@ namespace winrt::TerminalApp::implementation
|
||||
});
|
||||
|
||||
term.ShowWindowChanged({ get_weak(), &TerminalPage::_ShowWindowChangedHandler });
|
||||
|
||||
term.SearchMissingCommand({ get_weak(), &TerminalPage::_SearchMissingCommandHandler });
|
||||
|
||||
term.WindowSizeChanged({ get_weak(), &TerminalPage::_WindowSizeChanged });
|
||||
|
||||
// Don't even register for the event if the feature is compiled off.
|
||||
@@ -2089,7 +1946,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return false;
|
||||
}
|
||||
|
||||
TermControl TerminalPage::_GetActiveControl() const
|
||||
TermControl TerminalPage::_GetActiveControl()
|
||||
{
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
@@ -2550,8 +2407,6 @@ namespace winrt::TerminalApp::implementation
|
||||
auto profile = tab->GetFocusedProfile();
|
||||
_UpdateBackground(profile);
|
||||
}
|
||||
|
||||
_adjustProcessPriorityThrottled->Run();
|
||||
}
|
||||
|
||||
uint32_t TerminalPage::NumberOfTabs() const
|
||||
@@ -2770,9 +2625,17 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (_settings.GlobalSettings().ShowTitleInTitlebar())
|
||||
{
|
||||
if (const auto tab{ _GetFocusedTab() })
|
||||
auto selectedIndex = _tabView.SelectedIndex();
|
||||
if (selectedIndex >= 0)
|
||||
{
|
||||
return tab.Title();
|
||||
try
|
||||
{
|
||||
if (auto focusedControl{ _GetActiveControl() })
|
||||
{
|
||||
return focusedControl.Title();
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
return { L"Terminal" };
|
||||
@@ -2867,6 +2730,75 @@ namespace winrt::TerminalApp::implementation
|
||||
return dimension;
|
||||
}
|
||||
|
||||
static wil::unique_close_clipboard_call _openClipboard(HWND hwnd)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// OpenClipboard may fail to acquire the internal lock --> retry.
|
||||
for (DWORD sleep = 10;; sleep *= 2)
|
||||
{
|
||||
if (OpenClipboard(hwnd))
|
||||
{
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
// 10 iterations
|
||||
if (sleep > 10000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(sleep);
|
||||
}
|
||||
|
||||
return wil::unique_close_clipboard_call{ success };
|
||||
}
|
||||
|
||||
static winrt::hstring _extractClipboard()
|
||||
{
|
||||
// This handles most cases of pasting text as the OS converts most formats to CF_UNICODETEXT automatically.
|
||||
if (const auto handle = GetClipboardData(CF_UNICODETEXT))
|
||||
{
|
||||
const wil::unique_hglobal_locked lock{ handle };
|
||||
const auto str = static_cast<const wchar_t*>(lock.get());
|
||||
if (!str)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto maxLen = GlobalSize(handle) / sizeof(wchar_t);
|
||||
const auto len = wcsnlen(str, maxLen);
|
||||
return winrt::hstring{ str, gsl::narrow_cast<uint32_t>(len) };
|
||||
}
|
||||
|
||||
// We get CF_HDROP when a user copied a file with Ctrl+C in Explorer and pastes that into the terminal (among others).
|
||||
if (const auto handle = GetClipboardData(CF_HDROP))
|
||||
{
|
||||
const wil::unique_hglobal_locked lock{ handle };
|
||||
const auto drop = static_cast<HDROP>(lock.get());
|
||||
if (!drop)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto cap = DragQueryFileW(drop, 0, nullptr, 0);
|
||||
if (cap == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto buffer = winrt::impl::hstring_builder{ cap };
|
||||
const auto len = DragQueryFileW(drop, 0, buffer.data(), cap + 1);
|
||||
if (len == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return buffer.to_hstring();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - This function is called when the `TermControl` requests that we send
|
||||
// it the clipboard's content.
|
||||
@@ -2886,51 +2818,36 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto weakThis = get_weak();
|
||||
const auto dispatcher = Dispatcher();
|
||||
const auto globalSettings = _settings.GlobalSettings();
|
||||
const auto bracketedPaste = eventArgs.BracketedPasteEnabled();
|
||||
|
||||
// GetClipboardData might block for up to 30s for delay-rendered contents.
|
||||
co_await winrt::resume_background();
|
||||
|
||||
winrt::hstring text;
|
||||
if (const auto clipboard = clipboard::open(nullptr))
|
||||
if (const auto clipboard = _openClipboard(nullptr))
|
||||
{
|
||||
text = clipboard::read();
|
||||
text = _extractClipboard();
|
||||
}
|
||||
|
||||
if (!bracketedPaste && globalSettings.TrimPaste())
|
||||
if (globalSettings.TrimPaste())
|
||||
{
|
||||
text = winrt::hstring{ Utils::TrimPaste(text) };
|
||||
}
|
||||
|
||||
if (text.empty())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
bool warnMultiLine = false;
|
||||
switch (globalSettings.WarnAboutMultiLinePaste())
|
||||
{
|
||||
case WarnAboutMultiLinePaste::Automatic:
|
||||
// NOTE that this is unsafe, because a shell that doesn't support bracketed paste
|
||||
// will allow an attacker to enable the mode, not realize that, and then accept
|
||||
// the paste as if it was a series of legitimate commands. See GH#13014.
|
||||
warnMultiLine = !bracketedPaste;
|
||||
break;
|
||||
case WarnAboutMultiLinePaste::Always:
|
||||
warnMultiLine = true;
|
||||
break;
|
||||
default:
|
||||
warnMultiLine = false;
|
||||
break;
|
||||
text = { Utils::TrimPaste(text) };
|
||||
if (text.empty())
|
||||
{
|
||||
// Text is all white space, nothing to paste
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
// If the requesting terminal is in bracketed paste mode, then we don't need to warn about a multi-line paste.
|
||||
auto warnMultiLine = globalSettings.WarnAboutMultiLinePaste() && !eventArgs.BracketedPasteEnabled();
|
||||
if (warnMultiLine)
|
||||
{
|
||||
const std::wstring_view view{ text };
|
||||
warnMultiLine = view.find_first_of(L"\r\n") != std::wstring_view::npos;
|
||||
const auto isNewLineLambda = [](auto c) { return c == L'\n' || c == L'\r'; };
|
||||
const auto hasNewLine = std::find_if(text.cbegin(), text.cend(), isNewLineLambda) != text.cend();
|
||||
warnMultiLine = hasNewLine;
|
||||
}
|
||||
|
||||
constexpr std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
|
||||
constexpr const std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
|
||||
const auto warnLargeText = text.size() > minimumSizeForWarning && globalSettings.WarnAboutLargePaste();
|
||||
|
||||
if (warnMultiLine || warnLargeText)
|
||||
@@ -2940,7 +2857,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
// We have to initialize the dialog here to be able to change the text of the text block within it
|
||||
std::ignore = FindName(L"MultiLinePasteDialog");
|
||||
FindName(L"MultiLinePasteDialog").try_as<WUX::Controls::ContentDialog>();
|
||||
ClipboardText().Text(text);
|
||||
|
||||
// The vertical offset on the scrollbar does not reset automatically, so reset it manually
|
||||
@@ -3121,7 +3038,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - formats: dictate which formats need to be copied
|
||||
// Return Value:
|
||||
// - true iff we we able to copy text (if a selection was active)
|
||||
bool TerminalPage::_CopyText(const bool dismissSelection, const bool singleLine, const bool withControlSequences, const CopyFormat formats)
|
||||
bool TerminalPage::_CopyText(const bool dismissSelection, const bool singleLine, const bool withControlSequences, const Windows::Foundation::IReference<CopyFormat>& formats)
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
@@ -3264,21 +3181,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_copyToClipboard(const IInspectable, const WriteToClipboardEventArgs args) const
|
||||
{
|
||||
if (const auto clipboard = clipboard::open(_hostingHwnd.value_or(nullptr)))
|
||||
{
|
||||
const auto plain = args.Plain();
|
||||
const auto html = args.Html();
|
||||
const auto rtf = args.Rtf();
|
||||
|
||||
clipboard::write(
|
||||
{ plain.data(), plain.size() },
|
||||
{ reinterpret_cast<const char*>(html.data()), html.size() },
|
||||
{ reinterpret_cast<const char*>(rtf.data()), rtf.size() });
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Paste text from the Windows Clipboard to the focused terminal
|
||||
void TerminalPage::_PasteText()
|
||||
@@ -3669,7 +3571,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
const auto path = newAppearance.BackgroundImagePath().Resolved();
|
||||
const auto path = newAppearance.ExpandedBackgroundImagePath();
|
||||
if (path.empty())
|
||||
{
|
||||
_tabContent.Background(nullptr);
|
||||
@@ -3734,7 +3636,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// updating terminal panes, so that we don't have to build a _new_
|
||||
// TerminalSettings for every profile we update - we can just look them
|
||||
// up the previous ones we built.
|
||||
_terminalSettingsCache->Reset(_settings, *_bindings);
|
||||
_terminalSettingsCache.Reset(_settings, *_bindings);
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
@@ -3792,9 +3694,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_updateThemeColors();
|
||||
|
||||
_updateAllTabCloseButtons();
|
||||
|
||||
// The user may have changed the "show title in titlebar" setting.
|
||||
TitleChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPage::_updateAllTabCloseButtons()
|
||||
@@ -4005,18 +3904,36 @@ namespace winrt::TerminalApp::implementation
|
||||
// and the non-client are behind it
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_SetNewTabButtonColor(const til::color color, const til::color accentColor)
|
||||
void TerminalPage::_SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor)
|
||||
{
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
// TODO GH#3327: Look at what to do with the tab button when we have XAML theming
|
||||
const auto IsBrightColor = ColorFix::GetLightness(color) >= lightnessThreshold;
|
||||
const auto isLightAccentColor = ColorFix::GetLightness(accentColor) >= lightnessThreshold;
|
||||
const auto hoverColorAdjustment = isLightAccentColor ? -0.05f : 0.05f;
|
||||
const auto pressedColorAdjustment = isLightAccentColor ? -0.1f : 0.1f;
|
||||
auto IsBrightColor = ColorHelper::IsBrightColor(color);
|
||||
auto isLightAccentColor = ColorHelper::IsBrightColor(accentColor);
|
||||
winrt::Windows::UI::Color pressedColor{};
|
||||
winrt::Windows::UI::Color hoverColor{};
|
||||
winrt::Windows::UI::Color foregroundColor{};
|
||||
const auto hoverColorAdjustment = 5.f;
|
||||
const auto pressedColorAdjustment = 7.f;
|
||||
|
||||
const auto foregroundColor = IsBrightColor ? Colors::Black() : Colors::White();
|
||||
const auto hoverColor = til::color{ ColorFix::AdjustLightness(accentColor, hoverColorAdjustment) };
|
||||
const auto pressedColor = til::color{ ColorFix::AdjustLightness(accentColor, pressedColorAdjustment) };
|
||||
if (IsBrightColor)
|
||||
{
|
||||
foregroundColor = winrt::Windows::UI::Colors::Black();
|
||||
}
|
||||
else
|
||||
{
|
||||
foregroundColor = winrt::Windows::UI::Colors::White();
|
||||
}
|
||||
|
||||
if (isLightAccentColor)
|
||||
{
|
||||
hoverColor = ColorHelper::Darken(accentColor, hoverColorAdjustment);
|
||||
pressedColor = ColorHelper::Darken(accentColor, pressedColorAdjustment);
|
||||
}
|
||||
else
|
||||
{
|
||||
hoverColor = ColorHelper::Lighten(accentColor, hoverColorAdjustment);
|
||||
pressedColor = ColorHelper::Lighten(accentColor, pressedColorAdjustment);
|
||||
}
|
||||
|
||||
Media::SolidColorBrush backgroundBrush{ accentColor };
|
||||
Media::SolidColorBrush backgroundHoverBrush{ hoverColor };
|
||||
@@ -4684,12 +4601,9 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto coreState{ sender.try_as<winrt::Microsoft::Terminal::Control::ICoreState>() })
|
||||
{
|
||||
const auto newConnectionState = coreState.ConnectionState();
|
||||
co_await wil::resume_foreground(Dispatcher());
|
||||
|
||||
_adjustProcessPriorityThrottled->Run();
|
||||
|
||||
if (newConnectionState == ConnectionState::Failed && !_IsMessageDismissed(InfoBarMessage::CloseOnExitInfo))
|
||||
{
|
||||
co_await wil::resume_foreground(Dispatcher());
|
||||
if (const auto infoBar = FindName(L"CloseOnExitInfoBar").try_as<MUX::Controls::InfoBar>())
|
||||
{
|
||||
infoBar.IsOpen(true);
|
||||
@@ -4954,94 +4868,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_adjustProcessPriority() const
|
||||
{
|
||||
// Windowing is single-threaded, so this will not cause a race condition.
|
||||
static bool supported{ true };
|
||||
|
||||
if (!supported || !_hostingHwnd.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<HANDLE, 32> processes;
|
||||
auto it = processes.begin();
|
||||
const auto end = processes.end();
|
||||
|
||||
auto&& appendFromControl = [&](auto&& control) {
|
||||
if (it == end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (control)
|
||||
{
|
||||
if (const auto conn{ control.Connection() })
|
||||
{
|
||||
if (const auto pty{ conn.try_as<winrt::Microsoft::Terminal::TerminalConnection::ConptyConnection>() })
|
||||
{
|
||||
if (const uint64_t process{ pty.RootProcessHandle() }; process != 0)
|
||||
{
|
||||
*it++ = reinterpret_cast<HANDLE>(process);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto&& appendFromTab = [&](auto&& tabImpl) {
|
||||
if (const auto pane{ tabImpl->GetRootPane() })
|
||||
{
|
||||
pane->WalkTree([&](auto&& child) {
|
||||
if (const auto& control{ child->GetTerminalControl() })
|
||||
{
|
||||
appendFromControl(control);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (!_activated)
|
||||
{
|
||||
// When a window is out of focus, we want to attach all of the processes
|
||||
// under it to the window so they all go into the background at the same time.
|
||||
for (auto&& tab : _tabs)
|
||||
{
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
appendFromTab(tabImpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When a window is in focus, propagate our foreground boost (if we have one)
|
||||
// to current all panes in the current tab.
|
||||
if (auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
appendFromTab(tabImpl);
|
||||
}
|
||||
}
|
||||
|
||||
const auto count{ gsl::narrow_cast<DWORD>(it - processes.begin()) };
|
||||
const auto hr = TerminalTrySetWindowAssociatedProcesses(_hostingHwnd.value(), count, count ? processes.data() : nullptr);
|
||||
if (S_FALSE == hr)
|
||||
{
|
||||
// Don't bother trying again or logging. The wrapper tells us it's unsupported.
|
||||
supported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"CalledNewQoSAPI",
|
||||
TraceLoggingValue(reinterpret_cast<uintptr_t>(_hostingHwnd.value()), "hwnd"),
|
||||
TraceLoggingValue(count),
|
||||
TraceLoggingHResult(hr));
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringW(fmt::format(FMT_COMPILE(L"Submitted {} processes to TerminalTrySetWindowAssociatedProcesses; return=0x{:08x}\n"), count, hr).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void TerminalPage::WindowActivated(const bool activated)
|
||||
{
|
||||
// Stash if we're activated. Use that when we reload
|
||||
@@ -5049,8 +4875,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_activated = activated;
|
||||
_updateThemeColors();
|
||||
|
||||
_adjustProcessPriorityThrottled->Run();
|
||||
|
||||
if (const auto& tab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (tab->TabStatus().IsInputBroadcastActive())
|
||||
@@ -5070,6 +4894,8 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine TerminalPage::_ControlCompletionsChangedHandler(const IInspectable sender,
|
||||
const CompletionsChangedEventArgs args)
|
||||
{
|
||||
// This will come in on a background (not-UI, not output) thread.
|
||||
|
||||
// This won't even get hit if the velocity flag is disabled - we gate
|
||||
// registering for the event based off of
|
||||
// Feature_ShellCompletions::IsEnabled back in _RegisterTerminalEvents
|
||||
@@ -5243,7 +5069,7 @@ namespace winrt::TerminalApp::implementation
|
||||
makeItem(RS_(L"DuplicateTabText"), L"\xF5ED", ActionAndArgs{ ShortcutAction::DuplicateTab, nullptr }, menu);
|
||||
|
||||
const auto focusedProfileName = focusedProfile.Name();
|
||||
const auto focusedProfileIcon = focusedProfile.Icon().Resolved();
|
||||
const auto focusedProfileIcon = focusedProfile.Icon();
|
||||
const auto splitPaneDuplicateText = RS_(L"SplitPaneDuplicateText") + L" " + focusedProfileName; // SplitPaneDuplicateText
|
||||
|
||||
const auto splitPaneRightText = RS_(L"SplitPaneRightText");
|
||||
@@ -5269,7 +5095,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
const auto profile = activeProfiles.GetAt(profileIndex);
|
||||
const auto profileName = profile.Name();
|
||||
const auto profileIcon = profile.Icon().Resolved();
|
||||
const auto profileIcon = profile.Icon();
|
||||
|
||||
NewTerminalArgs args{};
|
||||
args.Profile(profileName);
|
||||
@@ -5304,22 +5130,22 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Down, mruPanes))
|
||||
{
|
||||
makeItem(RS_(L"SwapPaneDownText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Down } }, swapPaneMenu);
|
||||
makeItem(RS_(L"SwapPaneDownText"), neighbor->GetProfile().Icon(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Down } }, swapPaneMenu);
|
||||
}
|
||||
|
||||
if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Right, mruPanes))
|
||||
{
|
||||
makeItem(RS_(L"SwapPaneRightText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Right } }, swapPaneMenu);
|
||||
makeItem(RS_(L"SwapPaneRightText"), neighbor->GetProfile().Icon(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Right } }, swapPaneMenu);
|
||||
}
|
||||
|
||||
if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Up, mruPanes))
|
||||
{
|
||||
makeItem(RS_(L"SwapPaneUpText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Up } }, swapPaneMenu);
|
||||
makeItem(RS_(L"SwapPaneUpText"), neighbor->GetProfile().Icon(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Up } }, swapPaneMenu);
|
||||
}
|
||||
|
||||
if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Left, mruPanes))
|
||||
{
|
||||
makeItem(RS_(L"SwapPaneLeftText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Left } }, swapPaneMenu);
|
||||
makeItem(RS_(L"SwapPaneLeftText"), neighbor->GetProfile().Icon(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Left } }, swapPaneMenu);
|
||||
}
|
||||
|
||||
makeMenuItem(RS_(L"SwapPaneText"), L"\xF1CB", swapPaneMenu, menu);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ThrottledFunc.h>
|
||||
|
||||
#include "TerminalPage.g.h"
|
||||
#include "Tab.h"
|
||||
#include "AppKeyBindings.h"
|
||||
@@ -31,8 +29,6 @@ namespace Microsoft::Terminal::Core
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalSettingsCache;
|
||||
|
||||
inline constexpr uint32_t DefaultRowsToScroll{ 3 };
|
||||
inline constexpr std::wstring_view TabletInputServiceKey{ L"TabletInputService" };
|
||||
|
||||
@@ -153,7 +149,7 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine ProcessStartupActions(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> actions,
|
||||
const winrt::hstring cwd = winrt::hstring{},
|
||||
const winrt::hstring env = winrt::hstring{});
|
||||
safe_void_coroutine CreateTabFromConnection(winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection connection);
|
||||
void CreateTabFromConnection(winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection connection);
|
||||
|
||||
TerminalApp::WindowProperties WindowProperties() const noexcept { return _WindowProperties; };
|
||||
|
||||
@@ -173,7 +169,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
til::typed_event<IInspectable, IInspectable> TitleChanged;
|
||||
til::typed_event<IInspectable, winrt::hstring> TitleChanged;
|
||||
til::typed_event<IInspectable, IInspectable> CloseWindowRequested;
|
||||
til::typed_event<IInspectable, winrt::Windows::UI::Xaml::UIElement> SetTitleBarContent;
|
||||
til::typed_event<IInspectable, IInspectable> FocusModeChanged;
|
||||
@@ -277,7 +273,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::ContentManager _manager{ nullptr };
|
||||
|
||||
std::shared_ptr<TerminalSettingsCache> _terminalSettingsCache{};
|
||||
TerminalApp::TerminalSettingsCache _terminalSettingsCache{ nullptr };
|
||||
|
||||
struct StashedDragData
|
||||
{
|
||||
@@ -363,11 +359,8 @@ namespace winrt::TerminalApp::implementation
|
||||
bool _MovePane(const Microsoft::Terminal::Settings::Model::MovePaneArgs args);
|
||||
bool _MoveTab(winrt::com_ptr<Tab> tab, const Microsoft::Terminal::Settings::Model::MoveTabArgs args);
|
||||
|
||||
std::shared_ptr<ThrottledFunc<>> _adjustProcessPriorityThrottled;
|
||||
void _adjustProcessPriority() const;
|
||||
|
||||
template<typename F>
|
||||
bool _ApplyToActiveControls(F f) const
|
||||
bool _ApplyToActiveControls(F f)
|
||||
{
|
||||
if (const auto tab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
@@ -386,7 +379,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return false;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _GetActiveControl() const;
|
||||
winrt::Microsoft::Terminal::Control::TermControl _GetActiveControl();
|
||||
std::optional<uint32_t> _GetFocusedTabIndex() const noexcept;
|
||||
std::optional<uint32_t> _GetTabIndex(const TerminalApp::Tab& tab) const noexcept;
|
||||
TerminalApp::Tab _GetFocusedTab() const noexcept;
|
||||
@@ -420,11 +413,10 @@ namespace winrt::TerminalApp::implementation
|
||||
bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
|
||||
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
|
||||
bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats);
|
||||
bool _CopyText(const bool dismissSelection, const bool singleLine, const bool withControlSequences, const Windows::Foundation::IReference<Microsoft::Terminal::Control::CopyFormat>& formats);
|
||||
|
||||
safe_void_coroutine _SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs);
|
||||
|
||||
void _copyToClipboard(IInspectable, Microsoft::Terminal::Control::WriteToClipboardEventArgs args) const;
|
||||
void _PasteText();
|
||||
|
||||
safe_void_coroutine _ControlNoticeRaisedHandler(const IInspectable sender, const Microsoft::Terminal::Control::NoticeEventArgs eventArgs);
|
||||
@@ -471,7 +463,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _RefreshUIForSettingsReload();
|
||||
|
||||
void _SetNewTabButtonColor(til::color color, til::color accentColor);
|
||||
void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor);
|
||||
void _ClearNewTabButtonColor();
|
||||
|
||||
safe_void_coroutine _CompleteInitialization();
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace TerminalApp
|
||||
void WindowActivated(Boolean activated);
|
||||
void SendContentToOther(RequestReceiveContentArgs args);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CloseWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "TerminalSettingsCache.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include "BellEventArgs.g.cpp"
|
||||
@@ -21,7 +20,7 @@ using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TerminalPaneContent::TerminalPaneContent(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
|
||||
const std::shared_ptr<TerminalSettingsCache>& cache,
|
||||
const TerminalApp::TerminalSettingsCache& cache,
|
||||
const winrt::Microsoft::Terminal::Control::TermControl& control) :
|
||||
_control{ control },
|
||||
_cache{ cache },
|
||||
@@ -83,7 +82,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::hstring TerminalPaneContent::Icon() const
|
||||
{
|
||||
return _profile.Icon().Resolved();
|
||||
return _profile.EvaluatedIcon();
|
||||
}
|
||||
|
||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TerminalPaneContent::TabColor() const noexcept
|
||||
@@ -341,13 +340,9 @@ namespace winrt::TerminalApp::implementation
|
||||
RestartTerminalRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPaneContent::UpdateSettings(const CascadiaSettings& settings)
|
||||
void TerminalPaneContent::UpdateSettings(const CascadiaSettings& /*settings*/)
|
||||
{
|
||||
// Reload our profile from the settings model to propagate bell mode, icon, and close on exit mode (anything that uses _profile).
|
||||
const auto profile{ settings.FindProfile(_profile.Guid()) };
|
||||
_profile = profile ? profile : settings.ProfileDefaults();
|
||||
|
||||
if (const auto& settings{ _cache->TryLookup(_profile) })
|
||||
if (const auto& settings{ _cache.TryLookup(_profile) })
|
||||
{
|
||||
_control.UpdateControlSettings(settings.DefaultSettings(), settings.UnfocusedSettings());
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalSettingsCache;
|
||||
|
||||
struct BellEventArgs : public BellEventArgsT<BellEventArgs>
|
||||
{
|
||||
public:
|
||||
@@ -22,7 +20,7 @@ namespace winrt::TerminalApp::implementation
|
||||
struct TerminalPaneContent : TerminalPaneContentT<TerminalPaneContent>, BasicPaneEvents
|
||||
{
|
||||
TerminalPaneContent(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
|
||||
const std::shared_ptr<TerminalSettingsCache>& cache,
|
||||
const TerminalApp::TerminalSettingsCache& cache,
|
||||
const winrt::Microsoft::Terminal::Control::TermControl& control);
|
||||
|
||||
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
|
||||
@@ -61,7 +59,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr };
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
|
||||
std::shared_ptr<TerminalSettingsCache> _cache{};
|
||||
TerminalApp::TerminalSettingsCache _cache{ nullptr };
|
||||
bool _isDefTermSession{ false };
|
||||
|
||||
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "IPaneContent.idl";
|
||||
import "TerminalSettingsCache.idl";
|
||||
import "FilteredCommand.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalSettingsCache.h"
|
||||
#include "TerminalSettingsCache.g.cpp"
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
|
||||
@@ -13,13 +13,14 @@ Abstract:
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "winrt/Microsoft.Terminal.Settings.Model.h"
|
||||
#include "winrt/TerminalApp.h"
|
||||
#include "TerminalSettingsCache.g.h"
|
||||
#include <inc/cppwinrt_utils.h>
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalSettingsCache
|
||||
class TerminalSettingsCache : public TerminalSettingsCacheT<TerminalSettingsCache>
|
||||
{
|
||||
public:
|
||||
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const TerminalApp::AppKeyBindings& bindings);
|
||||
Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult TryLookup(const Microsoft::Terminal::Settings::Model::Profile& profile);
|
||||
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const TerminalApp::AppKeyBindings& bindings);
|
||||
@@ -30,3 +31,8 @@ namespace winrt::TerminalApp::implementation
|
||||
std::unordered_map<winrt::guid, std::pair<Microsoft::Terminal::Settings::Model::Profile, Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult>> profileGuidSettingsMap;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(TerminalSettingsCache);
|
||||
}
|
||||
|
||||
13
src/cascadia/TerminalApp/TerminalSettingsCache.idl
Normal file
13
src/cascadia/TerminalApp/TerminalSettingsCache.idl
Normal file
@@ -0,0 +1,13 @@
|
||||
import "AppKeyBindings.idl";
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass TerminalSettingsCache
|
||||
{
|
||||
TerminalSettingsCache(Microsoft.Terminal.Settings.Model.CascadiaSettings settings, AppKeyBindings bindings);
|
||||
Microsoft.Terminal.Settings.Model.TerminalSettingsCreateResult TryLookup(Microsoft.Terminal.Settings.Model.Profile profile);
|
||||
void Reset(Microsoft.Terminal.Settings.Model.CascadiaSettings settings, AppKeyBindings bindings);
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,8 @@ static const std::array settingsLoadWarningsLabels{
|
||||
USES_RESOURCE(L"MissingDefaultProfileText"),
|
||||
USES_RESOURCE(L"DuplicateProfileText"),
|
||||
USES_RESOURCE(L"UnknownColorSchemeText"),
|
||||
USES_RESOURCE(L"InvalidMediaResource"),
|
||||
USES_RESOURCE(L"InvalidBackgroundImage"),
|
||||
USES_RESOURCE(L"InvalidIcon"),
|
||||
USES_RESOURCE(L"AtLeastOneKeybindingWarning"),
|
||||
USES_RESOURCE(L"TooManyKeysForChord"),
|
||||
USES_RESOURCE(L"MissingRequiredParameter"),
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, Initialized);
|
||||
|
||||
FORWARDED_TYPED_EVENT(SetTitleBarContent, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement, _root, SetTitleBarContent);
|
||||
FORWARDED_TYPED_EVENT(TitleChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, TitleChanged);
|
||||
FORWARDED_TYPED_EVENT(TitleChanged, winrt::Windows::Foundation::IInspectable, winrt::hstring, _root, TitleChanged);
|
||||
FORWARDED_TYPED_EVENT(CloseWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, CloseWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(FocusModeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FocusModeChanged);
|
||||
FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged);
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> Initialized;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CloseWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Theme> RequestedThemeChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "TitlebarControl.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
|
||||
#include "ColorHelper.h"
|
||||
|
||||
#include "TitlebarControl.g.cpp"
|
||||
|
||||
@@ -188,8 +189,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
const auto isBrightColor = ColorFix::GetLightness(c) >= lightnessThreshold;
|
||||
const auto isBrightColor = ColorHelper::IsBrightColor(c);
|
||||
MinMaxCloseControl().RequestedTheme(isBrightColor ? winrt::Windows::UI::Xaml::ElementTheme::Light :
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Dark);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
<TerminalThemeHelpers>true</TerminalThemeHelpers>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
|
||||
@@ -30,7 +30,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
// Function Description:
|
||||
// - launches the client application attached to the new pseudoconsole
|
||||
void ConptyConnection::_LaunchAttachedClient()
|
||||
HRESULT ConptyConnection::_LaunchAttachedClient() noexcept
|
||||
try
|
||||
{
|
||||
STARTUPINFOEX siEx{ 0 };
|
||||
siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
|
||||
@@ -42,16 +43,15 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
auto attrList{ std::make_unique<std::byte[]>(size) };
|
||||
#pragma warning(suppress : 26490) // We have to use reinterpret_cast because we allocated a byte array as a proxy for the adjustable size list.
|
||||
siEx.lpAttributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(attrList.get());
|
||||
THROW_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &size));
|
||||
RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &size));
|
||||
|
||||
THROW_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(
|
||||
siEx.lpAttributeList,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
|
||||
_hPC.get(),
|
||||
sizeof(HPCON),
|
||||
nullptr,
|
||||
nullptr));
|
||||
RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
|
||||
_hPC.get(),
|
||||
sizeof(HPCON),
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
auto cmdline{ wil::ExpandEnvironmentStringsW<std::wstring>(_commandline.c_str()) }; // mutable copy -- required for CreateProcessW
|
||||
auto environment = _initialEnv;
|
||||
@@ -66,87 +66,37 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
// WSLENV is a colon-delimited list of environment variables (+flags) that should appear inside WSL
|
||||
// https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/
|
||||
|
||||
// WSLENV.1: Get a handle to the WSLENV environment variable.
|
||||
auto& wslEnv = environment.as_map()[L"WSLENV"];
|
||||
std::wstring additionalWslEnv;
|
||||
|
||||
// WSLENV.2: Figure out what variables are already in WSLENV.
|
||||
std::unordered_set<std::wstring> wslEnvVars{
|
||||
// We never want to put a custom Windows PATH variable into WSLENV,
|
||||
// because that would override WSL's computation of the NIX PATH.
|
||||
L"PATH",
|
||||
};
|
||||
for (const auto& part : til::split_iterator{ std::wstring_view{ wslEnv }, L':' })
|
||||
{
|
||||
// Each part may contain a variable name and flags (e.g., /p, /l, etc.)
|
||||
// We only care about the variable name for WSLENV.
|
||||
const auto key = til::safe_slice_len(part, 0, part.rfind(L'/'));
|
||||
wslEnvVars.emplace(key);
|
||||
}
|
||||
|
||||
// WSLENV.3: Add our terminal-specific environment variables to WSLENV.
|
||||
static constexpr std::wstring_view builtinWslEnvVars[] = {
|
||||
L"WT_SESSION",
|
||||
L"WT_PROFILE_ID",
|
||||
};
|
||||
// Misdiagnosis in MSVC 14.44.35207. No pointer arithmetic in sight.
|
||||
#pragma warning(suppress : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
|
||||
for (const auto& key : builtinWslEnvVars)
|
||||
{
|
||||
if (wslEnvVars.emplace(key).second)
|
||||
{
|
||||
additionalWslEnv.append(key);
|
||||
additionalWslEnv.push_back(L':');
|
||||
}
|
||||
}
|
||||
|
||||
// add additional env vars
|
||||
std::wstring wslEnv{ L"WT_SESSION:WT_PROFILE_ID:" };
|
||||
if (_environment)
|
||||
{
|
||||
// Order the environment variable names so that resolution order is consistent
|
||||
std::set<std::wstring, til::env_key_sorter> keys{};
|
||||
for (const auto item : _environment)
|
||||
{
|
||||
keys.insert(std::wstring{ item.Key() });
|
||||
}
|
||||
// add additional env vars
|
||||
for (const auto& key : keys)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto key = item.Key();
|
||||
// This will throw if the value isn't a string. If that
|
||||
// happens, then just skip this entry.
|
||||
const auto value = winrt::unbox_value<hstring>(_environment.Lookup(key));
|
||||
|
||||
environment.set_user_environment_var(key, value);
|
||||
|
||||
// WSLENV.4: Add custom user environment variables to WSLENV.
|
||||
if (wslEnvVars.emplace(key).second)
|
||||
{
|
||||
additionalWslEnv.append(key);
|
||||
additionalWslEnv.push_back(L':');
|
||||
}
|
||||
environment.set_user_environment_var(key.c_str(), value.c_str());
|
||||
// For each environment variable added to the environment, also add it to WSLENV
|
||||
wslEnv += key + L":";
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
|
||||
if (!additionalWslEnv.empty())
|
||||
{
|
||||
// WSLENV.5: In the next step we'll prepend `additionalWslEnv` to `wslEnv`,
|
||||
// so make sure that we have a single colon in between them.
|
||||
const auto hasColon = additionalWslEnv.ends_with(L':');
|
||||
const auto needsColon = !wslEnv.starts_with(L':');
|
||||
if (hasColon != needsColon)
|
||||
{
|
||||
if (hasColon)
|
||||
{
|
||||
additionalWslEnv.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
additionalWslEnv.push_back(L':');
|
||||
}
|
||||
}
|
||||
|
||||
// WSLENV.6: Prepend our additional environment variables to WSLENV.
|
||||
wslEnv.insert(0, additionalWslEnv);
|
||||
}
|
||||
// We want to prepend new environment variables to WSLENV - that way if a variable already
|
||||
// exists in WSLENV but with a flag, the flag will be respected.
|
||||
// (This behaviour was empirically observed)
|
||||
wslEnv += environment.as_map()[L"WSLENV"];
|
||||
environment.as_map().insert_or_assign(L"WSLENV", wslEnv);
|
||||
}
|
||||
|
||||
auto newEnvVars = environment.to_string();
|
||||
@@ -164,7 +114,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
auto [newCommandLine, newStartingDirectory] = Utils::MangleStartingDirectoryForWSL(cmdline, _startingDirectory);
|
||||
const auto startingDirectory = newStartingDirectory.size() > 0 ? newStartingDirectory.c_str() : nullptr;
|
||||
|
||||
THROW_IF_WIN32_BOOL_FALSE(CreateProcessW(
|
||||
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(
|
||||
nullptr,
|
||||
newCommandLine.data(),
|
||||
nullptr, // lpProcessAttributes
|
||||
@@ -191,7 +141,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
TraceLoggingWideString(_clientName.c_str(), "Client", "The attached client process"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
// Who decided that?
|
||||
#pragma warning(suppress : 26455) // Default constructor should not throw. Declare it 'noexcept' (f.6).
|
||||
@@ -340,13 +293,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
auto ownedSignal = duplicateHandle(signal);
|
||||
auto ownedReference = duplicateHandle(reference);
|
||||
auto ownedServer = duplicateHandle(server);
|
||||
wil::unique_hfile ownedClient;
|
||||
LOG_IF_WIN32_BOOL_FALSE(DuplicateHandle(GetCurrentProcess(), client, GetCurrentProcess(), ownedClient.addressof(), PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_SET_INFORMATION | SYNCHRONIZE, FALSE, 0));
|
||||
if (!ownedClient)
|
||||
{
|
||||
// If we couldn't reopen the handle with SET_INFORMATION, which may be required to do things like QoS management, fall back.
|
||||
ownedClient = duplicateHandle(client);
|
||||
}
|
||||
auto ownedClient = duplicateHandle(client);
|
||||
|
||||
THROW_IF_FAILED(ConptyPackPseudoConsole(ownedServer.get(), ownedReference.get(), ownedSignal.get(), &_hPC));
|
||||
ownedServer.release();
|
||||
@@ -419,7 +366,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
THROW_IF_FAILED(ConptyShowHidePseudoConsole(_hPC.get(), _initialVisibility));
|
||||
}
|
||||
|
||||
_LaunchAttachedClient();
|
||||
THROW_IF_FAILED(_LaunchAttachedClient());
|
||||
}
|
||||
// But if it was an inbound handoff... attempt to synchronize the size of it with what our connection
|
||||
// window is expecting it to be on the first layout.
|
||||
@@ -539,8 +486,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
DWORD exitCode{ 0 };
|
||||
GetExitCodeProcess(_piClient.hProcess, &exitCode);
|
||||
|
||||
_piClient.reset();
|
||||
|
||||
// Signal the closing or failure of the process.
|
||||
// exitCode might be STILL_ACTIVE if a client has called FreeConsole() and
|
||||
// thus caused the tab to close, even though the CLI app is still running.
|
||||
@@ -657,12 +602,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ConptyConnection::RootProcessHandle() noexcept
|
||||
{
|
||||
#pragma warning(disable : 26490) // Don't use reinterpret_cast (type.1).
|
||||
return reinterpret_cast<uint64_t>(_piClient.hProcess);
|
||||
}
|
||||
|
||||
void ConptyConnection::Close() noexcept
|
||||
try
|
||||
{
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
void ShowHide(const bool show);
|
||||
|
||||
void ReparentWindow(const uint64_t newParent);
|
||||
uint64_t RootProcessHandle() noexcept;
|
||||
|
||||
winrt::hstring Commandline() const;
|
||||
winrt::hstring StartingTitle() const;
|
||||
@@ -59,7 +58,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
static HRESULT NewHandoff(HANDLE* in, HANDLE* out, HANDLE signal, HANDLE reference, HANDLE server, HANDLE client, const TERMINAL_STARTUP_INFO* startupInfo) noexcept;
|
||||
static winrt::hstring _commandlineFromProcess(HANDLE process);
|
||||
|
||||
void _LaunchAttachedClient();
|
||||
HRESULT _LaunchAttachedClient() noexcept;
|
||||
void _indicateExitWithStatus(unsigned int status) noexcept;
|
||||
static std::wstring _formatStatus(uint32_t status);
|
||||
void _LastConPtyClientDisconnected() noexcept;
|
||||
|
||||
@@ -21,8 +21,6 @@ namespace Microsoft.Terminal.TerminalConnection
|
||||
|
||||
void ReparentWindow(UInt64 newParent);
|
||||
|
||||
UInt64 RootProcessHandle();
|
||||
|
||||
static event NewConnectionHandler NewConnection;
|
||||
static void StartInboundListener();
|
||||
|
||||
|
||||
@@ -104,9 +104,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// GH#8969: pre-seed working directory to prevent potential races
|
||||
_terminal->SetWorkingDirectory(_settings->StartingDirectory());
|
||||
|
||||
_terminal->SetCopyToClipboardCallback([this](wil::zwstring_view wstr) {
|
||||
WriteToClipboard.raise(*this, winrt::make<WriteToClipboardEventArgs>(winrt::hstring{ std::wstring_view{ wstr } }, std::string{}, std::string{}));
|
||||
});
|
||||
auto pfnCopyToClipboard = [this](auto&& PH1) { _terminalCopyToClipboard(std::forward<decltype(PH1)>(PH1)); };
|
||||
_terminal->SetCopyToClipboardCallback(pfnCopyToClipboard);
|
||||
|
||||
auto pfnWarningBell = [this] { _terminalWarningBell(); };
|
||||
_terminal->SetWarningBellCallback(pfnWarningBell);
|
||||
@@ -175,12 +174,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
//
|
||||
// NOTE: Calling UpdatePatternLocations from a background
|
||||
// thread is a workaround for us to hit GH#12607 less often.
|
||||
shared->outputIdle = std::make_unique<til::throttled_func<>>(
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 100 },
|
||||
.debounce = true,
|
||||
.trailing = true,
|
||||
},
|
||||
shared->outputIdle = std::make_unique<til::debounced_func_trailing<>>(
|
||||
std::chrono::milliseconds{ 100 },
|
||||
[this, weakThis = get_weak(), dispatcher = _dispatcher]() {
|
||||
dispatcher.TryEnqueue(DispatcherQueuePriority::Normal, [weakThis]() {
|
||||
if (const auto self = weakThis.get(); self && !self->_IsClosing())
|
||||
@@ -200,12 +195,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// If you rapidly show/hide Windows Terminal, something about GotFocus()/LostFocus() gets broken.
|
||||
// We'll then receive easily 10+ such calls from WinUI the next time the application is shown.
|
||||
shared->focusChanged = std::make_unique<til::throttled_func<bool>>(
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 25 },
|
||||
.debounce = true,
|
||||
.trailing = true,
|
||||
},
|
||||
shared->focusChanged = std::make_unique<til::debounced_func_trailing<bool>>(
|
||||
std::chrono::milliseconds{ 25 },
|
||||
[this](const bool focused) {
|
||||
// Theoretically `debounced_func_trailing` should call `WaitForThreadpoolTimerCallbacks()`
|
||||
// with cancel=true on destruction, which should ensure that our use of `this` here is safe.
|
||||
@@ -213,12 +204,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
});
|
||||
|
||||
// Scrollbar updates are also expensive (XAML), so we'll throttle them as well.
|
||||
shared->updateScrollBar = std::make_shared<ThrottledFunc<Control::ScrollPositionChangedArgs>>(
|
||||
shared->updateScrollBar = std::make_shared<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>>(
|
||||
_dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = std::chrono::milliseconds{ 8 },
|
||||
.trailing = true,
|
||||
},
|
||||
std::chrono::milliseconds{ 8 },
|
||||
[weakThis = get_weak()](const auto& update) {
|
||||
if (auto core{ weakThis.get() }; core && !core->_IsClosing())
|
||||
{
|
||||
@@ -600,7 +588,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
else if (vkey == VK_RETURN && !mods.IsCtrlPressed() && !mods.IsAltPressed())
|
||||
{
|
||||
// [Shift +] Enter --> copy text
|
||||
CopySelectionToClipboard(mods.IsShiftPressed(), false, _settings->CopyFormatting());
|
||||
CopySelectionToClipboard(mods.IsShiftPressed(), false, nullptr);
|
||||
_terminal->ClearSelection();
|
||||
_updateSelectionUI();
|
||||
return true;
|
||||
@@ -1264,6 +1252,89 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_updateSelectionUI();
|
||||
}
|
||||
|
||||
static wil::unique_close_clipboard_call _openClipboard(HWND hwnd)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// OpenClipboard may fail to acquire the internal lock --> retry.
|
||||
for (DWORD sleep = 10;; sleep *= 2)
|
||||
{
|
||||
if (OpenClipboard(hwnd))
|
||||
{
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
// 10 iterations
|
||||
if (sleep > 10000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(sleep);
|
||||
}
|
||||
|
||||
return wil::unique_close_clipboard_call{ success };
|
||||
}
|
||||
|
||||
static void _copyToClipboard(const UINT format, const void* src, const size_t bytes)
|
||||
{
|
||||
wil::unique_hglobal handle{ THROW_LAST_ERROR_IF_NULL(GlobalAlloc(GMEM_MOVEABLE, bytes)) };
|
||||
|
||||
const auto locked = GlobalLock(handle.get());
|
||||
memcpy(locked, src, bytes);
|
||||
GlobalUnlock(handle.get());
|
||||
|
||||
THROW_LAST_ERROR_IF_NULL(SetClipboardData(format, handle.get()));
|
||||
handle.release();
|
||||
}
|
||||
|
||||
static void _copyToClipboardRegisteredFormat(const wchar_t* format, const void* src, size_t bytes)
|
||||
{
|
||||
const auto id = RegisterClipboardFormatW(format);
|
||||
if (!id)
|
||||
{
|
||||
LOG_LAST_ERROR();
|
||||
return;
|
||||
}
|
||||
_copyToClipboard(id, src, bytes);
|
||||
}
|
||||
|
||||
static void copyToClipboard(wil::zwstring_view text, std::string_view html, std::string_view rtf)
|
||||
{
|
||||
const auto clipboard = _openClipboard(nullptr);
|
||||
if (!clipboard)
|
||||
{
|
||||
LOG_LAST_ERROR();
|
||||
return;
|
||||
}
|
||||
|
||||
EmptyClipboard();
|
||||
|
||||
if (!text.empty())
|
||||
{
|
||||
// As per: https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
|
||||
// CF_UNICODETEXT: [...] A null character signals the end of the data.
|
||||
// --> We add +1 to the length. This works because .c_str() is null-terminated.
|
||||
_copyToClipboard(CF_UNICODETEXT, text.c_str(), (text.size() + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
if (!html.empty())
|
||||
{
|
||||
_copyToClipboardRegisteredFormat(L"HTML Format", html.data(), html.size());
|
||||
}
|
||||
|
||||
if (!rtf.empty())
|
||||
{
|
||||
_copyToClipboardRegisteredFormat(L"Rich Text Format", rtf.data(), rtf.size());
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the Terminal wants to set something to the clipboard, i.e.
|
||||
// when an OSC 52 is emitted.
|
||||
void ControlCore::_terminalCopyToClipboard(wil::zwstring_view wstr)
|
||||
{
|
||||
copyToClipboard(wstr, {}, {});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Given a copy-able selection, get the selected text from the buffer and send it to the
|
||||
// Windows Clipboard (CascadiaWin32:main.cpp).
|
||||
@@ -1274,7 +1345,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// if we should defer which formats are copied to the global setting
|
||||
bool ControlCore::CopySelectionToClipboard(bool singleLine,
|
||||
bool withControlSequences,
|
||||
const CopyFormat formats)
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats)
|
||||
{
|
||||
::Microsoft::Terminal::Core::Terminal::TextCopyData payload;
|
||||
{
|
||||
@@ -1286,20 +1357,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto copyHtml = WI_IsFlagSet(formats, CopyFormat::HTML);
|
||||
const auto copyRtf = WI_IsFlagSet(formats, CopyFormat::RTF);
|
||||
// use action's copyFormatting if it's present, else fall back to globally
|
||||
// set copyFormatting.
|
||||
const auto copyFormats = formats != nullptr ? formats.Value() : _settings->CopyFormatting();
|
||||
|
||||
const auto copyHtml = WI_IsFlagSet(copyFormats, CopyFormat::HTML);
|
||||
const auto copyRtf = WI_IsFlagSet(copyFormats, CopyFormat::RTF);
|
||||
|
||||
// extract text from buffer
|
||||
// RetrieveSelectedTextFromBuffer will lock while it's reading
|
||||
payload = _terminal->RetrieveSelectedTextFromBuffer(singleLine, withControlSequences, copyHtml, copyRtf);
|
||||
}
|
||||
|
||||
WriteToClipboard.raise(
|
||||
*this,
|
||||
winrt::make<WriteToClipboardEventArgs>(
|
||||
winrt::hstring{ payload.plainText },
|
||||
std::move(payload.html),
|
||||
std::move(payload.rtf)));
|
||||
copyToClipboard(payload.plainText, payload.html, payload.rtf);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1999,7 +2069,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_terminal->MultiClickSelection(terminalPosition, mode);
|
||||
selectionNeedsToBeCopied = true;
|
||||
}
|
||||
else if (_settings->RepositionCursorWithMouse() && !selectionNeedsToBeCopied) // Don't reposition cursor if this is part of a selection operation
|
||||
else if (_settings->RepositionCursorWithMouse()) // This is also mode==Char && !shiftEnabled
|
||||
{
|
||||
_repositionCursorWithMouse(terminalPosition);
|
||||
}
|
||||
@@ -2687,9 +2757,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::_terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength)
|
||||
safe_void_coroutine ControlCore::_terminalCompletionsChanged(std::wstring_view menuJson,
|
||||
unsigned int replaceLength)
|
||||
{
|
||||
CompletionsChanged.raise(*this, winrt::make<CompletionsChangedEventArgs>(winrt::hstring{ menuJson }, replaceLength));
|
||||
auto args = winrt::make_self<CompletionsChangedEventArgs>(winrt::hstring{ menuJson },
|
||||
replaceLength);
|
||||
|
||||
co_await winrt::resume_background();
|
||||
|
||||
CompletionsChanged.raise(*this, *args);
|
||||
}
|
||||
|
||||
// Select the region of text between [s.start, s.end), in buffer space
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void SendInput(std::wstring_view wstr);
|
||||
void PasteText(const winrt::hstring& hstr);
|
||||
bool CopySelectionToClipboard(bool singleLine, bool withControlSequences, const CopyFormat formats);
|
||||
bool CopySelectionToClipboard(bool singleLine, bool withControlSequences, const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void SelectAll();
|
||||
void ClearSelection();
|
||||
bool ToggleBlockSelection();
|
||||
@@ -277,7 +277,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::FontSizeChangedArgs> FontSizeChanged;
|
||||
|
||||
til::typed_event<IInspectable, Control::TitleChangedEventArgs> TitleChanged;
|
||||
til::typed_event<IInspectable, Control::WriteToClipboardEventArgs> WriteToClipboard;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> TabColorChanged;
|
||||
til::typed_event<> BackgroundColorChanged;
|
||||
@@ -308,9 +307,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
private:
|
||||
struct SharedState
|
||||
{
|
||||
std::unique_ptr<til::throttled_func<>> outputIdle;
|
||||
std::unique_ptr<til::throttled_func<bool>> focusChanged;
|
||||
std::shared_ptr<ThrottledFunc<Control::ScrollPositionChangedArgs>> updateScrollBar;
|
||||
std::unique_ptr<til::debounced_func_trailing<>> outputIdle;
|
||||
std::unique_ptr<til::debounced_func_trailing<bool>> focusChanged;
|
||||
std::shared_ptr<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>> updateScrollBar;
|
||||
};
|
||||
|
||||
void _setupDispatcherAndCallbacks();
|
||||
@@ -326,6 +325,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _sendInputToConnection(std::wstring_view wstr);
|
||||
|
||||
#pragma region TerminalCoreCallbacks
|
||||
void _terminalCopyToClipboard(wil::zwstring_view wstr);
|
||||
void _terminalWarningBell();
|
||||
void _terminalTitleChanged(std::wstring_view wstr);
|
||||
void _terminalScrollPositionChanged(const int viewTop,
|
||||
@@ -339,7 +339,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _terminalSearchMissingCommand(std::wstring_view missingCommand, const til::CoordType& bufferRow);
|
||||
void _terminalWindowSizeChanged(int32_t width, int32_t height);
|
||||
|
||||
void _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
safe_void_coroutine _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
#pragma endregion
|
||||
|
||||
#pragma region RendererCallbacks
|
||||
|
||||
@@ -185,7 +185,6 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
// These events are called from some background thread
|
||||
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
|
||||
|
||||
@@ -199,7 +199,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// if we should defer which formats are copied to the global setting
|
||||
bool ControlInteractivity::CopySelectionToClipboard(bool singleLine,
|
||||
bool withControlSequences,
|
||||
const CopyFormat formats)
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats)
|
||||
{
|
||||
if (_core)
|
||||
{
|
||||
@@ -316,7 +316,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
else
|
||||
{
|
||||
// Try to copy the text and clear the selection
|
||||
const auto successfulCopy = CopySelectionToClipboard(shiftEnabled, false, _core->Settings().CopyFormatting());
|
||||
const auto successfulCopy = CopySelectionToClipboard(shiftEnabled, false, nullptr);
|
||||
_core->ClearSelection();
|
||||
if (_core->CopyOnSelect() || !successfulCopy)
|
||||
{
|
||||
@@ -461,7 +461,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// IMPORTANT!
|
||||
// DO NOT clear the selection here!
|
||||
// Otherwise, the selection will be cleared immediately after you make it.
|
||||
CopySelectionToClipboard(false, false, _core->Settings().CopyFormatting());
|
||||
CopySelectionToClipboard(false, false, nullptr);
|
||||
}
|
||||
|
||||
_singleClickTouchdownPos = std::nullopt;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
bool CopySelectionToClipboard(bool singleLine,
|
||||
bool withControlSequences,
|
||||
const CopyFormat formats);
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void RequestPasteTextFromClipboard();
|
||||
void SetEndSelectionPoint(const Core::Point pixelPosition);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
InteractivityAutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
Boolean CopySelectionToClipboard(Boolean singleLine, Boolean withControlSequences, CopyFormat formats);
|
||||
Boolean CopySelectionToClipboard(Boolean singleLine, Boolean withControlSequences, Windows.Foundation.IReference<CopyFormat> formats);
|
||||
void RequestPasteTextFromClipboard();
|
||||
void SetEndSelectionPoint(Microsoft.Terminal.Core.Point point);
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "FontSizeChangedArgs.g.cpp"
|
||||
#include "TitleChangedEventArgs.g.cpp"
|
||||
#include "ContextMenuRequestedEventArgs.g.cpp"
|
||||
#include "WriteToClipboardEventArgs.g.cpp"
|
||||
#include "PasteFromClipboardEventArgs.g.cpp"
|
||||
#include "OpenHyperlinkEventArgs.g.cpp"
|
||||
#include "NoticeEventArgs.g.cpp"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "FontSizeChangedArgs.g.h"
|
||||
#include "TitleChangedEventArgs.g.h"
|
||||
#include "ContextMenuRequestedEventArgs.g.h"
|
||||
#include "WriteToClipboardEventArgs.g.h"
|
||||
#include "PasteFromClipboardEventArgs.g.h"
|
||||
#include "OpenHyperlinkEventArgs.g.h"
|
||||
#include "NoticeEventArgs.g.h"
|
||||
@@ -57,32 +56,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
WINRT_PROPERTY(winrt::Windows::Foundation::Point, Position);
|
||||
};
|
||||
|
||||
struct WriteToClipboardEventArgs : WriteToClipboardEventArgsT<WriteToClipboardEventArgs>
|
||||
{
|
||||
WriteToClipboardEventArgs(winrt::hstring&& plain, std::string&& html, std::string&& rtf) :
|
||||
_plain(std::move(plain)),
|
||||
_html(std::move(html)),
|
||||
_rtf(std::move(rtf))
|
||||
{
|
||||
}
|
||||
|
||||
winrt::hstring Plain() const noexcept { return _plain; }
|
||||
winrt::com_array<uint8_t> Html() noexcept { return _cast(_html); }
|
||||
winrt::com_array<uint8_t> Rtf() noexcept { return _cast(_rtf); }
|
||||
|
||||
private:
|
||||
static winrt::com_array<uint8_t> _cast(const std::string& str)
|
||||
{
|
||||
const auto beg = reinterpret_cast<const uint8_t*>(str.data());
|
||||
const auto len = str.size();
|
||||
return { beg, beg + len };
|
||||
}
|
||||
|
||||
winrt::hstring _plain;
|
||||
std::string _html;
|
||||
std::string _rtf;
|
||||
};
|
||||
|
||||
struct PasteFromClipboardEventArgs : public PasteFromClipboardEventArgsT<PasteFromClipboardEventArgs>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Microsoft.Terminal.Control
|
||||
[flags]
|
||||
enum CopyFormat
|
||||
{
|
||||
None = 0x0,
|
||||
HTML = 0x1,
|
||||
RTF = 0x2,
|
||||
All = 0xffffffff
|
||||
@@ -32,13 +31,6 @@ namespace Microsoft.Terminal.Control
|
||||
AlphanumericHalfWidth,
|
||||
};
|
||||
|
||||
enum WarnAboutMultiLinePaste
|
||||
{
|
||||
Automatic,
|
||||
Always,
|
||||
Never,
|
||||
};
|
||||
|
||||
runtimeclass FontSizeChangedArgs
|
||||
{
|
||||
Int32 Width { get; };
|
||||
@@ -55,13 +47,6 @@ namespace Microsoft.Terminal.Control
|
||||
String Title;
|
||||
}
|
||||
|
||||
runtimeclass WriteToClipboardEventArgs
|
||||
{
|
||||
String Plain { get; }; // UTF-16, as required by CF_UNICODETEXT
|
||||
byte[] Html { get; }; // UTF-8, as required by "HTML Format"
|
||||
byte[] Rtf { get; }; // UTF-8, as required by "Rich Text Format"
|
||||
}
|
||||
|
||||
runtimeclass PasteFromClipboardEventArgs
|
||||
{
|
||||
void HandleClipboardData(String data);
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace Microsoft.Terminal.Control
|
||||
interface IControlSettings requires Microsoft.Terminal.Core.ICoreSettings,
|
||||
Microsoft.Terminal.Control.IControlAppearance
|
||||
{
|
||||
String ProfileName;
|
||||
|
||||
Boolean EnableUnfocusedAcrylic { get; };
|
||||
Guid SessionId { get; };
|
||||
ScrollbarState ScrollState { get; };
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parent.as<IAutomationPeerProtected>().ProviderFromPeer(parent));
|
||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parent.ProviderFromPeer(parent));
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
};
|
||||
|
||||
|
||||
@@ -330,7 +330,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.RestartTerminalRequested = _core.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleRestartTerminalRequested });
|
||||
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
|
||||
_revokers.WindowSizeChanged = _core.WindowSizeChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWindowSizeChanged });
|
||||
_revokers.WriteToClipboard = _core.WriteToClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWriteToClipboard });
|
||||
|
||||
_revokers.PasteFromClipboard = _interactivity.PasteFromClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubblePasteFromClipboard });
|
||||
|
||||
@@ -359,12 +358,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// These three throttled functions are triggered by terminal output and interact with the UI.
|
||||
// Since Close() is the point after which we are removed from the UI, but before the
|
||||
// destructor has run, we MUST check control->_IsClosing() before actually doing anything.
|
||||
_playWarningBell = std::make_shared<ThrottledFunc<>>(
|
||||
_playWarningBell = std::make_shared<ThrottledFuncLeading>(
|
||||
dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = TerminalWarningBellInterval,
|
||||
.leading = true,
|
||||
},
|
||||
TerminalWarningBellInterval,
|
||||
[weakThis = get_weak()]() {
|
||||
if (auto control{ weakThis.get() }; control && !control->_IsClosing())
|
||||
{
|
||||
@@ -372,12 +368,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
});
|
||||
|
||||
_updateScrollBar = std::make_shared<ThrottledFunc<ScrollBarUpdate>>(
|
||||
_updateScrollBar = std::make_shared<ThrottledFuncTrailing<ScrollBarUpdate>>(
|
||||
dispatcher,
|
||||
til::throttled_func_options{
|
||||
.delay = ScrollBarUpdateInterval,
|
||||
.trailing = true,
|
||||
},
|
||||
ScrollBarUpdateInterval,
|
||||
[weakThis = get_weak()](const auto& update) {
|
||||
if (auto control{ weakThis.get() }; control && !control->_IsClosing())
|
||||
{
|
||||
@@ -2610,9 +2603,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.Title();
|
||||
}
|
||||
|
||||
hstring TermControl::GetStartingTitle() const
|
||||
hstring TermControl::GetProfileName() const
|
||||
{
|
||||
return _core.Settings().StartingTitle();
|
||||
return _core.Settings().ProfileName();
|
||||
}
|
||||
|
||||
hstring TermControl::WorkingDirectory() const
|
||||
@@ -2635,7 +2628,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - withControlSequences: if enabled, the copied plain text contains color/style ANSI escape codes from the selection
|
||||
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
|
||||
// if we should defer which formats are copied to the global setting
|
||||
bool TermControl::CopySelectionToClipboard(bool dismissSelection, bool singleLine, bool withControlSequences, const CopyFormat formats)
|
||||
bool TermControl::CopySelectionToClipboard(bool dismissSelection, bool singleLine, bool withControlSequences, const Windows::Foundation::IReference<CopyFormat>& formats)
|
||||
{
|
||||
if (_IsClosing())
|
||||
{
|
||||
@@ -3458,14 +3451,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Switch on the light and animate the intensity to fade out
|
||||
VisualBellLight::SetIsTarget(RootGrid(), true);
|
||||
|
||||
auto compositionLight{ BellLight().as<Windows::UI::Xaml::Media::IXamlLightProtected>().CompositionLight() };
|
||||
if (_isBackgroundLight)
|
||||
{
|
||||
compositionLight.StartAnimation(L"Intensity", _bellDarkAnimation);
|
||||
BellLight().CompositionLight().StartAnimation(L"Intensity", _bellDarkAnimation);
|
||||
}
|
||||
else
|
||||
{
|
||||
compositionLight.StartAnimation(L"Intensity", _bellLightAnimation);
|
||||
BellLight().CompositionLight().StartAnimation(L"Intensity", _bellLightAnimation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4155,7 +4147,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const IInspectable& /*args*/)
|
||||
{
|
||||
// formats = nullptr -> copy all formats
|
||||
_interactivity.CopySelectionToClipboard(false, false, _core.Settings().CopyFormatting());
|
||||
_interactivity.CopySelectionToClipboard(false, false, nullptr);
|
||||
ContextMenu().Hide();
|
||||
SelectionContextMenu().Hide();
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
uint64_t ContentId() const;
|
||||
|
||||
hstring GetStartingTitle() const;
|
||||
hstring GetProfileName() const;
|
||||
|
||||
bool CopySelectionToClipboard(bool dismissSelection, bool singleLine, bool withControlSequences, const CopyFormat formats);
|
||||
bool CopySelectionToClipboard(bool dismissSelection, bool singleLine, bool withControlSequences, const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void PasteTextFromClipboard();
|
||||
void SelectAll();
|
||||
bool ToggleBlockSelection();
|
||||
@@ -227,8 +227,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(CloseTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(CompletionsChanged, IInspectable, Control::CompletionsChangedEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(WriteToClipboard, IInspectable, Control::WriteToClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -284,7 +284,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _quickFixesAvailable{ false };
|
||||
til::CoordType _quickFixBufferPos{};
|
||||
|
||||
std::shared_ptr<ThrottledFunc<>> _playWarningBell;
|
||||
std::shared_ptr<ThrottledFuncLeading> _playWarningBell;
|
||||
|
||||
struct ScrollBarUpdate
|
||||
{
|
||||
@@ -294,7 +294,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
double newViewportSize;
|
||||
};
|
||||
|
||||
std::shared_ptr<ThrottledFunc<ScrollBarUpdate>> _updateScrollBar;
|
||||
std::shared_ptr<ThrottledFuncTrailing<ScrollBarUpdate>> _updateScrollBar;
|
||||
|
||||
bool _isInternalScrollBarUpdate;
|
||||
|
||||
@@ -463,7 +463,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::ControlCore::UpdateSelectionMarkers_revoker UpdateSelectionMarkers;
|
||||
Control::ControlCore::OpenHyperlink_revoker coreOpenHyperlink;
|
||||
Control::ControlCore::TitleChanged_revoker TitleChanged;
|
||||
Control::ControlCore::WriteToClipboard_revoker WriteToClipboard;
|
||||
Control::ControlCore::TabColorChanged_revoker TabColorChanged;
|
||||
Control::ControlCore::TaskbarProgressChanged_revoker TaskbarProgressChanged;
|
||||
Control::ControlCore::ConnectionStateChanged_revoker ConnectionStateChanged;
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace Microsoft.Terminal.Control
|
||||
Microsoft.Terminal.Control.IControlSettings Settings { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
|
||||
event Windows.Foundation.TypedEventHandler<Object, PasteFromClipboardEventArgs> PasteFromClipboard;
|
||||
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
@@ -88,7 +87,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CloseTerminalRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RestartTerminalRequested;
|
||||
|
||||
Boolean CopySelectionToClipboard(Boolean dismissSelection, Boolean singleLine, Boolean withControlSequences, CopyFormat formats);
|
||||
Boolean CopySelectionToClipboard(Boolean dismissSelection, Boolean singleLine, Boolean withControlSequences, Windows.Foundation.IReference<CopyFormat> formats);
|
||||
void PasteTextFromClipboard();
|
||||
void SelectAll();
|
||||
Boolean ToggleBlockSelection();
|
||||
|
||||
@@ -308,14 +308,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// fall back to title if profile name is empty
|
||||
if (auto control{ _termControl.get() })
|
||||
{
|
||||
const auto originalName = control->GetStartingTitle();
|
||||
if (originalName.empty())
|
||||
const auto profileName = control->GetProfileName();
|
||||
if (profileName.empty())
|
||||
{
|
||||
return control->Title();
|
||||
}
|
||||
else
|
||||
{
|
||||
return originalName;
|
||||
return profileName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@ public:
|
||||
bool IsVtInputEnabled() const noexcept override;
|
||||
void NotifyAccessibilityChange(const til::rect& changedRect) noexcept override;
|
||||
void NotifyBufferRotation(const int delta) override;
|
||||
void NotifyShellIntegrationMark() override;
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
|
||||
@@ -404,9 +404,3 @@ void Terminal::NotifyBufferRotation(const int delta)
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyShellIntegrationMark()
|
||||
{
|
||||
// Notify the scrollbar that marks have been added so it can refresh the mark indicators
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
@@ -66,14 +66,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("actions", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
void Actions::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*eventArgs*/)
|
||||
|
||||
@@ -29,27 +29,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void AddProfile::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
{
|
||||
_State = e.Parameter().as<Editor::AddProfilePageNavigationState>();
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("addProfile", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
void AddProfile::AddNewClick(const IInspectable& /*sender*/,
|
||||
const Windows::UI::Xaml::RoutedEventArgs& /*eventArgs*/)
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"AddNewProfile",
|
||||
TraceLoggingDescription("Event emitted when the user adds a new profile"),
|
||||
TraceLoggingValue("EmptyProfile", "Type", "The type of the creation method (i.e. empty profile, duplicate)"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
_State.RequestAddNew();
|
||||
}
|
||||
|
||||
@@ -58,17 +42,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (const auto selected = Profiles().SelectedItem())
|
||||
{
|
||||
const auto selectedProfile = selected.as<Model::Profile>();
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"AddNewProfile",
|
||||
TraceLoggingDescription("Event emitted when the user adds a new profile"),
|
||||
TraceLoggingValue("Duplicate", "Type", "The type of the creation method (i.e. empty profile, duplicate)"),
|
||||
TraceLoggingValue(!selectedProfile.Source().empty(), "SourceProfileHasSource", "True, if the source profile has a source (i.e. dynamic profile generator namespace, fragment). Otherwise, False, indicating it's based on a custom profile."),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
_State.RequestDuplicate(selectedProfile.Guid());
|
||||
_State.RequestDuplicate(selected.try_as<Model::Profile>().Guid());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(EvaluatedIcon), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
@@ -254,9 +254,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// Cache the original BG image path. If the user clicks "Use desktop
|
||||
// wallpaper", then un-checks it, this is the string we'll restore to
|
||||
// them.
|
||||
if (BackgroundImagePath().Path() != L"desktopWallpaper")
|
||||
if (BackgroundImagePath() != L"desktopWallpaper")
|
||||
{
|
||||
_lastBgImagePath = BackgroundImagePath().Path();
|
||||
_lastBgImagePath = BackgroundImagePath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,8 +913,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void AppearanceViewModel::SetBackgroundImagePath(winrt::hstring path)
|
||||
{
|
||||
_appearance.BackgroundImagePath(Model::MediaResourceHelper::FromString(path));
|
||||
_NotifyChanges(L"BackgroundImagePath");
|
||||
BackgroundImagePath(path);
|
||||
}
|
||||
|
||||
hstring AppearanceViewModel::BackgroundImageAlignmentCurrentValue() const
|
||||
@@ -957,7 +956,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
hstring AppearanceViewModel::CurrentBackgroundImagePath() const
|
||||
{
|
||||
const auto bgImagePath = BackgroundImagePath().Path();
|
||||
const auto bgImagePath = BackgroundImagePath();
|
||||
if (bgImagePath.empty())
|
||||
{
|
||||
return RS_(L"Appearance_BackgroundImageNone");
|
||||
@@ -971,7 +970,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
bool AppearanceViewModel::UseDesktopBGImage() const
|
||||
{
|
||||
return BackgroundImagePath().Path() == L"desktopWallpaper";
|
||||
return BackgroundImagePath() == L"desktopWallpaper";
|
||||
}
|
||||
|
||||
void AppearanceViewModel::UseDesktopBGImage(const bool useDesktop)
|
||||
@@ -984,23 +983,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
//
|
||||
// Only stash this value if it's not the special "desktopWallpaper"
|
||||
// value.
|
||||
if (BackgroundImagePath().Path() != L"desktopWallpaper")
|
||||
if (BackgroundImagePath() != L"desktopWallpaper")
|
||||
{
|
||||
_lastBgImagePath = BackgroundImagePath().Path();
|
||||
_lastBgImagePath = BackgroundImagePath();
|
||||
}
|
||||
SetBackgroundImagePath(L"desktopWallpaper");
|
||||
BackgroundImagePath(L"desktopWallpaper");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore the path we had previously cached. This might be the
|
||||
// empty string.
|
||||
SetBackgroundImagePath(_lastBgImagePath);
|
||||
BackgroundImagePath(_lastBgImagePath);
|
||||
}
|
||||
}
|
||||
|
||||
bool AppearanceViewModel::BackgroundImageSettingsVisible() const
|
||||
{
|
||||
return !BackgroundImagePath().Path().empty();
|
||||
return !BackgroundImagePath().empty();
|
||||
}
|
||||
|
||||
void AppearanceViewModel::ClearColorScheme()
|
||||
@@ -1425,7 +1424,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
auto file = co_await OpenImagePicker(parentHwnd);
|
||||
if (!file.empty())
|
||||
{
|
||||
Appearance().SetBackgroundImagePath(file);
|
||||
Appearance().BackgroundImagePath(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Boolean, RetroTerminalEffect);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Core.CursorStyle, CursorShape);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(UInt32, CursorHeight);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Settings.Model.IMediaResource, BackgroundImagePath);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, BackgroundImagePath);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Single, BackgroundImageOpacity);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.UI.Xaml.Media.Stretch, BackgroundImageStretchMode);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Settings.Model.ConvergedAlignment, BackgroundImageAlignment);
|
||||
|
||||
@@ -68,7 +68,6 @@
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<!-- Grouping: Text -->
|
||||
<TextBlock x:Uid="Profile_TextHeader"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Color Scheme -->
|
||||
<!-- This currently only display the Dark color scheme, even if the user has a pair of schemes set. -->
|
||||
@@ -543,7 +542,7 @@
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Appearance.UseDesktopBGImage), Mode=OneWay}"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind mtu:Converters.StringOrEmptyIfPlaceholder('desktopWallpaper', Appearance.BackgroundImagePath.Path), Mode=TwoWay, BindBack=Appearance.SetBackgroundImagePath}" />
|
||||
Text="{x:Bind mtu:Converters.StringOrEmptyIfPlaceholder('desktopWallpaper', Appearance.BackgroundImagePath), Mode=TwoWay, BindBack=Appearance.SetBackgroundImagePath}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Uid="Profile_BackgroundImageBrowse"
|
||||
Margin="0,10,10,0"
|
||||
|
||||
@@ -44,14 +44,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
ColorSchemeListView().Focus(FocusState::Programmatic);
|
||||
});
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("colorSchemes", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
void ColorSchemes::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/)
|
||||
|
||||
@@ -160,13 +160,6 @@
|
||||
<Setter Property="Margin" Value="0,32,0,4" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TextBlockSubtitleStyle"
|
||||
BasedOn="{StaticResource SubtitleTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
<Setter Property="Margin" Value="0,32,0,4" />
|
||||
</Style>
|
||||
|
||||
<!-- Used for disclaimers -->
|
||||
<Style x:Key="DisclaimerStyle"
|
||||
TargetType="TextBlock">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user