Compare commits
103 Commits
dev/duhowe
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12c6b0a240 | ||
|
|
580b7b7d36 | ||
|
|
c60a006e77 | ||
|
|
c9a1f12894 | ||
|
|
318fd6abd6 | ||
|
|
fd434197f1 | ||
|
|
9f0d9a5d14 | ||
|
|
63e85e84c1 | ||
|
|
fc8c6f6802 | ||
|
|
64e57344be | ||
|
|
cb4403e8b3 | ||
|
|
f62754397d | ||
|
|
0c98216d2f | ||
|
|
ca6af92561 | ||
|
|
f4bffcfdb6 | ||
|
|
ef89e13ea9 | ||
|
|
fa91fd6940 | ||
|
|
91f7063d2d | ||
|
|
f5b8e98243 | ||
|
|
90a9d15659 | ||
|
|
f16f5133f3 | ||
|
|
cba3d71378 | ||
|
|
49e96f22be | ||
|
|
b690855cf5 | ||
|
|
117eb9b8fb | ||
|
|
0982abe762 | ||
|
|
78c36ca25d | ||
|
|
df9df3d4ee | ||
|
|
99df9e9444 | ||
|
|
d1ac37599c | ||
|
|
87c87b51fc | ||
|
|
dc8a830fea | ||
|
|
41bb31f5dc | ||
|
|
6b380cb7e0 | ||
|
|
84a33afb8c | ||
|
|
ef586f6bf5 | ||
|
|
bdb67a382a | ||
|
|
b6326cf23e | ||
|
|
e27ebe7681 | ||
|
|
c47d9e1ad9 | ||
|
|
b95cc19e87 | ||
|
|
e8c15683a7 | ||
|
|
6d4ff2e5a7 | ||
|
|
e60afb6f4e | ||
|
|
1519b6feb2 | ||
|
|
6d9fb78bfc | ||
|
|
102181f109 | ||
|
|
b028a5764b | ||
|
|
cf7a6617ab | ||
|
|
f2e9041aa0 | ||
|
|
8e7137dbde | ||
|
|
0cbe706f48 | ||
|
|
8c2c88e44f | ||
|
|
1742dc03ff | ||
|
|
42ab9bbd69 | ||
|
|
cb8a3f6ef1 | ||
|
|
ed08108e32 | ||
|
|
8aa56c25f4 | ||
|
|
e866a6c66f | ||
|
|
2890e8a3d4 | ||
|
|
6b6167ec2b | ||
|
|
5d1638f187 | ||
|
|
2befaa1669 | ||
|
|
83a9baa797 | ||
|
|
5a99621856 | ||
|
|
09aa541d56 | ||
|
|
4040e4c654 | ||
|
|
8f4775df96 | ||
|
|
3ab8921aa7 | ||
|
|
2a15717f69 | ||
|
|
846a8aa7a6 | ||
|
|
9cccef7224 | ||
|
|
196a60c7c2 | ||
|
|
aff77650e4 | ||
|
|
8f3b38fb81 | ||
|
|
d960c89634 | ||
|
|
332c5ad937 | ||
|
|
5f6783b01f | ||
|
|
334335fd43 | ||
|
|
30df31fd9b | ||
|
|
0030a1d52e | ||
|
|
082d166ac6 | ||
|
|
3e661bfad2 | ||
|
|
7b59a9eafb | ||
|
|
8038dc67cd | ||
|
|
bc365c9542 | ||
|
|
0d8e43c697 | ||
|
|
967dcfc5b0 | ||
|
|
e56a557c93 | ||
|
|
52eba74316 | ||
|
|
27de22d0e5 | ||
|
|
52ab4c467a | ||
|
|
ece2ef7f84 | ||
|
|
ef283da5cb | ||
|
|
18c3f72fe0 | ||
|
|
4d1b543a9e | ||
|
|
d838ce5e67 | ||
|
|
1f54562f04 | ||
|
|
f0fc1b5701 | ||
|
|
a6819c5384 | ||
|
|
3c6b2af578 | ||
|
|
fe237afc25 | ||
|
|
3600ee42f0 |
@@ -1,5 +0,0 @@
|
||||
EOB
|
||||
swrapped
|
||||
wordi
|
||||
wordiswrapped
|
||||
wrappe
|
||||
16
.github/actions/spelling/expect/expect.txt
vendored
@@ -18,6 +18,8 @@ ADDREF
|
||||
ADDSTRING
|
||||
ADDTOOL
|
||||
AFew
|
||||
adml
|
||||
admx
|
||||
AFill
|
||||
AFX
|
||||
AHelper
|
||||
@@ -552,6 +554,7 @@ entrypoints
|
||||
ENU
|
||||
ENUMLOGFONT
|
||||
ENUMLOGFONTEX
|
||||
EOB
|
||||
EOK
|
||||
EPres
|
||||
EQU
|
||||
@@ -607,6 +610,7 @@ FILTERONPASTE
|
||||
FINDCASE
|
||||
FINDDLG
|
||||
FINDDOWN
|
||||
FINDREGEX
|
||||
FINDSTRINGEXACT
|
||||
FINDUP
|
||||
FIter
|
||||
@@ -767,6 +771,7 @@ HIWORD
|
||||
HKCU
|
||||
hkey
|
||||
hkl
|
||||
HKLM
|
||||
hlocal
|
||||
hlsl
|
||||
HMB
|
||||
@@ -848,6 +853,7 @@ INLINEPREFIX
|
||||
inproc
|
||||
Inputkeyinfo
|
||||
Inputreadhandledata
|
||||
INPUTSCOPE
|
||||
INSERTMODE
|
||||
INTERACTIVITYBASE
|
||||
INTERCEPTCOPYPASTE
|
||||
@@ -1270,6 +1276,7 @@ parms
|
||||
PATCOPY
|
||||
pathcch
|
||||
PATTERNID
|
||||
pbstr
|
||||
pcb
|
||||
pcch
|
||||
PCCHAR
|
||||
@@ -1355,9 +1362,11 @@ POSTCHARBREAKS
|
||||
POSX
|
||||
POSXSCROLL
|
||||
POSYSCROLL
|
||||
ppbstr
|
||||
PPEB
|
||||
ppf
|
||||
ppidl
|
||||
pprg
|
||||
PPROC
|
||||
ppropvar
|
||||
ppsi
|
||||
@@ -1668,6 +1677,7 @@ srcsrv
|
||||
SRCSRVTRG
|
||||
srctool
|
||||
srect
|
||||
SRGS
|
||||
srvinit
|
||||
srvpipe
|
||||
ssa
|
||||
@@ -1705,6 +1715,7 @@ swapchain
|
||||
swapchainpanel
|
||||
SWMR
|
||||
SWP
|
||||
swrapped
|
||||
SYMED
|
||||
SYNCPAINT
|
||||
syscalls
|
||||
@@ -1816,7 +1827,6 @@ Tribool
|
||||
TRIMZEROHEADINGS
|
||||
trx
|
||||
tsa
|
||||
tsattrs
|
||||
tsgr
|
||||
tsm
|
||||
TStr
|
||||
@@ -1945,7 +1955,6 @@ vswhere
|
||||
vtapp
|
||||
VTE
|
||||
VTID
|
||||
vtio
|
||||
vtmode
|
||||
vtpipeterm
|
||||
vtpt
|
||||
@@ -2055,6 +2064,8 @@ WNDCLASSW
|
||||
Wndproc
|
||||
WNegative
|
||||
WNull
|
||||
wordi
|
||||
wordiswrapped
|
||||
workarea
|
||||
WOutside
|
||||
WOWARM
|
||||
@@ -2068,6 +2079,7 @@ WPrep
|
||||
WPresent
|
||||
wprp
|
||||
wprpi
|
||||
wrappe
|
||||
wregex
|
||||
writeback
|
||||
WRITECONSOLE
|
||||
|
||||
@@ -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/ms/terminal/_packaging/TerminalDependencies/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 />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"instanceUrl": "https://microsoft.visualstudio.com",
|
||||
"projectName": "OS",
|
||||
"areaPath": "OS\\Windows Client and Services\\ADEPT\\E4D-Engineered for Developers\\SHINE\\Terminal",
|
||||
"areaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\Terminal",
|
||||
"notificationAliases": ["condev@microsoft.com", "duhowett@microsoft.com"]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
|
||||
<PGOBranch>main</PGOBranch>
|
||||
<PGOBranch>release-1.21</PGOBranch>
|
||||
|
||||
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
|
||||
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>
|
||||
|
||||
@@ -37,6 +37,8 @@ extends:
|
||||
akvName: $(SigningAKVName)
|
||||
authCertName: $(SigningAuthCertName)
|
||||
signCertName: $(SigningSignCertName)
|
||||
useManagedIdentity: $(SigningUseManagedIdentity)
|
||||
clientId: $(SigningOriginalClientId)
|
||||
publishSymbolsToPublic: true
|
||||
publishVpackToWindows: false
|
||||
symbolExpiryTime: 15
|
||||
|
||||
@@ -27,7 +27,7 @@ parameters:
|
||||
- name: pgoBuildMode
|
||||
displayName: "PGO Build Mode"
|
||||
type: string
|
||||
default: Optimize
|
||||
default: None # BODGY - OneBranch is on VS 17.10, which is known to be the worst
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
@@ -85,6 +85,8 @@ extends:
|
||||
akvName: $(SigningAKVName)
|
||||
authCertName: $(SigningAuthCertName)
|
||||
signCertName: $(SigningSignCertName)
|
||||
useManagedIdentity: $(SigningUseManagedIdentity)
|
||||
clientId: $(SigningOriginalClientId)
|
||||
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
|
||||
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
|
||||
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
|
||||
|
||||
@@ -59,10 +59,7 @@ jobs:
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-setup-versioning.yml
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
@@ -100,36 +97,32 @@ jobs:
|
||||
flattenFolders: true
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@5
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: ${{ parameters.signingIdentity.serviceName }}
|
||||
AppRegistrationClientId: ${{ parameters.signingIdentity.appId }}
|
||||
AppRegistrationTenantId: ${{ parameters.signingIdentity.tenantId }}
|
||||
AuthAKVName: ${{ parameters.signingIdentity.akvName }}
|
||||
AuthCertName: ${{ parameters.signingIdentity.authCertName }}
|
||||
AuthSignCertName: ${{ parameters.signingIdentity.signCertName }}
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- template: steps-esrp-signing.yml
|
||||
parameters:
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
signingIdentity: ${{ parameters.signingIdentity }}
|
||||
inputs:
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
|
||||
@@ -242,18 +242,14 @@ jobs:
|
||||
|
||||
# Code-sign everything we just put together.
|
||||
# We run the signing in Terminal.BinDir, because all of the signing batches are relative to the final architecture/configuration output folder.
|
||||
- task: EsrpCodeSigning@5
|
||||
displayName: Submit Signing Request
|
||||
inputs:
|
||||
ConnectedServiceName: ${{ parameters.signingIdentity.serviceName }}
|
||||
AppRegistrationClientId: ${{ parameters.signingIdentity.appId }}
|
||||
AppRegistrationTenantId: ${{ parameters.signingIdentity.tenantId }}
|
||||
AuthAKVName: ${{ parameters.signingIdentity.akvName }}
|
||||
AuthCertName: ${{ parameters.signingIdentity.authCertName }}
|
||||
AuthSignCertName: ${{ parameters.signingIdentity.signCertName }}
|
||||
FolderPath: '$(Terminal.BinDir)'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
|
||||
- template: steps-esrp-signing.yml
|
||||
parameters:
|
||||
displayName: Submit Signing Request
|
||||
signingIdentity: ${{ parameters.signingIdentity }}
|
||||
inputs:
|
||||
FolderPath: '$(Terminal.BinDir)'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
|
||||
|
||||
# We only need to re-pack the MSIX if we actually signed, so this can stay in the codeSign conditional
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
|
||||
@@ -69,10 +69,9 @@ jobs:
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- template: steps-setup-versioning.yml
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
@@ -97,45 +96,41 @@ jobs:
|
||||
displayName: Create msixbundle
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@5
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: ${{ parameters.signingIdentity.serviceName }}
|
||||
AppRegistrationClientId: ${{ parameters.signingIdentity.appId }}
|
||||
AppRegistrationTenantId: ${{ parameters.signingIdentity.tenantId }}
|
||||
AuthAKVName: ${{ parameters.signingIdentity.akvName }}
|
||||
AuthCertName: ${{ parameters.signingIdentity.authCertName }}
|
||||
AuthSignCertName: ${{ parameters.signingIdentity.signCertName }}
|
||||
FolderPath: $(System.ArtifactsDirectory)\bundle
|
||||
Pattern: $(BundleStemName)*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- template: steps-esrp-signing.yml
|
||||
parameters:
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
signingIdentity: ${{ parameters.signingIdentity }}
|
||||
inputs:
|
||||
FolderPath: $(System.ArtifactsDirectory)\bundle
|
||||
Pattern: $(BundleStemName)*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
|
||||
@@ -57,10 +57,7 @@ jobs:
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-setup-versioning.yml
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
@@ -85,36 +82,32 @@ jobs:
|
||||
versionEnvVar: XES_PACKAGEVERSIONNUMBER
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@5
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: ${{ parameters.signingIdentity.serviceName }}
|
||||
AppRegistrationClientId: ${{ parameters.signingIdentity.appId }}
|
||||
AppRegistrationTenantId: ${{ parameters.signingIdentity.tenantId }}
|
||||
AuthAKVName: ${{ parameters.signingIdentity.akvName }}
|
||||
AuthCertName: ${{ parameters.signingIdentity.authCertName }}
|
||||
AuthSignCertName: ${{ parameters.signingIdentity.signCertName }}
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- template: steps-esrp-signing.yml
|
||||
parameters:
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
signingIdentity: ${{ parameters.signingIdentity }}
|
||||
inputs:
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
|
||||
@@ -44,10 +44,7 @@ jobs:
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-setup-versioning.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download all PDBs from all prior build phases
|
||||
|
||||
@@ -43,10 +43,7 @@ jobs:
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-setup-versioning.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download all PDBs from all prior build phases
|
||||
|
||||
@@ -38,10 +38,7 @@ jobs:
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-setup-versioning.yml
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download MSIX Bundle Artifact
|
||||
|
||||
@@ -92,10 +92,7 @@ stages:
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: ./build/pipelines/templates-v2/steps-setup-versioning.yml@self
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
@@ -119,10 +116,7 @@ stages:
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps:
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: ./build/pipelines/templates-v2/steps-setup-versioning.yml@self
|
||||
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
|
||||
|
||||
- stage: Package
|
||||
|
||||
@@ -130,10 +130,7 @@ extends:
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
signingIdentity: ${{ parameters.signingIdentity }}
|
||||
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: ./build/pipelines/templates-v2/steps-setup-versioning.yml@self
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
@@ -167,10 +164,7 @@ extends:
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
signingIdentity: ${{ parameters.signingIdentity }}
|
||||
beforeBuildSteps:
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: ./build/pipelines/templates-v2/steps-setup-versioning.yml@self
|
||||
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
|
||||
|
||||
- stage: Package
|
||||
|
||||
24
build/pipelines/templates-v2/steps-esrp-signing.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
parameters:
|
||||
- name: displayName
|
||||
type: string
|
||||
default: ESRP Code Signing
|
||||
- name: inputs
|
||||
type: object
|
||||
default: {}
|
||||
- name: signingIdentity
|
||||
type: object
|
||||
default: {}
|
||||
|
||||
steps:
|
||||
- task: EsrpCodeSigning@5
|
||||
displayName: ${{ parameters.displayName }}
|
||||
inputs:
|
||||
ConnectedServiceName: ${{ parameters.signingIdentity.serviceName }}
|
||||
AppRegistrationClientId: ${{ parameters.signingIdentity.appId }}
|
||||
AppRegistrationTenantId: ${{ parameters.signingIdentity.tenantId }}
|
||||
AuthAKVName: ${{ parameters.signingIdentity.akvName }}
|
||||
AuthCertName: ${{ parameters.signingIdentity.authCertName }}
|
||||
AuthSignCertName: ${{ parameters.signingIdentity.signCertName }}
|
||||
UseMSIAuthentication: ${{ coalesce(parameters.signingIdentity.useManagedIdentity, 'false') }}
|
||||
EsrpClientId: ${{ parameters.signingIdentity.clientId }}
|
||||
${{ insert }}: ${{ parameters.inputs }}
|
||||
6
build/pipelines/templates-v2/steps-setup-versioning.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
steps:
|
||||
- pwsh: |-
|
||||
nuget install Microsoft.Windows.Terminal.Versioning -OutputDirectory _versioning
|
||||
$VersionRoot = (Get-Item _versioning\Microsoft.Windows.*).FullName
|
||||
& "$VersionRoot\build\Setup.ps1" -ProjectDirectory "$(Build.SourcesDirectory)" -Verbose
|
||||
displayName: Set up versioning via M.W.T.V
|
||||
@@ -1,2 +1,7 @@
|
||||
parameters:
|
||||
- name: containerVersion
|
||||
type: string
|
||||
default: latest
|
||||
|
||||
variables:
|
||||
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:1.0.02566.28'
|
||||
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:${{ parameters.containerVersion }}'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$VSInstances = ([xml](& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -include packages -format xml))
|
||||
$VSPackages = $VSInstances.instances.instance.packages.package
|
||||
$LatestVCPackage = ($VSInstances.instances.instance.packages.package | ? { $_.id -eq "Microsoft.VisualCpp.CRT.Source" })
|
||||
$LatestVCPackage = ($VSInstances.instances.instance.packages.package | ? { $_.id -eq "Microsoft.VisualCpp.Tools.Core" })
|
||||
$LatestVCToolsVersion = $LatestVCPackage.version;
|
||||
|
||||
Write-Output "Latest VCToolsVersion: $LatestVCToolsVersion"
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
"enum": [
|
||||
"Windows.Terminal.Wsl",
|
||||
"Windows.Terminal.Azure",
|
||||
"Windows.Terminal.PowershellCore"
|
||||
"Windows.Terminal.PowershellCore",
|
||||
"Windows.Terminal.VisualStudio"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -618,6 +619,11 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "This will override the profile's `elevate` setting."
|
||||
},
|
||||
"reloadEnvironmentVariables": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "When set to true, a new environment block will be generated when creating a new session. Otherwise, the session will inherit the variables the Terminal was started with."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
||||
28
policies/WindowsTerminal.admx
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- (c) 2024 Microsoft Corporation -->
|
||||
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.0" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
|
||||
<policyNamespaces>
|
||||
<target prefix="terminal" namespace="Microsoft.Policies.WindowsTerminal" />
|
||||
<using prefix="windows" namespace="Microsoft.Policies.Windows" />
|
||||
</policyNamespaces>
|
||||
<resources minRequiredRevision="1.0" />
|
||||
<supportedOn>
|
||||
<definitions>
|
||||
<definition name="SUPPORTED_WindowsTerminal_1_21" displayName="$(string.SUPPORTED_WindowsTerminal_1_21)" />
|
||||
</definitions>
|
||||
</supportedOn>
|
||||
<categories>
|
||||
<category name="WindowsTerminal" displayName="$(string.WindowsTerminal)">
|
||||
<parentCategory ref="windows:WindowsComponents" />
|
||||
</category>
|
||||
</categories>
|
||||
<policies>
|
||||
<policy name="DisabledProfileSources" class="Both" displayName="$(string.DisabledProfileSources)" explainText="$(string.DisabledProfileSourcesText)" presentation="$(presentation.DisabledProfileSources)" key="Software\Policies\Microsoft\Windows Terminal">
|
||||
<parentCategory ref="WindowsTerminal" />
|
||||
<supportedOn ref="SUPPORTED_WindowsTerminal_1_21" />
|
||||
<elements>
|
||||
<multiText id="DisabledProfileSources" valueName="DisabledProfileSources" required="true" />
|
||||
</elements>
|
||||
</policy>
|
||||
</policies>
|
||||
</policyDefinitions>
|
||||
28
policies/en-US/WindowsTerminal.adml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- (c) 2024 Microsoft Corporation -->
|
||||
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.0" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
|
||||
<displayName>Windows Terminal</displayName>
|
||||
<description>Windows Terminal</description>
|
||||
<resources>
|
||||
<stringTable>
|
||||
<string id="WindowsTerminal">Windows Terminal</string>
|
||||
<string id="SUPPORTED_WindowsTerminal_1_21">At least Windows Terminal 1.21</string>
|
||||
<string id="DisabledProfileSources">Disabled Profile Sources</string>
|
||||
<string id="DisabledProfileSourcesText">Profiles will not be generated from any sources listed here. Source names can be arbitrary strings. Potential candidates can be found as the "source" property on profile definitions in Windows Terminal's settings.json file.
|
||||
|
||||
Common sources are:
|
||||
- Windows.Terminal.Azure
|
||||
- Windows.Terminal.PowershellCore
|
||||
- Windows.Terminal.Wsl
|
||||
|
||||
For instance, setting this policy to Windows.Terminal.Wsl will disable the builtin WSL integration of Windows Terminal.
|
||||
|
||||
Note: Existing profiles will disappear from Windows Terminal after adding their source to this policy.</string>
|
||||
</stringTable>
|
||||
<presentationTable>
|
||||
<presentation id="DisabledProfileSources">
|
||||
<multiTextBox refId="DisabledProfileSources">List of disabled sources (one per line)</multiTextBox>
|
||||
</presentation>
|
||||
</presentationTable>
|
||||
</resources>
|
||||
</policyDefinitionResources>
|
||||
@@ -8,5 +8,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
|
||||
|
||||
### Fonts Included
|
||||
|
||||
* Cascadia Code, Cascadia Mono (2404.23)
|
||||
* from microsoft/cascadia-code@1034791e5fc6e060a448d2b29cd94a6c683edb36
|
||||
* Cascadia Code, Cascadia Mono (2407.24)
|
||||
* from microsoft/cascadia-code@56bcca3f2c1e4cb19458954f0e2bb4635960df91
|
||||
|
||||
@@ -186,12 +186,9 @@ catch (...)
|
||||
static UBool U_CALLCONV utextAccess(UText* ut, int64_t nativeIndex, UBool forward) noexcept
|
||||
try
|
||||
{
|
||||
if (nativeIndex < 0)
|
||||
{
|
||||
nativeIndex = 0;
|
||||
}
|
||||
|
||||
auto neededIndex = nativeIndex;
|
||||
// This will make it simpler for us to search the row that contains the nativeIndex,
|
||||
// because we'll now only need to check for `start<=index<limit` and nothing else.
|
||||
if (!forward)
|
||||
{
|
||||
neededIndex--;
|
||||
@@ -199,10 +196,12 @@ try
|
||||
|
||||
const auto& textBuffer = *static_cast<const TextBuffer*>(ut->context);
|
||||
const auto range = accessRowRange(ut);
|
||||
auto start = ut->chunkNativeStart;
|
||||
auto limit = ut->chunkNativeLimit;
|
||||
const auto startOld = ut->chunkNativeStart;
|
||||
const auto limitOld = ut->chunkNativeLimit;
|
||||
auto start = startOld;
|
||||
auto limit = limitOld;
|
||||
|
||||
if (neededIndex < start || neededIndex >= limit)
|
||||
if (neededIndex < startOld || neededIndex >= limitOld)
|
||||
{
|
||||
auto y = accessCurrentRow(ut);
|
||||
std::wstring_view text;
|
||||
@@ -215,8 +214,7 @@ try
|
||||
--y;
|
||||
if (y < range.begin)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto& row = textBuffer.GetRowByOffset(y);
|
||||
@@ -235,8 +233,7 @@ try
|
||||
++y;
|
||||
if (y >= range.end)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto& row = textBuffer.GetRowByOffset(y);
|
||||
@@ -249,38 +246,50 @@ try
|
||||
} while (neededIndex >= limit);
|
||||
}
|
||||
|
||||
if (!wasWrapForced)
|
||||
assert(start >= 0);
|
||||
// If we have already calculated the total length we can also assert that the limit is in range.
|
||||
assert(ut->p == nullptr || static_cast<size_t>(limit) <= accessLength(ut));
|
||||
|
||||
// Even if we went out-of-bounds, we still need to update the chunkContents to contain the first/last chunk.
|
||||
if (limit != limitOld)
|
||||
{
|
||||
const auto newSize = text.size() + 1;
|
||||
const auto buffer = RefcountBuffer::EnsureCapacityForOverwrite(accessBuffer(ut), newSize);
|
||||
if (!wasWrapForced)
|
||||
{
|
||||
const auto newSize = text.size() + 1;
|
||||
const auto buffer = RefcountBuffer::EnsureCapacityForOverwrite(accessBuffer(ut), newSize);
|
||||
|
||||
memcpy(&buffer->data[0], text.data(), text.size() * sizeof(wchar_t));
|
||||
til::at(buffer->data, text.size()) = L'\n';
|
||||
memcpy(&buffer->data[0], text.data(), text.size() * sizeof(wchar_t));
|
||||
til::at(buffer->data, text.size()) = L'\n';
|
||||
|
||||
text = { &buffer->data[0], newSize };
|
||||
accessBuffer(ut) = buffer;
|
||||
}
|
||||
text = { &buffer->data[0], newSize };
|
||||
accessBuffer(ut) = buffer;
|
||||
}
|
||||
|
||||
accessCurrentRow(ut) = y;
|
||||
ut->chunkNativeStart = start;
|
||||
ut->chunkNativeLimit = limit;
|
||||
ut->chunkLength = gsl::narrow_cast<int32_t>(text.size());
|
||||
accessCurrentRow(ut) = y;
|
||||
ut->chunkNativeStart = start;
|
||||
ut->chunkNativeLimit = limit;
|
||||
ut->chunkLength = gsl::narrow_cast<int32_t>(text.size());
|
||||
#pragma warning(suppress : 26490) // Don't use reinterpret_cast (type.1).
|
||||
ut->chunkContents = reinterpret_cast<const char16_t*>(text.data());
|
||||
ut->nativeIndexingLimit = ut->chunkLength;
|
||||
ut->chunkContents = reinterpret_cast<const char16_t*>(text.data());
|
||||
ut->nativeIndexingLimit = ut->chunkLength;
|
||||
}
|
||||
}
|
||||
|
||||
auto offset = gsl::narrow_cast<int32_t>(nativeIndex - start);
|
||||
|
||||
// The ICU documentation is a little bit misleading. It states:
|
||||
// > @param forward [...] If true, start<=index<limit. If false, [...] start<index<=limit.
|
||||
// but that's just for finding the target chunk. The chunkOffset is not actually constrained to that!
|
||||
// std::clamp will perform a<=b<=c, which is what we want.
|
||||
const auto clampedIndex = std::clamp(nativeIndex, start, limit);
|
||||
auto offset = gsl::narrow_cast<int32_t>(clampedIndex - start);
|
||||
// Don't leave the offset on a trailing surrogate pair. See U16_SET_CP_START.
|
||||
// This assumes that the TextBuffer contains valid UTF-16 which may theoretically not be the case.
|
||||
if (offset > 0 && offset < ut->chunkLength && U16_IS_TRAIL(til::at(ut->chunkContents, offset)))
|
||||
{
|
||||
offset--;
|
||||
}
|
||||
|
||||
ut->chunkOffset = offset;
|
||||
return true;
|
||||
|
||||
return neededIndex >= start && neededIndex < limit;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
@@ -8,35 +8,37 @@
|
||||
|
||||
using namespace Microsoft::Console::Types;
|
||||
|
||||
bool Search::IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive) const noexcept
|
||||
bool Search::IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags) const noexcept
|
||||
{
|
||||
return _renderData != &renderData ||
|
||||
_needle != needle ||
|
||||
_caseInsensitive != caseInsensitive ||
|
||||
_flags != flags ||
|
||||
_lastMutationId != renderData.GetTextBuffer().GetLastMutationId();
|
||||
}
|
||||
|
||||
bool Search::Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive, bool reverse)
|
||||
void Search::Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags, bool reverse)
|
||||
{
|
||||
const auto& textBuffer = renderData.GetTextBuffer();
|
||||
|
||||
_renderData = &renderData;
|
||||
_needle = needle;
|
||||
_caseInsensitive = caseInsensitive;
|
||||
_flags = flags;
|
||||
_lastMutationId = textBuffer.GetLastMutationId();
|
||||
|
||||
_results = textBuffer.SearchText(needle, caseInsensitive);
|
||||
auto result = textBuffer.SearchText(needle, _flags);
|
||||
_ok = result.has_value();
|
||||
_results = std::move(result).value_or(std::vector<til::point_span>{});
|
||||
_index = reverse ? gsl::narrow_cast<ptrdiff_t>(_results.size()) - 1 : 0;
|
||||
_step = reverse ? -1 : 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Search::MoveToCurrentSelection()
|
||||
{
|
||||
if (_renderData->IsSelectionActive())
|
||||
{
|
||||
MoveToPoint(_renderData->GetTextBuffer().ScreenToBufferPosition(_renderData->GetSelectionAnchor()));
|
||||
}
|
||||
else if (const auto span = _renderData->GetSearchHighlightFocused())
|
||||
{
|
||||
MoveToPoint(_step > 0 ? span->start : span->end);
|
||||
}
|
||||
}
|
||||
|
||||
void Search::MoveToPoint(const til::point anchor) noexcept
|
||||
@@ -144,3 +146,8 @@ ptrdiff_t Search::CurrentMatch() const noexcept
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
|
||||
bool Search::IsOk() const noexcept
|
||||
{
|
||||
return _ok;
|
||||
}
|
||||
|
||||
@@ -20,15 +20,24 @@ Revision History:
|
||||
#include "textBuffer.hpp"
|
||||
#include "../renderer/inc/IRenderData.hpp"
|
||||
|
||||
enum class SearchFlag : unsigned int
|
||||
{
|
||||
None = 0,
|
||||
|
||||
CaseInsensitive = 1 << 0,
|
||||
RegularExpression = 1 << 1,
|
||||
};
|
||||
|
||||
DEFINE_ENUM_FLAG_OPERATORS(SearchFlag);
|
||||
|
||||
class Search final
|
||||
{
|
||||
public:
|
||||
Search() = default;
|
||||
|
||||
bool IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive) const noexcept;
|
||||
bool Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive, bool reverse);
|
||||
bool IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags) const noexcept;
|
||||
void Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags, bool reverse);
|
||||
|
||||
void MoveToCurrentSelection();
|
||||
void MoveToPoint(til::point anchor) noexcept;
|
||||
void MovePastPoint(til::point anchor) noexcept;
|
||||
void FindNext(bool reverse) noexcept;
|
||||
@@ -39,14 +48,16 @@ public:
|
||||
const std::vector<til::point_span>& Results() const noexcept;
|
||||
std::vector<til::point_span>&& ExtractResults() noexcept;
|
||||
ptrdiff_t CurrentMatch() const noexcept;
|
||||
bool IsOk() const noexcept;
|
||||
|
||||
private:
|
||||
// _renderData is a pointer so that Search() is constexpr default constructable.
|
||||
Microsoft::Console::Render::IRenderData* _renderData = nullptr;
|
||||
std::wstring _needle;
|
||||
bool _caseInsensitive = false;
|
||||
SearchFlag _flags{};
|
||||
uint64_t _lastMutationId = 0;
|
||||
|
||||
bool _ok{ false };
|
||||
std::vector<til::point_span> _results;
|
||||
ptrdiff_t _index = 0;
|
||||
ptrdiff_t _step = 0;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../../types/inc/GlyphWidth.hpp"
|
||||
#include "../renderer/base/renderer.hpp"
|
||||
#include "../types/inc/utils.hpp"
|
||||
#include "search.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace Microsoft::Console::Types;
|
||||
@@ -2789,7 +2790,7 @@ void TextBuffer::Serialize(const wchar_t* destination) const
|
||||
// In other words, we can only skip \x1b[K = Erase in Line, if both the first/last attribute are the default attribute.
|
||||
static constexpr TextAttribute defaultAttr;
|
||||
const auto trimTrailingWhitespaces = it == last && lastCharX < newX;
|
||||
const auto clearToEndOfLine = trimTrailingWhitespaces && beg->value != defaultAttr || beg->value != defaultAttr;
|
||||
const auto clearToEndOfLine = trimTrailingWhitespaces && (beg->value != defaultAttr || last->value != defaultAttr);
|
||||
|
||||
if (trimTrailingWhitespaces)
|
||||
{
|
||||
@@ -3040,6 +3041,15 @@ void TextBuffer::Reflow(TextBuffer& oldBuffer, TextBuffer& newBuffer, const View
|
||||
}
|
||||
}
|
||||
|
||||
// The for loop right after this if condition will copy entire rows of attributes at a time.
|
||||
// This assumes of course that the "write cursor" (newX, newY) is at the start of a row.
|
||||
// If we didn't check for this, we may otherwise copy attributes from a later row into a previous one.
|
||||
if (newX != 0)
|
||||
{
|
||||
newX = 0;
|
||||
newY++;
|
||||
}
|
||||
|
||||
// Finish copying buffer attributes to remaining rows below the last
|
||||
// printable character. This is to fix the `color 2f` scenario, where you
|
||||
// change the buffer colors then resize and everything below the last
|
||||
@@ -3184,14 +3194,15 @@ void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
|
||||
|
||||
// Searches through the entire (committed) text buffer for `needle` and returns the coordinates in absolute coordinates.
|
||||
// The end coordinates of the returned ranges are considered inclusive.
|
||||
std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& needle, bool caseInsensitive) const
|
||||
std::optional<std::vector<til::point_span>> TextBuffer::SearchText(const std::wstring_view& needle, SearchFlag flags) const
|
||||
{
|
||||
return SearchText(needle, caseInsensitive, 0, til::CoordTypeMax);
|
||||
return SearchText(needle, flags, 0, til::CoordTypeMax);
|
||||
}
|
||||
|
||||
// Searches through the given rows [rowBeg,rowEnd) for `needle` and returns the coordinates in absolute coordinates.
|
||||
// While the end coordinates of the returned ranges are considered inclusive, the [rowBeg,rowEnd) range is half-open.
|
||||
std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& needle, bool caseInsensitive, til::CoordType rowBeg, til::CoordType rowEnd) const
|
||||
// Returns nullopt if the parameters were invalid (e.g. regex search was requested with an invalid regex)
|
||||
std::optional<std::vector<til::point_span>> TextBuffer::SearchText(const std::wstring_view& needle, SearchFlag flags, til::CoordType rowBeg, til::CoordType rowEnd) const
|
||||
{
|
||||
rowEnd = std::min(rowEnd, _estimateOffsetOfLastCommittedRow() + 1);
|
||||
|
||||
@@ -3205,11 +3216,25 @@ std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& nee
|
||||
|
||||
auto text = ICU::UTextFromTextBuffer(*this, rowBeg, rowEnd);
|
||||
|
||||
uint32_t flags = UREGEX_LITERAL;
|
||||
WI_SetFlagIf(flags, UREGEX_CASE_INSENSITIVE, caseInsensitive);
|
||||
uint32_t icuFlags{ 0 };
|
||||
WI_SetFlagIf(icuFlags, UREGEX_CASE_INSENSITIVE, WI_IsFlagSet(flags, SearchFlag::CaseInsensitive));
|
||||
|
||||
if (WI_IsFlagSet(flags, SearchFlag::RegularExpression))
|
||||
{
|
||||
WI_SetFlag(icuFlags, UREGEX_MULTILINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
WI_SetFlag(icuFlags, UREGEX_LITERAL);
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const auto re = ICU::CreateRegex(needle, flags, &status);
|
||||
const auto re = ICU::CreateRegex(needle, icuFlags, &status);
|
||||
if (status > U_ZERO_ERROR)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
uregex_setUText(re.get(), &text, &status);
|
||||
|
||||
if (uregex_find(re.get(), -1, &status))
|
||||
|
||||
@@ -58,6 +58,7 @@ filling in the last row, and updating the screen.
|
||||
#include "../buffer/out/textBufferTextIterator.hpp"
|
||||
|
||||
struct URegularExpression;
|
||||
enum class SearchFlag : unsigned int;
|
||||
|
||||
namespace Microsoft::Console::Render
|
||||
{
|
||||
@@ -293,8 +294,8 @@ public:
|
||||
|
||||
static void Reflow(TextBuffer& oldBuffer, TextBuffer& newBuffer, const Microsoft::Console::Types::Viewport* lastCharacterViewport = nullptr, PositionInformation* positionInfo = nullptr);
|
||||
|
||||
std::vector<til::point_span> SearchText(const std::wstring_view& needle, bool caseInsensitive) const;
|
||||
std::vector<til::point_span> SearchText(const std::wstring_view& needle, bool caseInsensitive, til::CoordType rowBeg, til::CoordType rowEnd) const;
|
||||
std::optional<std::vector<til::point_span>> SearchText(const std::wstring_view& needle, SearchFlag flags) const;
|
||||
std::optional<std::vector<til::point_span>> SearchText(const std::wstring_view& needle, SearchFlag flags, til::CoordType rowBeg, til::CoordType rowEnd) const;
|
||||
|
||||
// Mark handling
|
||||
std::vector<ScrollMark> GetMarkRows() const;
|
||||
|
||||
@@ -589,13 +589,13 @@ namespace
|
||||
TestBuffer{
|
||||
{ 2, 5 }, // reduce width aggressively
|
||||
{
|
||||
{ L" ", true },
|
||||
{ L" ", true },
|
||||
{ L" ", true },
|
||||
{ L" ", true },
|
||||
{ L" ", false },
|
||||
{ L" ", true },
|
||||
{ L" ", true },
|
||||
{ L" ", true },
|
||||
{ L" ", true },
|
||||
},
|
||||
{ 1, 0 },
|
||||
{ 1, 4 },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "WexTestClass.h"
|
||||
#include "../textBuffer.hpp"
|
||||
#include "../../renderer/inc/DummyRenderer.hpp"
|
||||
#include "../search.h"
|
||||
|
||||
template<>
|
||||
class WEX::TestExecution::VerifyOutputTraits<std::vector<til::point_span>>
|
||||
@@ -49,15 +50,15 @@ class UTextAdapterTests
|
||||
};
|
||||
|
||||
auto expected = std::vector{ s(0, 2), s(8, 10) };
|
||||
auto actual = buffer.SearchText(L"abc", false);
|
||||
auto actual = buffer.SearchText(L"abc", SearchFlag::None);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
expected = std::vector{ s(5, 5) };
|
||||
actual = buffer.SearchText(L"𝒷", false);
|
||||
actual = buffer.SearchText(L"𝒷", SearchFlag::None);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
|
||||
expected = std::vector{ s(12, 15) };
|
||||
actual = buffer.SearchText(L"ネコ", false);
|
||||
actual = buffer.SearchText(L"ネコ", SearchFlag::None);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
};
|
||||
|
||||
BIN
src/cascadia/CascadiaPackage/ProfileIcons/vs-cmd.scale-100.png
Normal file
|
After Width: | Height: | Size: 433 B |
BIN
src/cascadia/CascadiaPackage/ProfileIcons/vs-cmd.scale-150.png
Normal file
|
After Width: | Height: | Size: 804 B |
BIN
src/cascadia/CascadiaPackage/ProfileIcons/vs-cmd.scale-200.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 758 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/cascadia/CascadiaPackage/ProfileIcons/vs-pwsh.scale-100.png
Normal file
|
After Width: | Height: | Size: 819 B |
BIN
src/cascadia/CascadiaPackage/ProfileIcons/vs-pwsh.scale-150.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/cascadia/CascadiaPackage/ProfileIcons/vs-pwsh.scale-200.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
@@ -154,7 +154,7 @@
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppDescription" xml:space="preserve">
|
||||
<value>Nová Terminál Windows</value>
|
||||
<value>Nový Terminál Windows</value>
|
||||
</data>
|
||||
<data name="AppDescriptionPre" xml:space="preserve">
|
||||
<value>Terminál Windows s náhledem připravovaných funkcí</value>
|
||||
@@ -164,11 +164,11 @@
|
||||
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
|
||||
</data>
|
||||
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
|
||||
<value>Otevřít náhled &aplikace Terminal</value>
|
||||
<value>Otevřít &náhled Terminálu</value>
|
||||
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
|
||||
</data>
|
||||
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
|
||||
<value>Otevřít v aplikaci &Terminal</value>
|
||||
<value>Otevřít v &Terminálu</value>
|
||||
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -96,7 +96,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
|
||||
peasant.ShowNotificationIconRequested([this](auto&&, auto&&) { ShowNotificationIconRequested.raise(*this, nullptr); });
|
||||
peasant.HideNotificationIconRequested([this](auto&&, auto&&) { HideNotificationIconRequested.raise(*this, nullptr); });
|
||||
peasant.QuitAllRequested({ this, &Monarch::_handleQuitAll });
|
||||
|
||||
{
|
||||
std::unique_lock lock{ _peasantsMutex };
|
||||
@@ -134,7 +133,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
// - <none> used
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||
void Monarch::QuitAll()
|
||||
{
|
||||
if (_quitting.exchange(true, std::memory_order_relaxed))
|
||||
{
|
||||
@@ -166,12 +165,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
{
|
||||
peasantSearch->second.Quit();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Somehow we don't have our own peasant, this should never happen.
|
||||
// We are trying to quit anyways so just fail here.
|
||||
assert(peasantSearch != _peasants.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
|
||||
uint64_t AddPeasant(winrt::Microsoft::Terminal::Remoting::IPeasant peasant);
|
||||
void SignalClose(const uint64_t peasantId);
|
||||
void QuitAll();
|
||||
|
||||
uint64_t GetNumberOfPeasants();
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace Microsoft.Terminal.Remoting
|
||||
void HandleActivatePeasant(WindowActivatedArgs args);
|
||||
void SummonWindow(SummonWindowSelectionArgs args);
|
||||
void SignalClose(UInt64 peasantId);
|
||||
void QuitAll();
|
||||
|
||||
void SummonAllWindows();
|
||||
Boolean DoesQuakeWindowExist();
|
||||
|
||||
@@ -260,22 +260,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||
}
|
||||
|
||||
void Peasant::RequestQuitAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
QuitAllRequested.raise(*this, nullptr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Peasant_RequestQuit",
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||
}
|
||||
|
||||
void Peasant::AttachContentToWindow(Remoting::AttachRequest request)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
|
||||
void RequestShowNotificationIcon();
|
||||
void RequestHideNotificationIcon();
|
||||
void RequestQuitAll();
|
||||
void Quit();
|
||||
|
||||
void AttachContentToWindow(Remoting::AttachRequest request);
|
||||
@@ -76,7 +75,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
|
||||
til::typed_event<> ShowNotificationIconRequested;
|
||||
til::typed_event<> HideNotificationIconRequested;
|
||||
til::typed_event<> QuitAllRequested;
|
||||
til::typed_event<> QuitRequested;
|
||||
|
||||
til::typed_event<winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::AttachRequest> AttachRequested;
|
||||
|
||||
@@ -80,7 +80,6 @@ namespace Microsoft.Terminal.Remoting
|
||||
|
||||
void RequestShowNotificationIcon();
|
||||
void RequestHideNotificationIcon();
|
||||
void RequestQuitAll();
|
||||
void Quit();
|
||||
|
||||
void AttachContentToWindow(AttachRequest request);
|
||||
@@ -95,7 +94,6 @@ namespace Microsoft.Terminal.Remoting
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> ShowNotificationIconRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> HideNotificationIconRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> QuitAllRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, AttachRequest> AttachRequested;
|
||||
|
||||
@@ -130,6 +130,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
// We connected to a monarch instance, not us though. This won't hit
|
||||
// in isolated mode.
|
||||
|
||||
LOG_IF_FAILED(CoAllowSetForegroundWindow(winrt::get_unknown(_monarch), nullptr));
|
||||
|
||||
// Send the commandline over to the monarch process
|
||||
if (_proposeToMonarch(args))
|
||||
{
|
||||
@@ -373,6 +375,18 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
WindowClosed.raise(s, e);
|
||||
}
|
||||
|
||||
void WindowManager::QuitAll()
|
||||
{
|
||||
if (_monarch)
|
||||
{
|
||||
try
|
||||
{
|
||||
_monarch.QuitAll();
|
||||
}
|
||||
CATCH_LOG()
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::SignalClose(const Remoting::Peasant& peasant)
|
||||
{
|
||||
if (_monarch)
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
Remoting::Peasant CreatePeasant(const Remoting::WindowRequestedArgs& args);
|
||||
|
||||
void SignalClose(const Remoting::Peasant& peasant);
|
||||
void QuitAll();
|
||||
void SummonWindow(const Remoting::SummonWindowSelectionArgs& args);
|
||||
void SummonAllWindows();
|
||||
Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Terminal::Remoting::PeasantInfo> GetPeasantInfos();
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Microsoft.Terminal.Remoting
|
||||
Peasant CreatePeasant(WindowRequestedArgs args);
|
||||
|
||||
void SignalClose(Peasant p);
|
||||
void QuitAll();
|
||||
|
||||
void UpdateActiveTabTitle(String title, Peasant p);
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleCloseWindow(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
CloseRequested.raise(nullptr, nullptr);
|
||||
CloseWindow();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,27 @@
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="2" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="ListItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<ListViewItem HorizontalContentAlignment="Stretch"
|
||||
@@ -69,12 +90,12 @@
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Background="{ThemeResource FlyoutPresenterBackground}"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Style="{StaticResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
|
||||
|
||||
<TextBlock AutomationProperties.AccessibilityView="Raw"
|
||||
FontSize="12"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Style="{StaticResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind Item.KeyChordText, Mode=OneWay}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
@@ -118,12 +139,12 @@
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Style="{StaticResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
|
||||
|
||||
<TextBlock AutomationProperties.AccessibilityView="Raw"
|
||||
FontSize="12"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Style="{StaticResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind Item.KeyChordText, Mode=OneWay}" />
|
||||
</Border>
|
||||
|
||||
@@ -212,79 +233,6 @@
|
||||
GeneralItemTemplate="{StaticResource GeneralItemTemplate}"
|
||||
NestedItemTemplate="{StaticResource NestedItemTemplate}"
|
||||
TabItemTemplate="{StaticResource TabItemTemplate}" />
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="2" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="2" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
|
||||
<!-- ParsedCommandLineText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
@@ -368,7 +316,7 @@
|
||||
Padding="16,12"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Style="{ThemeResource ParsedCommandLineBorderStyle}"
|
||||
Style="{StaticResource ParsedCommandLineBorderStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParsedCommandLineText), Mode=OneWay}">
|
||||
|
||||
<ScrollViewer MaxHeight="200"
|
||||
|
||||
@@ -27,10 +27,10 @@ static const int CombinedPaneBorderSize = 2 * PaneBorderSize;
|
||||
static const int AnimationDurationInMilliseconds = 200;
|
||||
static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Windows::Foundation::TimeSpan(std::chrono::milliseconds(AnimationDurationInMilliseconds)));
|
||||
|
||||
Pane::Pane(const IPaneContent& content, const bool lastFocused) :
|
||||
_content{ content },
|
||||
Pane::Pane(IPaneContent content, const bool lastFocused) :
|
||||
_lastActive{ lastFocused }
|
||||
{
|
||||
_setPaneContent(std::move(content));
|
||||
_root.Children().Append(_borderFirst);
|
||||
|
||||
const auto& control{ _content.GetRoot() };
|
||||
@@ -467,7 +467,7 @@ std::shared_ptr<Pane> Pane::NextPane(const std::shared_ptr<Pane> targetPane)
|
||||
std::shared_ptr<Pane> nextPane = nullptr;
|
||||
auto foundTarget = false;
|
||||
|
||||
auto foundNext = WalkTree([&](auto pane) {
|
||||
auto foundNext = WalkTree([&](const auto& pane) {
|
||||
// If we are a parent pane we don't want to move to one of our children
|
||||
if (foundTarget && targetPane->_HasChild(pane))
|
||||
{
|
||||
@@ -985,6 +985,7 @@ void Pane::_ContentLostFocusHandler(const winrt::Windows::Foundation::IInspectab
|
||||
// - <none>
|
||||
void Pane::Close()
|
||||
{
|
||||
_setPaneContent(nullptr);
|
||||
// Fire our Closed event to tell our parent that we should be removed.
|
||||
Closed.raise(nullptr, nullptr);
|
||||
}
|
||||
@@ -996,7 +997,7 @@ void Pane::Shutdown()
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
_content.Close();
|
||||
_setPaneContent(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1341,7 +1342,7 @@ std::shared_ptr<Pane> Pane::DetachPane(std::shared_ptr<Pane> pane)
|
||||
detached->_ApplySplitDefinitions();
|
||||
|
||||
// Trigger the detached event on each child
|
||||
detached->WalkTree([](auto pane) {
|
||||
detached->WalkTree([](const auto& pane) {
|
||||
pane->Detached.raise(pane);
|
||||
});
|
||||
|
||||
@@ -1400,7 +1401,7 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
_borders = _GetCommonBorders();
|
||||
|
||||
// take the control, profile, id and isDefTermSession of the pane that _wasn't_ closed.
|
||||
_content = remainingChild->_content;
|
||||
_setPaneContent(remainingChild->_takePaneContent());
|
||||
_id = remainingChild->Id();
|
||||
|
||||
// Revoke the old event handlers. Remove both the handlers for the panes
|
||||
@@ -1542,7 +1543,7 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
{
|
||||
// update our path to our first remaining leaf
|
||||
_parentChildPath = _firstChild;
|
||||
_firstChild->WalkTree([](auto p) {
|
||||
_firstChild->WalkTree([](const auto& p) {
|
||||
if (p->_IsLeaf())
|
||||
{
|
||||
return true;
|
||||
@@ -1705,6 +1706,33 @@ void Pane::_SetupChildCloseHandlers()
|
||||
});
|
||||
}
|
||||
|
||||
// With this method you take ownership of the control from this Pane.
|
||||
// Assign it to another Pane with _setPaneContent() or Close() it.
|
||||
IPaneContent Pane::_takePaneContent()
|
||||
{
|
||||
_closeRequestedRevoker.revoke();
|
||||
return std::move(_content);
|
||||
}
|
||||
|
||||
// This method safely sets the content of the Pane. It'll ensure to revoke and
|
||||
// assign event handlers, and to Close() the existing content if there's any.
|
||||
// The new content can be nullptr to remove any content.
|
||||
void Pane::_setPaneContent(IPaneContent content)
|
||||
{
|
||||
// The IPaneContent::Close() implementation may be buggy and raise the CloseRequested event again.
|
||||
// _takePaneContent() avoids this as it revokes the event handler.
|
||||
if (const auto c = _takePaneContent())
|
||||
{
|
||||
c.Close();
|
||||
}
|
||||
|
||||
if (content)
|
||||
{
|
||||
_content = std::move(content);
|
||||
_closeRequestedRevoker = _content.CloseRequested(winrt::auto_revoke, [this](auto&&, auto&&) { Close(); });
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up row/column definitions for this pane. There are three total
|
||||
// row/cols. The middle one is for the separator. The first and third are for
|
||||
@@ -2255,8 +2283,7 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
|
||||
else
|
||||
{
|
||||
// Move our control, guid, isDefTermSession into the first one.
|
||||
_firstChild = std::make_shared<Pane>(_content);
|
||||
_content = nullptr;
|
||||
_firstChild = std::make_shared<Pane>(_takePaneContent());
|
||||
_firstChild->_broadcastEnabled = _broadcastEnabled;
|
||||
}
|
||||
|
||||
@@ -2398,7 +2425,7 @@ void Pane::Id(uint32_t id) noexcept
|
||||
bool Pane::FocusPane(const uint32_t id)
|
||||
{
|
||||
// Always clear the parent child path if we are focusing a leaf
|
||||
return WalkTree([=](auto p) {
|
||||
return WalkTree([=](const auto& p) {
|
||||
p->_parentChildPath.reset();
|
||||
if (p->_id == id)
|
||||
{
|
||||
@@ -2421,7 +2448,7 @@ bool Pane::FocusPane(const uint32_t id)
|
||||
// - true if focus was set
|
||||
bool Pane::FocusPane(const std::shared_ptr<Pane> pane)
|
||||
{
|
||||
return WalkTree([&](auto p) {
|
||||
return WalkTree([&](const auto& p) {
|
||||
if (p == pane)
|
||||
{
|
||||
p->_Focus();
|
||||
@@ -2451,6 +2478,11 @@ bool Pane::_HasChild(const std::shared_ptr<Pane> child)
|
||||
});
|
||||
}
|
||||
|
||||
winrt::TerminalApp::TerminalPaneContent Pane::_getTerminalContent() const
|
||||
{
|
||||
return _IsLeaf() ? _content.try_as<winrt::TerminalApp::TerminalPaneContent>() : nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Recursive function that finds a pane with the given ID
|
||||
// Arguments:
|
||||
@@ -2923,13 +2955,13 @@ bool Pane::ContainsReadOnly() const
|
||||
// - <none>
|
||||
void Pane::CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& states)
|
||||
{
|
||||
if (_IsLeaf())
|
||||
if (_content)
|
||||
{
|
||||
auto tbState{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>(_content.TaskbarState(),
|
||||
_content.TaskbarProgress()) };
|
||||
states.push_back(tbState);
|
||||
}
|
||||
else
|
||||
else if (_firstChild && _secondChild)
|
||||
{
|
||||
_firstChild->CollectTaskbarStates(states);
|
||||
_secondChild->CollectTaskbarStates(states);
|
||||
|
||||
@@ -62,7 +62,7 @@ struct PaneResources
|
||||
class Pane : public std::enable_shared_from_this<Pane>
|
||||
{
|
||||
public:
|
||||
Pane(const winrt::TerminalApp::IPaneContent& content,
|
||||
Pane(winrt::TerminalApp::IPaneContent content,
|
||||
const bool lastFocused = false);
|
||||
|
||||
Pane(std::shared_ptr<Pane> first,
|
||||
@@ -248,13 +248,13 @@ private:
|
||||
|
||||
std::optional<uint32_t> _id;
|
||||
std::weak_ptr<Pane> _parentChildPath{};
|
||||
|
||||
bool _lastActive{ false };
|
||||
winrt::event_token _firstClosedToken{ 0 };
|
||||
winrt::event_token _secondClosedToken{ 0 };
|
||||
|
||||
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
|
||||
winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker;
|
||||
winrt::TerminalApp::IPaneContent::CloseRequested_revoker _closeRequestedRevoker;
|
||||
|
||||
Borders _borders{ Borders::None };
|
||||
|
||||
@@ -264,11 +264,10 @@ private:
|
||||
bool _IsLeaf() const noexcept;
|
||||
bool _HasFocusedChild() const noexcept;
|
||||
void _SetupChildCloseHandlers();
|
||||
winrt::TerminalApp::IPaneContent _takePaneContent();
|
||||
void _setPaneContent(winrt::TerminalApp::IPaneContent content);
|
||||
bool _HasChild(const std::shared_ptr<Pane> child);
|
||||
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const
|
||||
{
|
||||
return _IsLeaf() ? _content.try_as<winrt::TerminalApp::TerminalPaneContent>() : nullptr;
|
||||
}
|
||||
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const;
|
||||
|
||||
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> _Split(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppDescription" xml:space="preserve">
|
||||
<value>Nová Terminál Windows</value>
|
||||
<value>Nový Terminál Windows</value>
|
||||
</data>
|
||||
<data name="AppDescriptionPre" xml:space="preserve">
|
||||
<value>Terminál Windows s náhledem připravovaných funkcí</value>
|
||||
@@ -164,11 +164,11 @@
|
||||
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
|
||||
</data>
|
||||
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
|
||||
<value>Otevřít náhled &aplikace Terminal</value>
|
||||
<value>Otevřít &náhled Terminálu</value>
|
||||
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
|
||||
</data>
|
||||
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
|
||||
<value>Otevřít v aplikaci &Terminal</value>
|
||||
<value>Otevřít v &Terminálu</value>
|
||||
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -205,7 +205,7 @@
|
||||
<value>Dividir pestaña</value>
|
||||
</data>
|
||||
<data name="SplitPaneText" xml:space="preserve">
|
||||
<value>Panel dividido</value>
|
||||
<value>Dividir panel</value>
|
||||
</data>
|
||||
<data name="SearchWebText" xml:space="preserve">
|
||||
<value>Búsqueda en la web</value>
|
||||
|
||||
@@ -421,13 +421,13 @@
|
||||
<value>Apri nuova scheda</value>
|
||||
</data>
|
||||
<data name="NewPaneRun.Text" xml:space="preserve">
|
||||
<value>ALT + clic per dividere la finestra corrente</value>
|
||||
<value>ALT+CLIC per dividere la finestra corrente</value>
|
||||
</data>
|
||||
<data name="NewWindowRun.Text" xml:space="preserve">
|
||||
<value>MAIUSC+clic per aprire una nuova finestra</value>
|
||||
<value>MAIUSC+CLIC per aprire una nuova finestra</value>
|
||||
</data>
|
||||
<data name="ElevatedRun.Text" xml:space="preserve">
|
||||
<value>CTRL+Clic per aprire come amministratore</value>
|
||||
<value>CTRL+CLIC per aprire come amministratore</value>
|
||||
</data>
|
||||
<data name="WindowCloseButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Chiudi</value>
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="InitialJsonParseErrorText" xml:space="preserve">
|
||||
<value>파일에서 설정을 로드 하지 못했습니다. 후행 쉼표를 포함 하 여 구문 오류가 있는지 확인 합니다.</value>
|
||||
<value>파일에서 설정을 로드하지 못했습니다. 후행 쉼표를 포함하여 구문 오류가 있는지 확인합니다.</value>
|
||||
</data>
|
||||
<data name="MissingDefaultProfileText" xml:space="preserve">
|
||||
<value>첫 번째 프로필을 사용하여 프로필 목록에서 기본 프로필을 찾을 수 없습니다. "defaultProfile"이 프로필 중 하나의 GUID와 일치하는지 확인합니다.</value>
|
||||
@@ -310,7 +310,7 @@
|
||||
<value>상위 창의 백분율로 크기를 지정합니다. (0,1) 사이 값만 유효합니다.</value>
|
||||
</data>
|
||||
<data name="CmdNewTabDesc" xml:space="preserve">
|
||||
<value>새 작업 만들기</value>
|
||||
<value>새 탭 만들기</value>
|
||||
</data>
|
||||
<data name="CmdNTDesc" xml:space="preserve">
|
||||
<value>"new-tab" 하위 명령의 별칭입니다.</value>
|
||||
@@ -515,7 +515,7 @@
|
||||
<value>경고</value>
|
||||
</data>
|
||||
<data name="CloseReadOnlyDialog.Content" xml:space="preserve">
|
||||
<value>읽기 전용 터미널을 닫으려고 합니다. 계속하시겠어요?</value>
|
||||
<value>읽기 전용 터미널을 닫으려고 합니다. 계속하시겠습니까?</value>
|
||||
</data>
|
||||
<data name="LargePasteDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>취소</value>
|
||||
@@ -607,7 +607,7 @@
|
||||
<comment>{0} will be replaced with a number.</comment>
|
||||
</data>
|
||||
<data name="CrimsonColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>심홍</value>
|
||||
<value>진홍</value>
|
||||
</data>
|
||||
<data name="SteelBlueColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>강철색</value>
|
||||
|
||||
@@ -45,7 +45,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
void ScratchpadContent::Close()
|
||||
{
|
||||
CloseRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
INewContentArgs ScratchpadContent::GetNewTerminalArgs(const BuildStartupKind /* kind */) const
|
||||
|
||||
@@ -47,7 +47,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
void SettingsPaneContent::Close()
|
||||
{
|
||||
CloseRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
INewContentArgs SettingsPaneContent::GetNewTerminalArgs(const BuildStartupKind /*kind*/) const
|
||||
|
||||
@@ -48,7 +48,20 @@ namespace winrt::TerminalApp::implementation
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return eventArgs.Handled();
|
||||
const auto handled = eventArgs.Handled();
|
||||
|
||||
if (handled)
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"ActionDispatched",
|
||||
TraceLoggingDescription("Event emitted when an action was successfully performed"),
|
||||
TraceLoggingValue(static_cast<int>(actionAndArgs.Action()), "Action"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool ShortcutActionDispatch::DoAction(const ActionAndArgs& actionAndArgs)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
MinWidth="256"
|
||||
AllowFocusOnInteraction="True"
|
||||
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
|
||||
IsTabStop="True"
|
||||
@@ -99,6 +100,24 @@
|
||||
GeneralItemTemplate="{StaticResource GeneralItemTemplate}"
|
||||
NestedItemTemplate="{StaticResource NestedItemTemplate}" />
|
||||
|
||||
<!--
|
||||
Remove all item animations from the suggestions UI. They're
|
||||
entirely too slow to let that UI be usable.
|
||||
-->
|
||||
<Style x:Key="NoAnimationsPlease"
|
||||
TargetType="ListView">
|
||||
<Setter Property="ItemContainerTransitions">
|
||||
<Setter.Value>
|
||||
<TransitionCollection>
|
||||
<!-- (deleted transitions are left for reference for what we removed) -->
|
||||
<ContentThemeTransition />
|
||||
<!--<AddDeleteThemeTransition/>-->
|
||||
<!--<ReorderThemeTransition/>-->
|
||||
<!--<EntranceThemeTransition IsStaggeringEnabled="False"/>-->
|
||||
</TransitionCollection>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
@@ -203,7 +222,8 @@
|
||||
ItemClick="_listItemClicked"
|
||||
ItemsSource="{x:Bind FilteredActions}"
|
||||
SelectionChanged="_listItemSelectionChanged"
|
||||
SelectionMode="Single" />
|
||||
SelectionMode="Single"
|
||||
Style="{StaticResource NoAnimationsPlease}" />
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
@@ -739,7 +739,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Clean read-only mode to prevent additional prompt if closing the pane triggers closing of a hosting tab
|
||||
pane->WalkTree([](auto p) {
|
||||
pane->WalkTree([](const auto& p) {
|
||||
if (const auto control{ p->GetTerminalControl() })
|
||||
{
|
||||
if (control.ReadOnly())
|
||||
|
||||
@@ -1899,7 +1899,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TerminalPage::PersistState()
|
||||
{
|
||||
if (_startupState != StartupState::Initialized)
|
||||
// This method may be called for a window even if it hasn't had a tab yet or lost all of them.
|
||||
// We shouldn't persist such windows.
|
||||
const auto tabCount = _tabs.Size();
|
||||
if (_startupState != StartupState::Initialized || tabCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1915,7 +1918,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// if the focused tab was not the last tab, restore that
|
||||
auto idx = _GetFocusedTabIndex();
|
||||
if (idx && idx != _tabs.Size() - 1)
|
||||
if (idx && idx != tabCount - 1)
|
||||
{
|
||||
ActionAndArgs action;
|
||||
action.Action(ShortcutAction::SwitchToTab);
|
||||
@@ -3807,7 +3810,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// recipe for disaster. We won't ever open up a tab in this window.
|
||||
newTerminalArgs.Elevate(false);
|
||||
const auto newPane = _MakePane(newTerminalArgs, nullptr, connection);
|
||||
newPane->WalkTree([](auto pane) {
|
||||
newPane->WalkTree([](const auto& pane) {
|
||||
pane->FinalizeConfigurationGivenDefault();
|
||||
});
|
||||
_CreateNewTabFromPane(newPane);
|
||||
|
||||
@@ -186,7 +186,6 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
til::typed_event<IInspectable, IInspectable> SummonWindowRequested;
|
||||
|
||||
til::typed_event<IInspectable, IInspectable> CloseRequested;
|
||||
til::typed_event<IInspectable, IInspectable> OpenSystemMenu;
|
||||
til::typed_event<IInspectable, IInspectable> QuitRequested;
|
||||
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs> ShowWindowChanged;
|
||||
|
||||
@@ -97,7 +97,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CloseRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.ShowWindowArgs> ShowWindowChanged;
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellPlayer = nullptr;
|
||||
_bellPlayerCreated = false;
|
||||
}
|
||||
|
||||
CloseRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
winrt::hstring TerminalPaneContent::Icon() const
|
||||
@@ -239,19 +237,20 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (_profile)
|
||||
{
|
||||
if (_isDefTermSession && _profile.CloseOnExit() == CloseOnExitMode::Automatic)
|
||||
{
|
||||
// For 'automatic', we only care about the connection state if we were launched by Terminal
|
||||
// Since we were launched via defterm, ignore the connection state (i.e. we treat the
|
||||
// close on exit mode as 'always', see GH #13325 for discussion)
|
||||
Close();
|
||||
}
|
||||
|
||||
const auto mode = _profile.CloseOnExit();
|
||||
if ((mode == CloseOnExitMode::Always) ||
|
||||
((mode == CloseOnExitMode::Graceful || mode == CloseOnExitMode::Automatic) && newConnectionState == ConnectionState::Closed))
|
||||
|
||||
if (
|
||||
// This one is obvious: If the user asked for "always" we do just that.
|
||||
(mode == CloseOnExitMode::Always) ||
|
||||
// Otherwise, and unless the user asked for the opposite of "always",
|
||||
// close the pane when the connection closed gracefully (not failed).
|
||||
(mode != CloseOnExitMode::Never && newConnectionState == ConnectionState::Closed) ||
|
||||
// However, defterm handoff can result in Windows Terminal randomly opening which may be annoying,
|
||||
// so by default we should at least always close the pane, even if the command failed.
|
||||
// See GH #13325 for discussion.
|
||||
(mode == CloseOnExitMode::Automatic && _isDefTermSession))
|
||||
{
|
||||
Close();
|
||||
CloseRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +330,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPaneContent::_closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||
{
|
||||
Close();
|
||||
CloseRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_restartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
auto firstId = _nextPaneId;
|
||||
|
||||
_rootPane->WalkTree([&](std::shared_ptr<Pane> pane) {
|
||||
_rootPane->WalkTree([&](const auto& pane) {
|
||||
// update the IDs on each pane
|
||||
if (pane->_IsLeaf())
|
||||
{
|
||||
@@ -203,7 +203,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_rootPane->WalkTree([&](std::shared_ptr<Pane> pane) {
|
||||
_rootPane->WalkTree([&](const auto& pane) {
|
||||
// Attach event handlers to each new pane
|
||||
_AttachEventHandlersToPane(pane);
|
||||
if (auto content = pane->GetContent())
|
||||
@@ -275,7 +275,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_UpdateHeaderControlMaxWidth();
|
||||
|
||||
// Update the settings on all our panes.
|
||||
_rootPane->WalkTree([&](auto pane) {
|
||||
_rootPane->WalkTree([&](const auto& pane) {
|
||||
pane->UpdateSettings(settings);
|
||||
return false;
|
||||
});
|
||||
@@ -534,7 +534,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Add the new event handlers to the new pane(s)
|
||||
// and update their ids.
|
||||
pane->WalkTree([&](auto p) {
|
||||
pane->WalkTree([&](const auto& p) {
|
||||
_AttachEventHandlersToPane(p);
|
||||
if (p->_IsLeaf())
|
||||
{
|
||||
@@ -624,7 +624,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// manually.
|
||||
_rootPane->Closed(_rootClosedToken);
|
||||
auto p = _rootPane;
|
||||
p->WalkTree([](auto pane) {
|
||||
p->WalkTree([](const auto& pane) {
|
||||
pane->Detached.raise(pane);
|
||||
});
|
||||
|
||||
@@ -650,7 +650,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Add the new event handlers to the new pane(s)
|
||||
// and update their ids.
|
||||
pane->WalkTree([&](auto p) {
|
||||
pane->WalkTree([&](const auto& p) {
|
||||
_AttachEventHandlersToPane(p);
|
||||
if (p->_IsLeaf())
|
||||
{
|
||||
@@ -947,32 +947,6 @@ namespace winrt::TerminalApp::implementation
|
||||
auto dispatcher = TabViewItem().Dispatcher();
|
||||
ContentEventTokens events{};
|
||||
|
||||
events.CloseRequested = content.CloseRequested(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](auto sender, auto&&) -> winrt::fire_and_forget {
|
||||
// Don't forget! this ^^^^^^^^ sender can't be a reference, this is a async callback.
|
||||
|
||||
// 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() })
|
||||
{
|
||||
if (const auto content{ sender.try_as<TerminalApp::IPaneContent>() })
|
||||
{
|
||||
tab->_rootPane->WalkTree([content](std::shared_ptr<Pane> pane) {
|
||||
if (pane->GetContent() == content)
|
||||
{
|
||||
pane->Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
events.TitleChanged = content.TitleChanged(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](auto&&, auto&&) -> winrt::fire_and_forget {
|
||||
|
||||
@@ -134,7 +134,6 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::TerminalApp::IPaneContent::ConnectionStateChanged_revoker ConnectionStateChanged;
|
||||
winrt::TerminalApp::IPaneContent::ReadOnlyChanged_revoker ReadOnlyChanged;
|
||||
winrt::TerminalApp::IPaneContent::FocusRequested_revoker FocusRequested;
|
||||
winrt::TerminalApp::IPaneContent::CloseRequested_revoker CloseRequested;
|
||||
|
||||
// These events literally only apply if the content is a TermControl.
|
||||
winrt::Microsoft::Terminal::Control::TermControl::KeySent_revoker KeySent;
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace winrt::TerminalApp::implementation
|
||||
AppLogic::Current()->NotifyRootInitialized();
|
||||
}
|
||||
|
||||
void TerminalWindow::Quit()
|
||||
void TerminalWindow::PersistState()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
@@ -767,13 +767,22 @@ namespace winrt::TerminalApp::implementation
|
||||
// definitely not on OUR UI thread.
|
||||
winrt::fire_and_forget TerminalWindow::UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args)
|
||||
{
|
||||
_settings = args.NewSettings();
|
||||
// GH#17620: We have a bug somewhere where a window doesn't get unregistered from the window list.
|
||||
// This causes UpdateSettings calls where the thread dispatcher is already null.
|
||||
const auto dispatcher = _root->Dispatcher();
|
||||
if (!dispatcher)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
const auto weakThis{ get_weak() };
|
||||
co_await wil::resume_foreground(_root->Dispatcher());
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
|
||||
// Back on our UI thread...
|
||||
if (auto logic{ weakThis.get() })
|
||||
{
|
||||
_settings = args.NewSettings();
|
||||
|
||||
// Update the settings in TerminalPage
|
||||
// We're on our UI thread right now, so this is safe
|
||||
_root->SetSettings(_settings, true);
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void Create();
|
||||
|
||||
void Quit();
|
||||
void PersistState();
|
||||
|
||||
winrt::fire_and_forget UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args);
|
||||
|
||||
@@ -223,7 +223,6 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(CloseRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, CloseRequested);
|
||||
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
|
||||
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
|
||||
FORWARDED_TYPED_EVENT(ShowWindowChanged, Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs, _root, ShowWindowChanged);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace TerminalApp
|
||||
Boolean ShouldImmediatelyHandoffToElevated();
|
||||
void HandoffToElevated();
|
||||
|
||||
void Quit();
|
||||
void PersistState();
|
||||
|
||||
Windows.UI.Xaml.UIElement GetRoot();
|
||||
|
||||
@@ -127,7 +127,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CloseRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.SystemMenuChangeArgs> SystemMenuChangeRequested;
|
||||
|
||||
@@ -180,12 +180,14 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
const HANDLE hRef,
|
||||
const HANDLE hServerProcess,
|
||||
const HANDLE hClientProcess,
|
||||
TERMINAL_STARTUP_INFO startupInfo) :
|
||||
const TERMINAL_STARTUP_INFO& startupInfo) :
|
||||
_rows{ 25 },
|
||||
_cols{ 80 },
|
||||
_inPipe{ hIn },
|
||||
_outPipe{ hOut }
|
||||
{
|
||||
_sessionId = Utils::CreateGuid();
|
||||
|
||||
THROW_IF_FAILED(ConptyPackPseudoConsole(hServerProcess, hRef, hSig, &_hPC));
|
||||
_piClient.hProcess = hClientProcess;
|
||||
|
||||
@@ -429,12 +431,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
try
|
||||
{
|
||||
// GH#11556 - make sure to format the error code to this string as an UNSIGNED int
|
||||
winrt::hstring exitText{ fmt::format(std::wstring_view{ RS_(L"ProcessExited") }, fmt::format(_errorFormat, status)) };
|
||||
TerminalOutput.raise(L"\r\n");
|
||||
TerminalOutput.raise(exitText);
|
||||
TerminalOutput.raise(L"\r\n");
|
||||
TerminalOutput.raise(RS_(L"CtrlDToClose"));
|
||||
TerminalOutput.raise(L"\r\n");
|
||||
const auto msg1 = fmt::format(std::wstring_view{ RS_(L"ProcessExited") }, fmt::format(_errorFormat, status));
|
||||
const auto msg2 = RS_(L"CtrlDToClose");
|
||||
const auto msg = fmt::format(FMT_COMPILE(L"\r\n{}\r\n{}\r\n"), msg1, msg2);
|
||||
TerminalOutput.raise(msg);
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
@@ -677,7 +677,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
void ConptyConnection::closePseudoConsoleAsync(HPCON hPC) noexcept
|
||||
{
|
||||
::ConptyClosePseudoConsoleTimeout(hPC, 0);
|
||||
::ConptyClosePseudoConsole(hPC);
|
||||
}
|
||||
|
||||
HRESULT ConptyConnection::NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client, TERMINAL_STARTUP_INFO startupInfo) noexcept
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
const HANDLE hRef,
|
||||
const HANDLE hServerProcess,
|
||||
const HANDLE hClientProcess,
|
||||
TERMINAL_STARTUP_INFO startupInfo);
|
||||
const TERMINAL_STARTUP_INFO& startupInfo);
|
||||
|
||||
ConptyConnection() noexcept = default;
|
||||
void Initialize(const Windows::Foundation::Collections::ValueSet& settings);
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Connection(connection);
|
||||
|
||||
_terminal->SetWriteInputCallback([this](std::wstring_view wstr) {
|
||||
_sendInputToConnection(wstr);
|
||||
_pendingResponses.append(wstr);
|
||||
});
|
||||
|
||||
// GH#8969: pre-seed working directory to prevent potential races
|
||||
@@ -161,7 +161,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
std::chrono::milliseconds{ 100 },
|
||||
[weakTerminal = std::weak_ptr{ _terminal }, weakThis = get_weak(), dispatcher = _dispatcher]() {
|
||||
dispatcher.TryEnqueue(DispatcherQueuePriority::Normal, [weakThis]() {
|
||||
if (const auto self = weakThis.get(); !self->_IsClosing())
|
||||
if (const auto self = weakThis.get(); self && !self->_IsClosing())
|
||||
{
|
||||
self->OutputIdle.raise(*self, nullptr);
|
||||
}
|
||||
@@ -179,7 +179,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_dispatcher,
|
||||
std::chrono::milliseconds{ 8 },
|
||||
[weakThis = get_weak()](const auto& update) {
|
||||
if (auto core{ weakThis.get() }; !core->_IsClosing())
|
||||
if (auto core{ weakThis.get() }; core && !core->_IsClosing())
|
||||
{
|
||||
core->ScrollPositionChanged.raise(*core, update);
|
||||
}
|
||||
@@ -398,6 +398,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ControlCore::_sendInputToConnection(std::wstring_view wstr)
|
||||
{
|
||||
_connection.WriteInput(wstr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Writes the given sequence as input to the active terminal connection,
|
||||
// Arguments:
|
||||
// - wstr: the string of characters to write to the terminal connection.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ControlCore::SendInput(const std::wstring_view wstr)
|
||||
{
|
||||
if (wstr.empty())
|
||||
{
|
||||
@@ -414,21 +425,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
_connection.WriteInput(wstr);
|
||||
_sendInputToConnection(wstr);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Writes the given sequence as input to the active terminal connection,
|
||||
// Arguments:
|
||||
// - wstr: the string of characters to write to the terminal connection.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ControlCore::SendInput(const std::wstring_view wstr)
|
||||
{
|
||||
_sendInputToConnection(wstr);
|
||||
}
|
||||
|
||||
bool ControlCore::SendCharEvent(const wchar_t ch,
|
||||
const WORD scanCode,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers)
|
||||
@@ -464,7 +464,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
if (out)
|
||||
{
|
||||
_sendInputToConnection(*out);
|
||||
SendInput(*out);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -622,7 +622,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
if (out)
|
||||
{
|
||||
_sendInputToConnection(*out);
|
||||
SendInput(*out);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -641,7 +641,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
if (out)
|
||||
{
|
||||
_sendInputToConnection(*out);
|
||||
SendInput(*out);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1392,7 +1392,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// It's important to not hold the terminal lock while calling this function as sending the data may take a long time.
|
||||
_sendInputToConnection(filtered);
|
||||
SendInput(filtered);
|
||||
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
_terminal->ClearSelection();
|
||||
@@ -1654,38 +1654,44 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool resetOnly)
|
||||
SearchResults ControlCore::Search(SearchRequest request)
|
||||
{
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), text, !caseSensitive);
|
||||
|
||||
if (searchInvalidated || !resetOnly)
|
||||
SearchFlag flags{};
|
||||
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !request.CaseSensitive);
|
||||
WI_SetFlagIf(flags, SearchFlag::RegularExpression, request.RegularExpression);
|
||||
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), request.Text, flags);
|
||||
|
||||
if (searchInvalidated || !request.ResetOnly)
|
||||
{
|
||||
std::vector<til::point_span> oldResults;
|
||||
til::point_span oldFocused;
|
||||
|
||||
if (const auto focused = _terminal->GetSearchHighlightFocused())
|
||||
{
|
||||
oldFocused = *focused;
|
||||
}
|
||||
|
||||
if (searchInvalidated)
|
||||
{
|
||||
oldResults = _searcher.ExtractResults();
|
||||
_searcher.Reset(*_terminal.get(), text, !caseSensitive, !goForward);
|
||||
|
||||
if (SnapSearchResultToSelection())
|
||||
{
|
||||
_searcher.MoveToCurrentSelection();
|
||||
SnapSearchResultToSelection(false);
|
||||
}
|
||||
|
||||
_searcher.Reset(*_terminal.get(), request.Text, flags, !request.GoForward);
|
||||
_terminal->SetSearchHighlights(_searcher.Results());
|
||||
}
|
||||
else
|
||||
|
||||
if (!request.ResetOnly)
|
||||
{
|
||||
_searcher.FindNext(!goForward);
|
||||
_searcher.FindNext(!request.GoForward);
|
||||
}
|
||||
|
||||
if (const auto idx = _searcher.CurrentMatch(); idx >= 0)
|
||||
{
|
||||
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx));
|
||||
}
|
||||
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(std::max<ptrdiff_t>(0, _searcher.CurrentMatch())));
|
||||
_renderer->TriggerSearchHighlight(oldResults);
|
||||
|
||||
if (const auto focused = _terminal->GetSearchHighlightFocused(); focused && *focused != oldFocused)
|
||||
{
|
||||
_terminal->ScrollToSearchHighlight(request.ScrollOffset);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t totalMatches = 0;
|
||||
@@ -1700,6 +1706,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
.TotalMatches = totalMatches,
|
||||
.CurrentMatch = currentMatch,
|
||||
.SearchInvalidated = searchInvalidated,
|
||||
.SearchRegexInvalid = !_searcher.IsOk(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1712,27 +1719,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
_terminal->SetSearchHighlights({});
|
||||
_terminal->SetSearchHighlightFocused({});
|
||||
_terminal->SetSearchHighlightFocused(0);
|
||||
_renderer->TriggerSearchHighlight(_searcher.Results());
|
||||
_searcher = {};
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tells ControlCore to snap the current search result index to currently
|
||||
// selected text if the search was started using it.
|
||||
void ControlCore::SnapSearchResultToSelection(bool shouldSnap) noexcept
|
||||
{
|
||||
_snapSearchResultToSelection = shouldSnap;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns true, if we should snap the current search result index to
|
||||
// the currently selected text after a new search is started, else false.
|
||||
bool ControlCore::SnapSearchResultToSelection() const noexcept
|
||||
{
|
||||
return _snapSearchResultToSelection;
|
||||
}
|
||||
|
||||
void ControlCore::Close()
|
||||
{
|
||||
if (!_IsClosing())
|
||||
@@ -2083,7 +2074,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Sending input requires that we're unlocked, because
|
||||
// writing the input pipe may block indefinitely.
|
||||
const auto suspension = _terminal->SuspendLock();
|
||||
_sendInputToConnection(buffer);
|
||||
SendInput(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2140,6 +2131,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_terminal->Write(hstr);
|
||||
}
|
||||
|
||||
if (!_pendingResponses.empty())
|
||||
{
|
||||
_sendInputToConnection(_pendingResponses);
|
||||
_pendingResponses.clear();
|
||||
}
|
||||
|
||||
// Start the throttled update of where our hyperlinks are.
|
||||
const auto shared = _shared.lock_shared();
|
||||
if (shared->outputIdle)
|
||||
@@ -2235,20 +2232,39 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
std::vector<winrt::hstring> commands;
|
||||
const auto bufferCommands{ textBuffer.Commands() };
|
||||
for (const auto& commandInBuffer : bufferCommands)
|
||||
{
|
||||
const auto strEnd = commandInBuffer.find_last_not_of(UNICODE_SPACE);
|
||||
|
||||
auto trimToHstring = [](const auto& s) -> winrt::hstring {
|
||||
const auto strEnd = s.find_last_not_of(UNICODE_SPACE);
|
||||
if (strEnd != std::string::npos)
|
||||
{
|
||||
const auto trimmed = commandInBuffer.substr(0, strEnd + 1);
|
||||
const auto trimmed = s.substr(0, strEnd + 1);
|
||||
return winrt::hstring{ trimmed };
|
||||
}
|
||||
return winrt::hstring{ L"" };
|
||||
};
|
||||
|
||||
commands.push_back(winrt::hstring{ trimmed });
|
||||
const auto currentCommand = _terminal->CurrentCommand();
|
||||
const auto trimmedCurrentCommand = trimToHstring(currentCommand);
|
||||
|
||||
for (const auto& commandInBuffer : bufferCommands)
|
||||
{
|
||||
if (const auto hstr{ trimToHstring(commandInBuffer) };
|
||||
(!hstr.empty() && hstr != trimmedCurrentCommand))
|
||||
{
|
||||
commands.push_back(hstr);
|
||||
}
|
||||
}
|
||||
|
||||
auto context = winrt::make_self<CommandHistoryContext>(std::move(commands));
|
||||
context->CurrentCommandline(winrt::hstring{ _terminal->CurrentCommand() });
|
||||
// If the very last thing in the list of recent commands, is exactly the
|
||||
// same as the current command, then let's not include it in the
|
||||
// history. It's literally the thing the user has typed, RIGHT now.
|
||||
if (!commands.empty() && commands.back() == trimmedCurrentCommand)
|
||||
{
|
||||
commands.pop_back();
|
||||
}
|
||||
|
||||
auto context = winrt::make_self<CommandHistoryContext>(std::move(commands));
|
||||
context->CurrentCommandline(trimmedCurrentCommand);
|
||||
return *context;
|
||||
}
|
||||
|
||||
@@ -2424,7 +2440,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// _sendInputToConnection() asserts that we aren't in focus mode,
|
||||
// but window focus events are always fine to send.
|
||||
_connection.WriteInput(*out);
|
||||
_sendInputToConnection(*out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,11 +219,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void SetSelectionAnchor(const til::point position);
|
||||
void SetEndSelectionPoint(const til::point position);
|
||||
|
||||
SearchResults Search(const std::wstring_view& text, bool goForward, bool caseSensitive, bool reset);
|
||||
SearchResults Search(SearchRequest request);
|
||||
const std::vector<til::point_span>& SearchResultRows() const noexcept;
|
||||
void ClearSearch();
|
||||
void SnapSearchResultToSelection(bool snap) noexcept;
|
||||
bool SnapSearchResultToSelection() const noexcept;
|
||||
|
||||
void LeftClickOnTerminal(const til::point terminalPosition,
|
||||
const int numberOfClicks,
|
||||
@@ -307,6 +305,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
winrt::com_ptr<ControlSettings> _settings{ nullptr };
|
||||
|
||||
std::shared_ptr<::Microsoft::Terminal::Core::Terminal> _terminal{ nullptr };
|
||||
std::wstring _pendingResponses;
|
||||
|
||||
// NOTE: _renderEngine must be ordered before _renderer.
|
||||
//
|
||||
|
||||
@@ -49,11 +49,22 @@ namespace Microsoft.Terminal.Control
|
||||
Boolean EndAtRightBoundary;
|
||||
};
|
||||
|
||||
struct SearchRequest
|
||||
{
|
||||
String Text;
|
||||
Boolean GoForward;
|
||||
Boolean CaseSensitive;
|
||||
Boolean RegularExpression;
|
||||
Boolean ResetOnly;
|
||||
Int32 ScrollOffset;
|
||||
};
|
||||
|
||||
struct SearchResults
|
||||
{
|
||||
Int32 TotalMatches;
|
||||
Int32 CurrentMatch;
|
||||
Boolean SearchInvalidated;
|
||||
Boolean SearchRegexInvalid;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SelectionColor
|
||||
@@ -134,9 +145,8 @@ namespace Microsoft.Terminal.Control
|
||||
void ResumeRendering();
|
||||
void BlinkAttributeTick();
|
||||
|
||||
SearchResults Search(String text, Boolean goForward, Boolean caseSensitive, Boolean reset);
|
||||
SearchResults Search(SearchRequest request);
|
||||
void ClearSearch();
|
||||
Boolean SnapSearchResultToSelection;
|
||||
|
||||
Microsoft.Terminal.Core.Color ForegroundColor { get; };
|
||||
Microsoft.Terminal.Core.Color BackgroundColor { get; };
|
||||
|
||||
@@ -734,6 +734,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - true if the connection we were created with was a WSL profile.
|
||||
bool ControlInteractivity::ManglePathsForWsl()
|
||||
{
|
||||
return _core->Settings().ProfileSource() == L"Windows.Terminal.Wsl";
|
||||
const auto source{ _core->Settings().ProfileSource() };
|
||||
return til::equals_insensitive_ascii(source, L"Windows.Terminal.Wsl") || til::equals_insensitive_ascii(source, L"Microsoft.WSL");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ namespace Microsoft.Terminal.Control
|
||||
Direct3D11,
|
||||
};
|
||||
|
||||
enum DefaultInputScope
|
||||
{
|
||||
Default,
|
||||
AlphanumericHalfWidth,
|
||||
};
|
||||
|
||||
runtimeclass FontSizeChangedArgs
|
||||
{
|
||||
Int32 Width { get; };
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace Microsoft.Terminal.Control
|
||||
Microsoft.Terminal.Control.GraphicsAPI GraphicsAPI { get; };
|
||||
Boolean DisablePartialInvalidation { get; };
|
||||
Boolean SoftwareRendering { get; };
|
||||
Microsoft.Terminal.Control.DefaultInputScope DefaultInputScope { get; };
|
||||
Boolean ShowMarks { get; };
|
||||
Boolean UseBackgroundImageForWindow { get; };
|
||||
Boolean RightClickContextMenu { get; };
|
||||
|
||||
@@ -217,6 +217,10 @@ Installieren Sie entweder die fehlende Schriftart, oder wählen Sie eine andere
|
||||
<value>Die folgenden Schriftarten wurden nicht gefunden: {0}. Installieren Sie sie, oder wählen Sie andere Schriftarten aus.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Ihre Version von MacType ist mit dieser Anwendung nicht kompatibel. Bitte aktualisieren Sie auf Version 2023.5.31 oder höher.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Unerwarteter Rendererfehler: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@ Installieren Sie entweder die fehlende Schriftart, oder wählen Sie eine andere
|
||||
<value>Wiederhergestellt</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Regulärer Ausdruck</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Suche nach regulärem Ausdruck</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>invalid</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@ Please either install the missing font or choose another one.</value>
|
||||
<value>Unable to find the following fonts: {0}. Please either install them or choose different fonts.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Your version of MacType is incompatible with this application. Please update to version 2023.5.31 or later.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Renderer encountered an unexpected error: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@ Please either install the missing font or choose another one.</value>
|
||||
<value>Restored</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
</root>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Regular Expression</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Regular Expression Search</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>invalid</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -217,6 +217,10 @@ Instale la fuente que falta o elija otra.</value>
|
||||
<value>No se pueden encontrar las siguientes fuentes: {0}. Instálelas o elija fuentes diferentes.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Su versión de MacType no es compatible con esta aplicación. Actualice a la versión 2023.5.31 o posterior.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>El representador encontró un error inesperado: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@ Instale la fuente que falta o elija otra.</value>
|
||||
<value>Se ha restaurado</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Expresión regular</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Búsqueda de expresiones regulares</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>no válido</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@ Installez la police manquante ou choisissez-en une autre.</value>
|
||||
<value>Impossible de trouver les polices suivantes : {0}. Installez-les ou choisissez d’autres polices.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Votre version de MacType est incompatible avec cette application. Veuillez mettre à jour la version 2023.5.31 ou une version ultérieure.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Le convertisseur a rencontré une erreur inattendue : {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@ Installez la police manquante ou choisissez-en une autre.</value>
|
||||
<value>Restaurée</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Expression régulière</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Recherche d’expressions régulières</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>incorrect</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -176,7 +176,7 @@
|
||||
<value>Riprendi</value>
|
||||
</data>
|
||||
<data name="HowToOpenRun.Text" xml:space="preserve">
|
||||
<value>CTRL+clic per aprire il collegamento</value>
|
||||
<value>CTRL+CLIC per aprire il collegamento</value>
|
||||
</data>
|
||||
<data name="TermControl_NoMatch" xml:space="preserve">
|
||||
<value>Nessun risultato</value>
|
||||
@@ -217,6 +217,10 @@ Installare il tipo di carattere mancante o sceglierne un altro.</value>
|
||||
<value>Impossibile trovare i tipi di carattere seguenti: {0}. Installarli o scegliere tipi di carattere diversi.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>La versione di MacType è incompatibile con questa applicazione. Aggiornare alla versione 2023.5.31 o successiva.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Errore imprevisto del renderer: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@ Installare il tipo di carattere mancante o sceglierne un altro.</value>
|
||||
<value>Ripristinato</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Espressione regolare</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Ricerca di espressioni regolari</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>non valido</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>次のフォントが見つかりません: {0}。インストールするか、別のフォントを選択してください。</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>お使いのバージョンの MacType は、このアプリケーションと互換性がありません。バージョン 2023.5.31 以降に更新してください。</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>レンダラーで予期しないエラーが発生しました: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>復元済み</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>正規表現</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>正規表現検索</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>invalid</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>다음 글꼴을 찾을 수 없습니다. {0}. 설치하거나 다른 글꼴을 선택하세요.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>MacType 버전이 이 애플리케이션과 호환되지 않습니다. 버전 2023.5.31 이상으로 업데이트하세요.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>렌더러에서 예기치 않은 오류가 발생했습니다. {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>복원됨</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>정규 표현식</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>정규식 검색</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>invalid</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@ Instale a fonte ausente ou escolha outra.</value>
|
||||
<value>Não é possível localizar as seguintes fontes: {0}. Instale-os ou escolha fontes diferentes.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Sua versão do MacType é incompatível com este aplicativo. Atualize para a versão 2023.5.31 ou posterior.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>O renderizador encontrou um erro inesperado: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@ Instale a fonte ausente ou escolha outra.</value>
|
||||
<value>Restaurado</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Expressão Regular</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Pesquisa de Expressão Regular</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>inválido</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>Цйǻьľė ŧò ƒіņð τнė ƒσℓľоŵíпğ ƒŏптš: {0}. Рĺёąšė èìťђėг ïŋŝţăĺℓ тħēm ôѓ ςђоōѕз ðįƒƒеřęʼnţ ƒóπţś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Ύοϋг νέяšîǿŋ бƒ MacType їš ìⁿçомрāţΐвŀè шιťћ тĥĩѕ ªрφℓíċąţіōņ. Рĺэаşέ űφđаτє τő νзřѕíбʼn 2023.5.31 бŗ ℓâţëґ. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Гêʼnďěѓēŗ эήçομήťєřĕď åń µŋέхρэсťèð ęґяöя: {0:#010×} {1} !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>Яєŝťòяёď !!</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Ґéğùℓаŕ Έхρřëśѕΐöл !!! !!</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Ŕēĝűŀаѓ Ë×φгёŝşιол Ѕêªŕ¢ћ !!! !!! !</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>іʼnναłīď !!</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>Цйǻьľė ŧò ƒіņð τнė ƒσℓľоŵíпğ ƒŏптš: {0}. Рĺёąšė èìťђėг ïŋŝţăĺℓ тħēm ôѓ ςђоōѕз ðįƒƒеřęʼnţ ƒóπţś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Ύοϋг νέяšîǿŋ бƒ MacType їš ìⁿçомрāţΐвŀè шιťћ тĥĩѕ ªрφℓíċąţіōņ. Рĺэаşέ űφđаτє τő νзřѕíбʼn 2023.5.31 бŗ ℓâţëґ. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Гêʼnďěѓēŗ эήçομήťєřĕď åń µŋέхρэсťèð ęґяöя: {0:#010×} {1} !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>Яєŝťòяёď !!</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Ґéğùℓаŕ Έхρřëśѕΐöл !!! !!</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Ŕēĝűŀаѓ Ë×φгёŝşιол Ѕêªŕ¢ћ !!! !!! !</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>іʼnναłīď !!</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>Цйǻьľė ŧò ƒіņð τнė ƒσℓľоŵíпğ ƒŏптš: {0}. Рĺёąšė èìťђėг ïŋŝţăĺℓ тħēm ôѓ ςђоōѕз ðįƒƒеřęʼnţ ƒóπţś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Ύοϋг νέяšîǿŋ бƒ MacType їš ìⁿçомрāţΐвŀè шιťћ тĥĩѕ ªрφℓíċąţіōņ. Рĺэаşέ űφđаτє τő νзřѕíбʼn 2023.5.31 бŗ ℓâţëґ. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>Гêʼnďěѓēŗ эήçομήťєřĕď åń µŋέхρэсťèð ęґяöя: {0:#010×} {1} !!! !!! !!! !!! !!! !</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>Яєŝťòяёď !!</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Ґéğùℓаŕ Έхρřëśѕΐöл !!! !!</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Ŕēĝűŀаѓ Ë×φгёŝşιол Ѕêªŕ¢ћ !!! !!! !</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>іʼnναłīď !!</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>Не удалось найти следующие шрифты: {0}. Установите их или выберите другие шрифты.</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>Эта версия MacType несовместима с этим приложением. Обновите версию до 2023.5.31 или более поздней.</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>В обработчике произошла непредвиденная ошибка: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>Восстановлено</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Регулярное выражение</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Поиск регулярного выражения</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>недопустимый</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>找不到以下字体: {0}。请安装它们或选择其他字体。</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>你的 MacType 版本与此应用程序不兼容。请更新到版本 2023.5.31 或更高版本。</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>呈现器遇到错误: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>已还原</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>正则表达式</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>正则表达式搜索</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>无效</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -217,6 +217,10 @@
|
||||
<value>找不到下列字型: {0}。請安裝它們,或選擇其他字型。</value>
|
||||
<comment>{Locked="{0}"} This is a warning dialog shown when the user selects a font that isn't installed.</comment>
|
||||
</data>
|
||||
<data name="RendererErrorMacType" xml:space="preserve">
|
||||
<value>您的 MacType 版本與此應用程式不相容。請更新至 2023.5.31 版或更新版本。</value>
|
||||
<comment>{Locked="2023.5.31","MacType"}</comment>
|
||||
</data>
|
||||
<data name="RendererErrorOther" xml:space="preserve">
|
||||
<value>轉譯器發生意外的錯誤: {0:#010x} {1}</value>
|
||||
<comment>{Locked="{0:#010x}","{1}"} {0:#010x} is a placeholder for a Windows error code (e.g. 0x88985002). {1} is the corresponding message.</comment>
|
||||
@@ -300,4 +304,16 @@
|
||||
<value>已還原</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>規則運算式</value>
|
||||
<comment>The tooltip text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchBox_RegularExpression.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>規則運算式搜尋</value>
|
||||
<comment>The accessibility description text for the button on the search box control governing the use of "regular expressions" ("regex").</comment>
|
||||
</data>
|
||||
<data name="SearchRegexInvalid" xml:space="preserve">
|
||||
<value>無效</value>
|
||||
<comment>This brief message is displayed when a regular expression is invalid.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -30,6 +30,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_focusableElements.insert(TextBox());
|
||||
_focusableElements.insert(CloseButton());
|
||||
_focusableElements.insert(CaseSensitivityButton());
|
||||
// 1.21 BACKPORT REMOVED - _focusableElements.insert(RegexButton());
|
||||
_focusableElements.insert(GoForwardButton());
|
||||
_focusableElements.insert(GoBackwardButton());
|
||||
|
||||
@@ -154,12 +155,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// search box remains in Visible state (though not really *visible*) during the
|
||||
// first load. So, we only need to apply this check here (after checking that
|
||||
// we're done initializing).
|
||||
if (Visibility() == Visibility::Visible)
|
||||
if (IsOpen())
|
||||
{
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop ongoing close animation if any
|
||||
if (CloseAnimation().GetCurrentState() == Media::Animation::ClockState::Active)
|
||||
{
|
||||
CloseAnimation().Stop();
|
||||
}
|
||||
|
||||
VisualStateManager::GoToState(*this, L"Opened", false);
|
||||
|
||||
// Call the callback only after we're in Opened state. Setting focus
|
||||
@@ -195,6 +202,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
bool SearchBoxControl::IsOpen()
|
||||
{
|
||||
return Visibility() == Visibility::Visible && CloseAnimation().GetCurrentState() != Media::Animation::ClockState::Active;
|
||||
}
|
||||
|
||||
winrt::hstring SearchBoxControl::Text()
|
||||
{
|
||||
return TextBox().Text();
|
||||
@@ -224,6 +236,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return CaseSensitivityButton().IsChecked().GetBoolean();
|
||||
}
|
||||
|
||||
bool SearchBoxControl::RegularExpression()
|
||||
{
|
||||
return false; // 1.21 BACKPORT REMOVED - RegexButton().IsChecked().GetBoolean();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handler for pressing Enter on TextBox, trigger
|
||||
// text search
|
||||
@@ -245,11 +262,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto state = CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Shift);
|
||||
if (WI_IsFlagSet(state, CoreVirtualKeyStates::Down))
|
||||
{
|
||||
Search.raise(Text(), !GoForward(), CaseSensitive());
|
||||
Search.raise(Text(), !GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
else
|
||||
{
|
||||
Search.raise(Text(), GoForward(), CaseSensitive());
|
||||
Search.raise(Text(), GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
e.Handled(true);
|
||||
}
|
||||
@@ -340,7 +357,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// kick off search
|
||||
Search.raise(Text(), GoForward(), CaseSensitive());
|
||||
Search.raise(Text(), GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -361,7 +378,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// kick off search
|
||||
Search.raise(Text(), GoForward(), CaseSensitive());
|
||||
Search.raise(Text(), GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -399,7 +416,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - <none>
|
||||
void SearchBoxControl::TextBoxTextChanged(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
SearchChanged.raise(Text(), GoForward(), CaseSensitive());
|
||||
SearchChanged.raise(Text(), GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -411,7 +428,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - <none>
|
||||
void SearchBoxControl::CaseSensitivityButtonClicked(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
SearchChanged.raise(Text(), GoForward(), CaseSensitive());
|
||||
SearchChanged.raise(Text(), GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
|
||||
void SearchBoxControl::RegexButtonClicked(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
SearchChanged.raise(Text(), GoForward(), CaseSensitive(), RegularExpression());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -504,7 +526,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
double SearchBoxControl::_GetStatusMaxWidth()
|
||||
{
|
||||
const auto fontSize = StatusBox().FontSize();
|
||||
const auto maxLength = std::max({ _TextWidth(_FormatStatus(-1, -1), fontSize),
|
||||
const auto maxLength = std::max({ _TextWidth(RS_(L"SearchRegexInvalid"), fontSize),
|
||||
_TextWidth(_FormatStatus(-1, -1), fontSize),
|
||||
_TextWidth(_FormatStatus(0, -1), fontSize),
|
||||
_TextWidth(_FormatStatus(MaximumTotalResultsToShowInStatus, MaximumTotalResultsToShowInStatus - 1), fontSize),
|
||||
_TextWidth(_FormatStatus(MaximumTotalResultsToShowInStatus + 1, MaximumTotalResultsToShowInStatus - 1), fontSize),
|
||||
@@ -521,9 +544,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - currentMatch - the index of the current match (0-based)
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void SearchBoxControl::SetStatus(int32_t totalMatches, int32_t currentMatch)
|
||||
void SearchBoxControl::SetStatus(int32_t totalMatches, int32_t currentMatch, bool searchRegexInvalid)
|
||||
{
|
||||
const auto status = _FormatStatus(totalMatches, currentMatch);
|
||||
hstring status;
|
||||
if (searchRegexInvalid)
|
||||
{
|
||||
status = RS_(L"SearchRegexInvalid");
|
||||
}
|
||||
else
|
||||
{
|
||||
status = _FormatStatus(totalMatches, currentMatch);
|
||||
}
|
||||
StatusBox().Text(status);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TextBoxKeyDown(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
||||
void Open(std::function<void()> callback);
|
||||
void Close();
|
||||
bool IsOpen();
|
||||
|
||||
winrt::hstring Text();
|
||||
bool GoForward();
|
||||
bool CaseSensitive();
|
||||
bool RegularExpression();
|
||||
void SetFocusOnTextbox();
|
||||
void PopulateTextbox(const winrt::hstring& text);
|
||||
bool ContainsFocus();
|
||||
void SetStatus(int32_t totalMatches, int32_t currentMatch);
|
||||
void SetStatus(int32_t totalMatches, int32_t currentMatch, bool searchRegexInvalid);
|
||||
void ClearStatus();
|
||||
|
||||
void GoBackwardClicked(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::UI::Xaml::RoutedEventArgs& /*e*/);
|
||||
@@ -50,6 +52,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void TextBoxTextChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void CaseSensitivityButtonClicked(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void RegexButtonClicked(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void SearchBoxPointerPressedHandler(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||
void SearchBoxPointerReleasedHandler(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||
|
||||
|
||||