mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-08 15:21:01 +00:00
Compare commits
52 Commits
release-1.
...
dev/pabhoj
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22a7a5bc5f | ||
|
|
b3997a3dad | ||
|
|
d866908eaf | ||
|
|
2e7a95ddb5 | ||
|
|
75e462441d | ||
|
|
c754f4d22d | ||
|
|
b22684e697 | ||
|
|
1b630ab6f6 | ||
|
|
cac52a9e30 | ||
|
|
94e1697a48 | ||
|
|
1de1325cd1 | ||
|
|
dc8183a525 | ||
|
|
2a7dd8b730 | ||
|
|
f685720cac | ||
|
|
205c09ccb8 | ||
|
|
799b5d4add | ||
|
|
730eb5fafd | ||
|
|
cd35bc5989 | ||
|
|
4e20a8631c | ||
|
|
1b81c6540f | ||
|
|
f4c4efc7f0 | ||
|
|
d76c70c470 | ||
|
|
ed27737233 | ||
|
|
c157f6346a | ||
|
|
9dca6c27ee | ||
|
|
7dbe741e1a | ||
|
|
fb1491a4af | ||
|
|
11b810e403 | ||
|
|
6439b4d807 | ||
|
|
78852e04ec | ||
|
|
c5fad74c54 | ||
|
|
bb03b00ebf | ||
|
|
4c333536b4 | ||
|
|
bf41a90ad8 | ||
|
|
d82af9367f | ||
|
|
77215d9d77 | ||
|
|
0154da5d33 | ||
|
|
e1086de512 | ||
|
|
fa6b066747 | ||
|
|
b699f9275f | ||
|
|
b851b0d3f4 | ||
|
|
df627c26f1 | ||
|
|
1db47ff8dc | ||
|
|
003cbe7c29 | ||
|
|
6ffc3dc7a8 | ||
|
|
1cb58a6a02 | ||
|
|
0630b18eff | ||
|
|
17d1e2437c | ||
|
|
c2f830843a | ||
|
|
1d3e1568a2 | ||
|
|
a69ce89712 | ||
|
|
9cb2bccd7f |
@@ -410,6 +410,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InteractivityOneCore", "src
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererWddmCon", "src\renderer\wddmcon\lib\wddmcon.vcxproj", "{75C6F576-18E9-4566-978A-F0A301CAC090}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Audio", "Audio", "{40BD8415-DD93-4200-8D82-498DDDC08CC8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MidiAudio", "src\audio\midi\lib\midi.vcxproj", "{3C67784E-1453-49C2-9660-483E2CC7F7AD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
AuditMode|Any CPU = AuditMode|Any CPU
|
||||
@@ -3449,6 +3453,46 @@ Global
|
||||
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x64.Build.0 = Release|x64
|
||||
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x86.ActiveCfg = Release|Win32
|
||||
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x86.Build.0 = Release|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x64.Build.0 = Debug|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x64.ActiveCfg = Release|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x64.Build.0 = Release|x64
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -3552,6 +3596,8 @@ Global
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {05500DEF-2294-41E3-AF9A-24E580B82836}
|
||||
{06EC74CB-9A12-428C-B551-8537EC964726} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
{75C6F576-18E9-4566-978A-F0A301CAC090} = {05500DEF-2294-41E3-AF9A-24E580B82836}
|
||||
{40BD8415-DD93-4200-8D82-498DDDC08CC8} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {40BD8415-DD93-4200-8D82-498DDDC08CC8}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
||||
|
||||
@@ -111,10 +111,10 @@ repository.
|
||||
|
||||
---
|
||||
|
||||
## Windows Terminal 2.0 Roadmap
|
||||
## Windows Terminal Roadmap
|
||||
|
||||
The plan for delivering Windows Terminal 2.0 [is described
|
||||
here](/doc/terminal-v2-roadmap.md) and will be updated as the project proceeds.
|
||||
The plan for the Windows Terminal [is described here](/doc/roadmap-2022.md) and
|
||||
will be updated as the project proceeds.
|
||||
|
||||
## Project Build Status
|
||||
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
|
||||
<!-- This cannot be included in another project that depends on XAML (as it would be a duplicate package ID) -->
|
||||
<package id="Microsoft.UI.Xaml" version="2.7.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
|
||||
<PGOBranch>release-1.14</PGOBranch>
|
||||
<PGOBranch>main</PGOBranch>
|
||||
|
||||
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
|
||||
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
- template: restore-nuget-steps.yml
|
||||
- steps: restore-nuget-steps.yml
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
This version should be tracked in all project packages.config files for projects that depend on Xaml.
|
||||
-->
|
||||
<TerminalMUXVersion>2.7.3-prerelease.220816001</TerminalMUXVersion>
|
||||
<TerminalMUXVersion>2.7.2-prerelease.220406002</TerminalMUXVersion>
|
||||
<!--
|
||||
For the Windows 11-specific build, we're targeting the public version of Microsoft.UI.Xaml.
|
||||
This version emits a package dependency instead of embedding the dependency in our own package.
|
||||
|
||||
This version should be tracked in build/packages.config.
|
||||
-->
|
||||
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.3</TerminalMUXVersion>
|
||||
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.1</TerminalMUXVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2022</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>14</VersionMinor>
|
||||
<VersionMinor>15</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.6.220404001" targetFramework="native" />
|
||||
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.7.3-prerelease.220816001" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.7.2-prerelease.220406002" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" developmentDependency="true" />
|
||||
|
||||
<!-- Managed packages -->
|
||||
<package id="Appium.WebDriver" version="3.0.0.2" targetFramework="net45" />
|
||||
<package id="Castle.Core" version="4.1.1" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
|
||||
<package id="Selenium.Support" version="3.5.0" targetFramework="net45" />
|
||||
<package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" />
|
||||
</packages>
|
||||
|
||||
@@ -318,6 +318,7 @@
|
||||
"moveFocus",
|
||||
"movePane",
|
||||
"swapPane",
|
||||
"markMode",
|
||||
"moveTab",
|
||||
"multipleActions",
|
||||
"newTab",
|
||||
@@ -2010,10 +2011,6 @@
|
||||
"description": "Controls what happens when the application emits a BEL character. When set to \"all\", the Terminal will play a sound, flash the taskbar icon (if the terminal window is not in focus) and flash the window. An array of specific behaviors can also be used. Supported array values include `audible`, `window` and `taskbar`. When set to \"none\", nothing will happen.",
|
||||
"$ref": "#/$defs/BellStyle"
|
||||
},
|
||||
"bellSound": {
|
||||
"description": "Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.",
|
||||
"$ref": "#/$defs/BellSound"
|
||||
},
|
||||
"closeOnExit": {
|
||||
"default": "graceful",
|
||||
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
|
||||
|
||||
@@ -22,21 +22,61 @@ Below is the schedule for when milestones will be included in release builds of
|
||||
| Milestone End Date | Milestone Name | Preview Release Blog Post |
|
||||
| ------------------ | -------------- | ------------------------- |
|
||||
| 2020-06-18 | [1.1] in Windows Terminal Preview | [Windows Terminal Preview 1.1 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-1-release/) |
|
||||
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | [Windows Terminal Preview 1.2 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-2-release/) |
|
||||
| 2020-08-31 | [1.3] in Windows Terminal Preview<br>[1.2] in Windows Terminal | [Windows Terminal Preview 1.3 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-3-release/) |
|
||||
| 2020-09-30 | [1.4] in Windows Terminal Preview<br>[1.3] in Windows Terminal | [Windows Terminal Preview 1.4 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-4-release/) |
|
||||
| 2020-11-30 | [1.5] in Windows Terminal Preview<br>[1.4] in Windows Terminal | [Windows Terminal Preview 1.5 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-5-release/) |
|
||||
| 2021-01-31 | [1.6] in Windows Terminal Preview<br>[1.5] in Windows Terminal | [Windows Terminal Preview 1.6 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-6-release/) |
|
||||
| 2021-03-01 | [1.7] in Windows Terminal Preview<br>[1.6] in Windows Terminal | [Windows Terminal Preview 1.7 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-7-release/) |
|
||||
| 2021-04-14 | [1.8] in Windows Terminal Preview<br>[1.7] in Windows Terminal | [Windows Terminal Preview 1.8 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-8-release/) |
|
||||
| 2021-05-31 | [1.9] in Windows Terminal Preview<br>[1.8] in Windows Terminal | [Windows Terminal Preview 1.9 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-9-release/) |
|
||||
| 2021-07-14 | [1.10] in Windows Terminal Preview<br>[1.9] in Windows Terminal | [Windows Terminal Preview 1.10 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-10-release/) |
|
||||
| 2021-08-31 | [1.11] in Windows Terminal Preview<br>[1.10] in Windows Terminal | [Windows Terminal Preview 1.11 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-11-release/) |
|
||||
| 2021-10-20 | [1.12] in Windows Terminal Preview<br>[1.11] in Windows Terminal | [Windows Terminal Preview 1.12 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-12-release/) |
|
||||
| | [1.13] in Windows Terminal Preview<br>[1.12] in Windows Terminal | |
|
||||
| | [1.14] in Windows Terminal Preview<br>[1.13] in Windows Terminal | |
|
||||
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | [Windows Terminal Preview 1.2 Release] |
|
||||
| 2020-08-31 | [1.3] in Windows Terminal Preview<br>[1.2] in Windows Terminal | [Windows Terminal Preview 1.3 Release] |
|
||||
| 2020-09-30 | [1.4] in Windows Terminal Preview<br>[1.3] in Windows Terminal | [Windows Terminal Preview 1.4 Release] |
|
||||
| 2020-11-30 | [1.5] in Windows Terminal Preview<br>[1.4] in Windows Terminal | [Windows Terminal Preview 1.5 Release] |
|
||||
| 2021-01-31 | [1.6] in Windows Terminal Preview<br>[1.5] in Windows Terminal | [Windows Terminal Preview 1.6 Release] |
|
||||
| 2021-03-01 | [1.7] in Windows Terminal Preview<br>[1.6] in Windows Terminal | [Windows Terminal Preview 1.7 Release] |
|
||||
| 2021-04-14 | [1.8] in Windows Terminal Preview<br>[1.7] in Windows Terminal | [Windows Terminal Preview 1.8 Release] |
|
||||
| 2021-05-31 | [1.9] in Windows Terminal Preview<br>[1.8] in Windows Terminal | [Windows Terminal Preview 1.9 Release] |
|
||||
| 2021-07-14 | [1.10] in Windows Terminal Preview<br>[1.9] in Windows Terminal | [Windows Terminal Preview 1.10 Release] |
|
||||
| 2021-08-31 | [1.11] in Windows Terminal Preview<br>[1.10] in Windows Terminal | [Windows Terminal Preview 1.11 Release] |
|
||||
| 2021-10-20 | [1.12] in Windows Terminal Preview<br>[1.11] in Windows Terminal | [Windows Terminal Preview 1.12 Release] |
|
||||
| 2022-02-03 | [1.13] in Windows Terminal Preview<br>[1.12] in Windows Terminal | [Windows Terminal Preview 1.13 Release] |
|
||||
| 2022-05-24 | [1.14] in Windows Terminal Preview<br>[1.13] in Windows Terminal | [Windows Terminal Preview 1.14 Release] |
|
||||
| | [1.15] in Windows Terminal Preview<br>[1.14] in Windows Terminal | |
|
||||
| | [1.16] in Windows Terminal Preview<br>[1.15] in Windows Terminal | |
|
||||
| | [1.17] in Windows Terminal Preview<br>[1.16] in Windows Terminal | |
|
||||
|
||||
|
||||
### Release outline
|
||||
|
||||
Below is a VERY vague outline of the remaining calendar year that was drafted late May 2022. This was drafted for internal planning purposes, as a guide. It is not meant to represent official dates. More often than not, releases are synced to official features landing, rather than arbitrary dates. Drift from this initial draft is entirely expected.
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title Proposed Terminal Releases 1.14-1.18
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d %b
|
||||
section Terminal 1.14
|
||||
Lock down & bake :done, 2022-05-06, 2w
|
||||
Release 1.14 :milestone, 2022-05-24
|
||||
section Terminal 1.15
|
||||
Features :done, a1, 2022-05-06, 4w
|
||||
Bugfix :active, a2, after a1 , 1w
|
||||
Lock down & bake :after a2 , 1w
|
||||
Release 1.15 :milestone, 2022-06-21, 0
|
||||
1.15 becomes Stable :milestone, after b3, 0
|
||||
section Terminal 1.16
|
||||
Features :b1, after a2, 4w
|
||||
Bugfix :b2, after b1 , 2w
|
||||
Lock down & bake :b3, after b2 , 2w
|
||||
Release 1.16 :milestone, after b3, 0
|
||||
1.16 becomes Stable :milestone, after c3, 0
|
||||
section Terminal 1.17
|
||||
Features :c1, after b2, 4w
|
||||
Bugfix :c2, after c1 , 2w
|
||||
Lock down & bake :c3, after c2 , 2w
|
||||
Release 1.17 :milestone, after c3, 0
|
||||
1.17 becomes Stable :milestone, after d3, 0
|
||||
section Terminal 1.18
|
||||
Features :d1, after c2, 4w
|
||||
Bugfix :d2, after d1 , 2w
|
||||
Lock down & bake :d3, after d2 , 2w
|
||||
Release 1.18 :milestone, after d3, 0
|
||||
```
|
||||
|
||||
## Issue Triage & Prioritization
|
||||
|
||||
Incoming issues/asks/etc. are triaged several times a week, labeled appropriately, and assigned to a milestone in priority order:
|
||||
@@ -62,7 +102,9 @@ Incoming issues/asks/etc. are triaged several times a week, labeled appropriatel
|
||||
[1.12]: https://github.com/microsoft/terminal/milestone/38
|
||||
[1.13]: https://github.com/microsoft/terminal/milestone/39
|
||||
[1.14]: https://github.com/microsoft/terminal/milestone/41
|
||||
|
||||
[1.15]: https://github.com/microsoft/terminal/milestone/47
|
||||
[1.16]: https://github.com/microsoft/terminal/milestone/48
|
||||
[1.17]: https://github.com/microsoft/terminal/milestone/49
|
||||
|
||||
[22H1]: https://github.com/microsoft/terminal/milestone/43
|
||||
[22H2]: https://github.com/microsoft/terminal/milestone/44
|
||||
@@ -70,3 +112,17 @@ Incoming issues/asks/etc. are triaged several times a week, labeled appropriatel
|
||||
[Backlog]: https://github.com/microsoft/terminal/milestone/45
|
||||
|
||||
[Terminal v2 Roadmap]: https://github.com/microsoft/terminal/tree/main/doc/terminal-v2-roadmap.md
|
||||
|
||||
[Windows Terminal Preview 1.2 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-2-release/
|
||||
[Windows Terminal Preview 1.3 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-3-release/
|
||||
[Windows Terminal Preview 1.4 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-4-release/
|
||||
[Windows Terminal Preview 1.5 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-5-release/
|
||||
[Windows Terminal Preview 1.6 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-6-release/
|
||||
[Windows Terminal Preview 1.7 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-7-release/
|
||||
[Windows Terminal Preview 1.8 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-8-release/
|
||||
[Windows Terminal Preview 1.9 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-9-release/
|
||||
[Windows Terminal Preview 1.10 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-10-release/
|
||||
[Windows Terminal Preview 1.11 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-11-release/
|
||||
[Windows Terminal Preview 1.12 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-12-release/
|
||||
[Windows Terminal Preview 1.13 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-13-release/
|
||||
[Windows Terminal Preview 1.14 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-14-release/
|
||||
|
||||
125
src/audio/midi/MidiAudio.cpp
Normal file
125
src/audio/midi/MidiAudio.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
#include "MidiAudio.hpp"
|
||||
#include "../terminal/parser/stateMachine.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class MidiOut
|
||||
{
|
||||
public:
|
||||
static constexpr auto NOTE_OFF = 0x80;
|
||||
static constexpr auto NOTE_ON = 0x90;
|
||||
static constexpr auto PROGRAM_CHANGE = 0xC0;
|
||||
|
||||
// We're using a square wave as an approximation of the sound that the
|
||||
// original VT525 terminals might have produced. This is probably not
|
||||
// quite right, but it works reasonably well.
|
||||
static constexpr auto SQUARE_WAVE_SYNTH = 80;
|
||||
|
||||
MidiOut() noexcept
|
||||
{
|
||||
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
|
||||
{
|
||||
midiOutOpen(&handle, MIDI_MAPPER, NULL, NULL, CALLBACK_NULL);
|
||||
OutputMessage(PROGRAM_CHANGE, SQUARE_WAVE_SYNTH);
|
||||
}
|
||||
}
|
||||
~MidiOut() noexcept
|
||||
{
|
||||
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
|
||||
{
|
||||
midiOutClose(handle);
|
||||
}
|
||||
}
|
||||
void OutputMessage(const int b1, const int b2, const int b3 = 0, const int b4 = 0) noexcept
|
||||
{
|
||||
if constexpr (Feature_DECPSViaMidiPlayer::IsEnabled())
|
||||
{
|
||||
midiOutShortMsg(handle, MAKELONG(MAKEWORD(b1, b2), MAKEWORD(b3, b4)));
|
||||
}
|
||||
}
|
||||
|
||||
MidiOut(const MidiOut&) = delete;
|
||||
MidiOut(MidiOut&&) = delete;
|
||||
MidiOut& operator=(const MidiOut&) = delete;
|
||||
MidiOut& operator=(MidiOut&&) = delete;
|
||||
|
||||
private:
|
||||
HMIDIOUT handle = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
MidiAudio::~MidiAudio() noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
#pragma warning(suppress : 26447)
|
||||
// We acquire the lock here so the class isn't destroyed while in use.
|
||||
// If this throws, we'll catch it, so the C26447 warning is bogus.
|
||||
_inUseMutex.lock();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// If the lock fails, we'll just have to live with the consequences.
|
||||
}
|
||||
}
|
||||
|
||||
void MidiAudio::Initialize()
|
||||
{
|
||||
_shutdownFuture = _shutdownPromise.get_future();
|
||||
}
|
||||
|
||||
void MidiAudio::Shutdown()
|
||||
{
|
||||
// Once the shutdown promise is set, any note that is playing will stop
|
||||
// immediately, and the Unlock call will exit the thread ASAP.
|
||||
_shutdownPromise.set_value();
|
||||
}
|
||||
|
||||
void MidiAudio::Lock()
|
||||
{
|
||||
_inUseMutex.lock();
|
||||
}
|
||||
|
||||
void MidiAudio::Unlock()
|
||||
{
|
||||
// We need to check the shutdown status before releasing the mutex,
|
||||
// because after that the class could be destroyed.
|
||||
const auto shutdownStatus = _shutdownFuture.wait_for(0s);
|
||||
_inUseMutex.unlock();
|
||||
// If the wait didn't timeout, that means the shutdown promise was set,
|
||||
// so we need to exit the thread ASAP by throwing an exception.
|
||||
if (shutdownStatus != std::future_status::timeout)
|
||||
{
|
||||
throw Microsoft::Console::VirtualTerminal::StateMachine::ShutdownException{};
|
||||
}
|
||||
}
|
||||
|
||||
void MidiAudio::PlayNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) noexcept
|
||||
try
|
||||
{
|
||||
// The MidiOut is a local static because we can only have one instance,
|
||||
// and we only want to construct it when it's actually needed.
|
||||
static MidiOut midiOut;
|
||||
|
||||
if (velocity)
|
||||
{
|
||||
midiOut.OutputMessage(MidiOut::NOTE_ON, noteNumber, velocity);
|
||||
}
|
||||
|
||||
// By waiting on the shutdown future with the duration of the note, we'll
|
||||
// either be paused for the appropriate amount of time, or we'll break out
|
||||
// of the wait early if we've been shutdown.
|
||||
_shutdownFuture.wait_for(duration);
|
||||
|
||||
if (velocity)
|
||||
{
|
||||
midiOut.OutputMessage(MidiOut::NOTE_OFF, noteNumber, velocity);
|
||||
}
|
||||
}
|
||||
CATCH_LOG()
|
||||
36
src/audio/midi/MidiAudio.hpp
Normal file
36
src/audio/midi/MidiAudio.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- MidiAudio.hpp
|
||||
|
||||
Abstract:
|
||||
This modules provide basic MIDI support with blocking sound output.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
|
||||
class MidiAudio
|
||||
{
|
||||
public:
|
||||
MidiAudio() = default;
|
||||
MidiAudio(const MidiAudio&) = delete;
|
||||
MidiAudio(MidiAudio&&) = delete;
|
||||
MidiAudio& operator=(const MidiAudio&) = delete;
|
||||
MidiAudio& operator=(MidiAudio&&) = delete;
|
||||
~MidiAudio() noexcept;
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
void PlayNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) noexcept;
|
||||
|
||||
private:
|
||||
std::promise<void> _shutdownPromise;
|
||||
std::future<void> _shutdownFuture;
|
||||
std::mutex _inUseMutex;
|
||||
};
|
||||
26
src/audio/midi/lib/midi.vcxproj
Normal file
26
src/audio/midi/lib/midi.vcxproj
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{3c67784e-1453-49c2-9660-483e2cc7f7ad}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>midi</RootNamespace>
|
||||
<ProjectName>MidiAudio</ProjectName>
|
||||
<TargetName>MidiAudio</TargetName>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)src\common.build.pre.props" />
|
||||
<Import Project="$(SolutionDir)src\common.nugetversions.props" />
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\MidiAudio.cpp" />
|
||||
<ClCompile Include="..\precomp.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\MidiAudio.hpp" />
|
||||
<ClInclude Include="..\precomp.h" />
|
||||
</ItemGroup>
|
||||
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
|
||||
<Import Project="$(SolutionDir)src\common.build.post.props" />
|
||||
<Import Project="$(SolutionDir)src\common.nugetversions.targets" />
|
||||
</Project>
|
||||
4
src/audio/midi/precomp.cpp
Normal file
4
src/audio/midi/precomp.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
30
src/audio/midi/precomp.h
Normal file
30
src/audio/midi/precomp.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- precomp.h
|
||||
|
||||
Abstract:
|
||||
- Contains external headers to include in the precompile phase of console build process.
|
||||
- Avoid including internal project headers. Instead include them only in the classes that need them (helps with test project building).
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
|
||||
// This includes support libraries from the CRT, STL, WIL, and GSL
|
||||
#include "LibraryIncludes.h"
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#define NOMCX
|
||||
#define NOHELP
|
||||
#define NOCOMM
|
||||
#endif
|
||||
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
|
||||
// clang-format on
|
||||
@@ -11,8 +11,8 @@
|
||||
// - attr - the default text attribute
|
||||
// Return Value:
|
||||
// - constructed object
|
||||
ATTR_ROW::ATTR_ROW(const uint16_t width, const TextAttribute attr) :
|
||||
_data(width, attr) {}
|
||||
ATTR_ROW::ATTR_ROW(const til::CoordType width, const TextAttribute attr) :
|
||||
_data(gsl::narrow_cast<uint16_t>(width), attr) {}
|
||||
|
||||
// Routine Description:
|
||||
// - Sets all properties of the ATTR_ROW to default values
|
||||
@@ -32,9 +32,9 @@ void ATTR_ROW::Reset(const TextAttribute attr)
|
||||
// - newWidth - The new width of the row.
|
||||
// Return Value:
|
||||
// - <none>, throws exceptions on failures.
|
||||
void ATTR_ROW::Resize(const uint16_t newWidth)
|
||||
void ATTR_ROW::Resize(const til::CoordType newWidth)
|
||||
{
|
||||
_data.resize_trailing_extent(newWidth);
|
||||
_data.resize_trailing_extent(gsl::narrow<uint16_t>(newWidth));
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -45,9 +45,9 @@ void ATTR_ROW::Resize(const uint16_t newWidth)
|
||||
// - the text attribute at column
|
||||
// Note:
|
||||
// - will throw on error
|
||||
TextAttribute ATTR_ROW::GetAttrByColumn(const uint16_t column) const
|
||||
TextAttribute ATTR_ROW::GetAttrByColumn(const til::CoordType column) const
|
||||
{
|
||||
return _data.at(column);
|
||||
return _data.at(gsl::narrow<uint16_t>(column));
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -74,7 +74,7 @@ std::vector<uint16_t> ATTR_ROW::GetHyperlinks() const
|
||||
// - attr - Attribute (color) to fill remaining characters with
|
||||
// Return Value:
|
||||
// - <none>
|
||||
bool ATTR_ROW::SetAttrToEnd(const uint16_t beginIndex, const TextAttribute attr)
|
||||
bool ATTR_ROW::SetAttrToEnd(const til::CoordType beginIndex, const TextAttribute attr)
|
||||
{
|
||||
_data.replace(gsl::narrow<uint16_t>(beginIndex), _data.size(), attr);
|
||||
return true;
|
||||
@@ -103,9 +103,9 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
|
||||
// - newAttr: The attribute to merge into this row.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ATTR_ROW::Replace(const uint16_t beginIndex, const uint16_t endIndex, const TextAttribute& newAttr)
|
||||
void ATTR_ROW::Replace(const til::CoordType beginIndex, const til::CoordType endIndex, const TextAttribute& newAttr)
|
||||
{
|
||||
_data.replace(beginIndex, endIndex, newAttr);
|
||||
_data.replace(gsl::narrow<uint16_t>(beginIndex), gsl::narrow<uint16_t>(endIndex), newAttr);
|
||||
}
|
||||
|
||||
ATTR_ROW::const_iterator ATTR_ROW::begin() const noexcept
|
||||
|
||||
@@ -30,7 +30,7 @@ class ATTR_ROW final
|
||||
public:
|
||||
using const_iterator = rle_vector::const_iterator;
|
||||
|
||||
ATTR_ROW(uint16_t width, TextAttribute attr);
|
||||
ATTR_ROW(til::CoordType width, TextAttribute attr);
|
||||
|
||||
~ATTR_ROW() = default;
|
||||
|
||||
@@ -40,13 +40,13 @@ public:
|
||||
noexcept = default;
|
||||
ATTR_ROW& operator=(ATTR_ROW&&) noexcept = default;
|
||||
|
||||
TextAttribute GetAttrByColumn(uint16_t column) const;
|
||||
TextAttribute GetAttrByColumn(til::CoordType column) const;
|
||||
std::vector<uint16_t> GetHyperlinks() const;
|
||||
|
||||
bool SetAttrToEnd(uint16_t beginIndex, TextAttribute attr);
|
||||
bool SetAttrToEnd(til::CoordType beginIndex, TextAttribute attr);
|
||||
void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith);
|
||||
void Resize(uint16_t newWidth);
|
||||
void Replace(uint16_t beginIndex, uint16_t endIndex, const TextAttribute& newAttr);
|
||||
void Resize(til::CoordType newWidth);
|
||||
void Replace(til::CoordType beginIndex, til::CoordType endIndex, const TextAttribute& newAttr);
|
||||
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// Note: will through if unable to allocate char/attribute buffers
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26447) // small_vector's constructor says it can throw but it should not given how we use it. This suppresses this error for the AuditMode build.
|
||||
CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
|
||||
CharRow::CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept :
|
||||
_data(rowWidth, value_type()),
|
||||
_pParent{ FAIL_FAST_IF_NULL(pParent) }
|
||||
{
|
||||
@@ -30,9 +30,9 @@ CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the size of the row
|
||||
size_t CharRow::size() const noexcept
|
||||
til::CoordType CharRow::size() const noexcept
|
||||
{
|
||||
return _data.size();
|
||||
return gsl::narrow_cast<til::CoordType>(_data.size());
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -55,7 +55,7 @@ void CharRow::Reset() noexcept
|
||||
// - newSize - the new width of the character and attributes rows
|
||||
// Return Value:
|
||||
// - S_OK on success, otherwise relevant error code
|
||||
[[nodiscard]] HRESULT CharRow::Resize(const size_t newSize) noexcept
|
||||
[[nodiscard]] HRESULT CharRow::Resize(const til::CoordType newSize) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -93,14 +93,14 @@ typename CharRow::const_iterator CharRow::cend() const noexcept
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The calculated left boundary of the internal string.
|
||||
size_t CharRow::MeasureLeft() const noexcept
|
||||
til::CoordType CharRow::MeasureLeft() const noexcept
|
||||
{
|
||||
auto it = _data.cbegin();
|
||||
while (it != _data.cend() && it->IsSpace())
|
||||
{
|
||||
++it;
|
||||
}
|
||||
return it - _data.cbegin();
|
||||
return gsl::narrow_cast<til::CoordType>(it - _data.cbegin());
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -109,17 +109,17 @@ size_t CharRow::MeasureLeft() const noexcept
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The calculated right boundary of the internal string.
|
||||
size_t CharRow::MeasureRight() const
|
||||
til::CoordType CharRow::MeasureRight() const
|
||||
{
|
||||
auto it = _data.crbegin();
|
||||
while (it != _data.crend() && it->IsSpace())
|
||||
{
|
||||
++it;
|
||||
}
|
||||
return _data.crend() - it;
|
||||
return gsl::narrow_cast<til::CoordType>(_data.crend() - it);
|
||||
}
|
||||
|
||||
void CharRow::ClearCell(const size_t column)
|
||||
void CharRow::ClearCell(const til::CoordType column)
|
||||
{
|
||||
_data.at(column).Reset();
|
||||
}
|
||||
@@ -149,7 +149,7 @@ bool CharRow::ContainsText() const noexcept
|
||||
// Return Value:
|
||||
// - the attribute
|
||||
// Note: will throw exception if column is out of bounds
|
||||
const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
|
||||
const DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column) const
|
||||
{
|
||||
return _data.at(column).DbcsAttr();
|
||||
}
|
||||
@@ -161,7 +161,7 @@ const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
|
||||
// Return Value:
|
||||
// - the attribute
|
||||
// Note: will throw exception if column is out of bounds
|
||||
DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
|
||||
DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column)
|
||||
{
|
||||
return _data.at(column).DbcsAttr();
|
||||
}
|
||||
@@ -173,7 +173,7 @@ DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
|
||||
// Return Value:
|
||||
// - <none>
|
||||
// Note: will throw exception if column is out of bounds
|
||||
void CharRow::ClearGlyph(const size_t column)
|
||||
void CharRow::ClearGlyph(const til::CoordType column)
|
||||
{
|
||||
_data.at(column).EraseChars();
|
||||
}
|
||||
@@ -185,9 +185,9 @@ void CharRow::ClearGlyph(const size_t column)
|
||||
// Return Value:
|
||||
// - text data at column
|
||||
// - Note: will throw exception if column is out of bounds
|
||||
const CharRow::reference CharRow::GlyphAt(const size_t column) const
|
||||
const CharRow::reference CharRow::GlyphAt(const til::CoordType column) const
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
||||
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
|
||||
return { const_cast<CharRow&>(*this), column };
|
||||
}
|
||||
|
||||
@@ -198,9 +198,9 @@ const CharRow::reference CharRow::GlyphAt(const size_t column) const
|
||||
// Return Value:
|
||||
// - text data at column
|
||||
// - Note: will throw exception if column is out of bounds
|
||||
CharRow::reference CharRow::GlyphAt(const size_t column)
|
||||
CharRow::reference CharRow::GlyphAt(const til::CoordType column)
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
||||
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
|
||||
return { *this, column };
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ std::wstring CharRow::GetText() const
|
||||
std::wstring wstr;
|
||||
wstr.reserve(_data.size());
|
||||
|
||||
for (size_t i = 0; i < _data.size(); ++i)
|
||||
for (til::CoordType i = 0; i < gsl::narrow_cast<til::CoordType>(_data.size()); ++i)
|
||||
{
|
||||
const auto glyph = GlyphAt(i);
|
||||
if (!DbcsAttrAt(i).IsTrailing())
|
||||
@@ -231,9 +231,9 @@ std::wstring CharRow::GetText() const
|
||||
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
||||
// Return Value:
|
||||
// - the delimiter class for the given char
|
||||
const DelimiterClass CharRow::DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const
|
||||
const DelimiterClass CharRow::DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
||||
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
|
||||
|
||||
const auto glyph = *GlyphAt(column).begin();
|
||||
if (glyph <= UNICODE_SPACE)
|
||||
@@ -265,10 +265,10 @@ const UnicodeStorage& CharRow::GetUnicodeStorage() const noexcept
|
||||
// Arguments:
|
||||
// - column - the column to generate the key for
|
||||
// Return Value:
|
||||
// - the COORD key for data access from UnicodeStorage for the column
|
||||
COORD CharRow::GetStorageKey(const size_t column) const noexcept
|
||||
// - the til::point key for data access from UnicodeStorage for the column
|
||||
til::point CharRow::GetStorageKey(const til::CoordType column) const noexcept
|
||||
{
|
||||
return { gsl::narrow<SHORT>(column), _pParent->GetId() };
|
||||
return { column, _pParent->GetId() };
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
||||
@@ -54,22 +54,22 @@ public:
|
||||
using const_reverse_iterator = typename boost::container::small_vector_base<value_type>::const_reverse_iterator;
|
||||
using reference = typename CharRowCellReference;
|
||||
|
||||
CharRow(size_t rowWidth, ROW* const pParent) noexcept;
|
||||
CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept;
|
||||
|
||||
size_t size() const noexcept;
|
||||
[[nodiscard]] HRESULT Resize(const size_t newSize) noexcept;
|
||||
size_t MeasureLeft() const noexcept;
|
||||
size_t MeasureRight() const;
|
||||
til::CoordType size() const noexcept;
|
||||
[[nodiscard]] HRESULT Resize(const til::CoordType newSize) noexcept;
|
||||
til::CoordType MeasureLeft() const noexcept;
|
||||
til::CoordType MeasureRight() const;
|
||||
bool ContainsText() const noexcept;
|
||||
const DbcsAttribute& DbcsAttrAt(const size_t column) const;
|
||||
DbcsAttribute& DbcsAttrAt(const size_t column);
|
||||
void ClearGlyph(const size_t column);
|
||||
const DbcsAttribute& DbcsAttrAt(const til::CoordType column) const;
|
||||
DbcsAttribute& DbcsAttrAt(const til::CoordType column);
|
||||
void ClearGlyph(const til::CoordType column);
|
||||
|
||||
const DelimiterClass DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const;
|
||||
const DelimiterClass DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const;
|
||||
|
||||
// working with glyphs
|
||||
const reference GlyphAt(const size_t column) const;
|
||||
reference GlyphAt(const size_t column);
|
||||
const reference GlyphAt(const til::CoordType column) const;
|
||||
reference GlyphAt(const til::CoordType column);
|
||||
|
||||
// iterators
|
||||
iterator begin() noexcept;
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
COORD GetStorageKey(const size_t column) const noexcept;
|
||||
til::point GetStorageKey(const til::CoordType column) const noexcept;
|
||||
|
||||
void UpdateParent(ROW* const pParent);
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
|
||||
private:
|
||||
void Reset() noexcept;
|
||||
void ClearCell(const size_t column);
|
||||
void ClearCell(const til::CoordType column);
|
||||
std::wstring GetText() const;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -25,7 +25,7 @@ class CharRowCellReference final
|
||||
public:
|
||||
using const_iterator = const wchar_t*;
|
||||
|
||||
CharRowCellReference(CharRow& parent, const size_t index) noexcept :
|
||||
CharRowCellReference(CharRow& parent, const til::CoordType index) noexcept :
|
||||
_parent{ parent },
|
||||
_index{ index }
|
||||
{
|
||||
@@ -51,7 +51,7 @@ private:
|
||||
// what char row the object belongs to
|
||||
CharRow& _parent;
|
||||
// the index of the cell in the parent char row
|
||||
const size_t _index;
|
||||
til::CoordType _index;
|
||||
|
||||
CharRowCell& _cellData();
|
||||
const CharRowCell& _cellData() const;
|
||||
|
||||
@@ -21,16 +21,16 @@ enum class LineRendition
|
||||
DoubleHeightBottom
|
||||
};
|
||||
|
||||
constexpr SMALL_RECT ScreenToBufferLine(const SMALL_RECT& line, const LineRendition lineRendition)
|
||||
constexpr til::inclusive_rect ScreenToBufferLine(const til::inclusive_rect& line, const LineRendition lineRendition)
|
||||
{
|
||||
// Use shift right to quickly divide the Left and Right by 2 for double width lines.
|
||||
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
||||
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
||||
return { line.Left >> scale, line.Top, line.Right >> scale, line.Bottom };
|
||||
}
|
||||
|
||||
constexpr SMALL_RECT BufferToScreenLine(const SMALL_RECT& line, const LineRendition lineRendition)
|
||||
constexpr til::inclusive_rect BufferToScreenLine(const til::inclusive_rect& line, const LineRendition lineRendition)
|
||||
{
|
||||
// Use shift left to quickly multiply the Left and Right by 2 for double width lines.
|
||||
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
||||
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
||||
return { line.Left << scale, line.Top, (line.Right << scale) + scale, line.Bottom };
|
||||
}
|
||||
|
||||
@@ -531,16 +531,16 @@ OutputCellView OutputCellIterator::s_GenerateView(const OutputCell& cell)
|
||||
// - Gets the distance between two iterators relative to the input data given in.
|
||||
// Return Value:
|
||||
// - The number of items of the input run consumed between these two iterators.
|
||||
ptrdiff_t OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
|
||||
til::CoordType OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
|
||||
{
|
||||
return _pos - other._pos;
|
||||
return gsl::narrow_cast<til::CoordType>(_pos - other._pos);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Gets the distance between two iterators relative to the number of cells inserted.
|
||||
// Return Value:
|
||||
// - The number of cells in the backing buffer filled between these two iterators.
|
||||
ptrdiff_t OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
|
||||
til::CoordType OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
|
||||
{
|
||||
return _distance - other._distance;
|
||||
return gsl::narrow_cast<til::CoordType>(_distance - other._distance);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class OutputCellIterator final
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = OutputCellView;
|
||||
using difference_type = ptrdiff_t;
|
||||
using difference_type = til::CoordType;
|
||||
using pointer = OutputCellView*;
|
||||
using reference = OutputCellView&;
|
||||
|
||||
@@ -48,9 +48,9 @@ public:
|
||||
|
||||
operator bool() const noexcept;
|
||||
|
||||
ptrdiff_t GetCellDistance(OutputCellIterator other) const noexcept;
|
||||
ptrdiff_t GetInputDistance(OutputCellIterator other) const noexcept;
|
||||
friend ptrdiff_t operator-(OutputCellIterator one, OutputCellIterator two) = delete;
|
||||
til::CoordType GetCellDistance(OutputCellIterator other) const noexcept;
|
||||
til::CoordType GetInputDistance(OutputCellIterator other) const noexcept;
|
||||
friend til::CoordType operator-(OutputCellIterator one, OutputCellIterator two) = delete;
|
||||
|
||||
OutputCellIterator& operator++();
|
||||
OutputCellIterator operator++(int);
|
||||
|
||||
@@ -21,14 +21,11 @@ OutputCellRect::OutputCellRect() noexcept :
|
||||
// Arguments:
|
||||
// - rows - Rows in the rectangle (height)
|
||||
// - cols - Columns in the rectangle (width)
|
||||
OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
|
||||
OutputCellRect::OutputCellRect(const til::CoordType rows, const til::CoordType cols) :
|
||||
_rows(rows),
|
||||
_cols(cols)
|
||||
{
|
||||
size_t totalCells;
|
||||
THROW_IF_FAILED(SizeTMult(rows, cols, &totalCells));
|
||||
|
||||
_storage.resize(totalCells);
|
||||
_storage.resize(gsl::narrow<size_t>(rows * cols));
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -37,7 +34,7 @@ OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
|
||||
// - row - The Y position or row index in the buffer.
|
||||
// Return Value:
|
||||
// - Read/write span of OutputCells
|
||||
gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
|
||||
gsl::span<OutputCell> OutputCellRect::GetRow(const til::CoordType row)
|
||||
{
|
||||
return gsl::span<OutputCell>(_FindRowOffset(row), _cols);
|
||||
}
|
||||
@@ -48,7 +45,7 @@ gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
|
||||
// - row - The Y position or row index in the buffer.
|
||||
// Return Value:
|
||||
// - Read-only iterator of OutputCells
|
||||
OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
|
||||
OutputCellIterator OutputCellRect::GetRowIter(const til::CoordType row) const
|
||||
{
|
||||
const gsl::span<const OutputCell> view(_FindRowOffset(row), _cols);
|
||||
|
||||
@@ -62,9 +59,9 @@ OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
|
||||
// - row - The Y position or row index in the buffer.
|
||||
// Return Value:
|
||||
// - Pointer to the location in the rectangle that represents the start of the requested row.
|
||||
OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
|
||||
OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row)
|
||||
{
|
||||
return &_storage.at(row * _cols);
|
||||
return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -74,16 +71,16 @@ OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
|
||||
// - row - The Y position or row index in the buffer.
|
||||
// Return Value:
|
||||
// - Pointer to the location in the rectangle that represents the start of the requested row.
|
||||
const OutputCell* OutputCellRect::_FindRowOffset(const size_t row) const
|
||||
const OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row) const
|
||||
{
|
||||
return &_storage.at(row * _cols);
|
||||
return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Gets the height of the rectangle
|
||||
// Return Value:
|
||||
// - Height
|
||||
size_t OutputCellRect::Height() const noexcept
|
||||
til::CoordType OutputCellRect::Height() const noexcept
|
||||
{
|
||||
return _rows;
|
||||
}
|
||||
@@ -92,7 +89,7 @@ size_t OutputCellRect::Height() const noexcept
|
||||
// - Gets the width of the rectangle
|
||||
// Return Value:
|
||||
// - Width
|
||||
size_t OutputCellRect::Width() const noexcept
|
||||
til::CoordType OutputCellRect::Width() const noexcept
|
||||
{
|
||||
return _cols;
|
||||
}
|
||||
|
||||
@@ -30,20 +30,20 @@ class OutputCellRect final
|
||||
{
|
||||
public:
|
||||
OutputCellRect() noexcept;
|
||||
OutputCellRect(const size_t rows, const size_t cols);
|
||||
OutputCellRect(const til::CoordType rows, const til::CoordType cols);
|
||||
|
||||
gsl::span<OutputCell> GetRow(const size_t row);
|
||||
OutputCellIterator GetRowIter(const size_t row) const;
|
||||
gsl::span<OutputCell> GetRow(const til::CoordType row);
|
||||
OutputCellIterator GetRowIter(const til::CoordType row) const;
|
||||
|
||||
size_t Height() const noexcept;
|
||||
size_t Width() const noexcept;
|
||||
til::CoordType Height() const noexcept;
|
||||
til::CoordType Width() const noexcept;
|
||||
|
||||
private:
|
||||
std::vector<OutputCell> _storage;
|
||||
|
||||
OutputCell* _FindRowOffset(const size_t row);
|
||||
const OutputCell* _FindRowOffset(const size_t row) const;
|
||||
OutputCell* _FindRowOffset(const til::CoordType row);
|
||||
const OutputCell* _FindRowOffset(const til::CoordType row) const;
|
||||
|
||||
size_t _cols;
|
||||
size_t _rows;
|
||||
til::CoordType _cols;
|
||||
til::CoordType _rows;
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ OutputCellView::OutputCellView(const std::wstring_view view,
|
||||
// - Reports how many columns we expect the Chars() text data to consume
|
||||
// Return Value:
|
||||
// - Count of column cells on the screen
|
||||
size_t OutputCellView::Columns() const noexcept
|
||||
til::CoordType OutputCellView::Columns() const noexcept
|
||||
{
|
||||
if (DbcsAttr().IsSingle())
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
const TextAttributeBehavior behavior) noexcept;
|
||||
|
||||
const std::wstring_view& Chars() const noexcept;
|
||||
size_t Columns() const noexcept;
|
||||
til::CoordType Columns() const noexcept;
|
||||
DbcsAttribute DbcsAttr() const noexcept;
|
||||
TextAttribute TextAttr() const noexcept;
|
||||
TextAttributeBehavior TextAttrBehavior() const noexcept;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// - pParent - the text buffer that this row belongs to
|
||||
// Return Value:
|
||||
// - constructed object
|
||||
ROW::ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
|
||||
ROW::ROW(const til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
|
||||
_id{ rowId },
|
||||
_rowWidth{ rowWidth },
|
||||
_charRow{ rowWidth, this },
|
||||
@@ -58,7 +58,7 @@ bool ROW::Reset(const TextAttribute Attr)
|
||||
// - width - the new width, in cells
|
||||
// Return Value:
|
||||
// - S_OK if successful, otherwise relevant error
|
||||
[[nodiscard]] HRESULT ROW::Resize(const unsigned short width)
|
||||
[[nodiscard]] HRESULT ROW::Resize(const til::CoordType width)
|
||||
{
|
||||
RETURN_IF_FAILED(_charRow.Resize(width));
|
||||
try
|
||||
@@ -78,7 +78,7 @@ bool ROW::Reset(const TextAttribute Attr)
|
||||
// - column - 0-indexed column index
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ROW::ClearColumn(const size_t column)
|
||||
void ROW::ClearColumn(const til::CoordType column)
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, column >= _charRow.size());
|
||||
_charRow.ClearCell(column);
|
||||
@@ -103,7 +103,7 @@ const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
|
||||
// - limitRight - right inclusive column ID for the last write in this row. (optional, will just write to the end of row if nullopt)
|
||||
// Return Value:
|
||||
// - iterator to first cell that was not written to this row.
|
||||
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap, std::optional<size_t> limitRight)
|
||||
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap, std::optional<til::CoordType> limitRight)
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, index >= _charRow.size());
|
||||
THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= _charRow.size());
|
||||
|
||||
@@ -32,9 +32,9 @@ class TextBuffer;
|
||||
class ROW final
|
||||
{
|
||||
public:
|
||||
ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
|
||||
ROW(const til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
|
||||
|
||||
size_t size() const noexcept { return _rowWidth; }
|
||||
til::CoordType size() const noexcept { return _rowWidth; }
|
||||
|
||||
void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
|
||||
bool WasWrapForced() const noexcept { return _wrapForced; }
|
||||
@@ -51,19 +51,19 @@ public:
|
||||
LineRendition GetLineRendition() const noexcept { return _lineRendition; }
|
||||
void SetLineRendition(const LineRendition lineRendition) noexcept { _lineRendition = lineRendition; }
|
||||
|
||||
SHORT GetId() const noexcept { return _id; }
|
||||
void SetId(const SHORT id) noexcept { _id = id; }
|
||||
til::CoordType GetId() const noexcept { return _id; }
|
||||
void SetId(const til::CoordType id) noexcept { _id = id; }
|
||||
|
||||
bool Reset(const TextAttribute Attr);
|
||||
[[nodiscard]] HRESULT Resize(const unsigned short width);
|
||||
[[nodiscard]] HRESULT Resize(const til::CoordType width);
|
||||
|
||||
void ClearColumn(const size_t column);
|
||||
void ClearColumn(const til::CoordType column);
|
||||
std::wstring GetText() const { return _charRow.GetText(); }
|
||||
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
|
||||
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap = std::nullopt, std::optional<size_t> limitRight = std::nullopt);
|
||||
OutputCellIterator WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap = std::nullopt, std::optional<til::CoordType> limitRight = std::nullopt);
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend constexpr bool operator==(const ROW& a, const ROW& b) noexcept;
|
||||
@@ -74,8 +74,8 @@ private:
|
||||
CharRow _charRow;
|
||||
ATTR_ROW _attrRow;
|
||||
LineRendition _lineRendition;
|
||||
SHORT _id;
|
||||
unsigned short _rowWidth;
|
||||
til::CoordType _id;
|
||||
til::CoordType _rowWidth;
|
||||
// Occurs when the user runs out of text in a given row and we're forced to wrap the cursor to the next line
|
||||
bool _wrapForced;
|
||||
// Occurs when the user runs out of text to support a double byte character and we're forced to the next line
|
||||
|
||||
@@ -357,6 +357,11 @@ void TextAttribute::SetReverseVideo(bool isReversed) noexcept
|
||||
WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO, isReversed);
|
||||
}
|
||||
|
||||
ExtendedAttributes TextAttribute::GetExtendedAttributes() const noexcept
|
||||
{
|
||||
return _extendedAttrs;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - swaps foreground and background color
|
||||
void TextAttribute::Invert() noexcept
|
||||
|
||||
@@ -109,10 +109,7 @@ public:
|
||||
void SetOverlined(bool isOverlined) noexcept;
|
||||
void SetReverseVideo(bool isReversed) noexcept;
|
||||
|
||||
constexpr ExtendedAttributes GetExtendedAttributes() const noexcept
|
||||
{
|
||||
return _extendedAttrs;
|
||||
}
|
||||
ExtendedAttributes GetExtendedAttributes() const noexcept;
|
||||
|
||||
bool IsHyperlink() const noexcept;
|
||||
|
||||
@@ -164,13 +161,6 @@ public:
|
||||
{
|
||||
return WI_IsAnyFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL | COMMON_LVB_GRID_LVERTICAL | COMMON_LVB_GRID_RVERTICAL | COMMON_LVB_UNDERSCORE);
|
||||
}
|
||||
constexpr bool HasAnyExtendedAttributes() const noexcept
|
||||
{
|
||||
return GetExtendedAttributes() != ExtendedAttributes::Normal ||
|
||||
IsAnyGridLineEnabled() ||
|
||||
GetHyperlinkId() != 0 ||
|
||||
IsReverseVideo();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::array<TextColor, 16> s_legacyForegroundColorMap;
|
||||
|
||||
@@ -49,6 +49,8 @@ enum class ColorAlias : size_t
|
||||
{
|
||||
DefaultForeground,
|
||||
DefaultBackground,
|
||||
FrameForeground,
|
||||
FrameBackground,
|
||||
ENUM_COUNT // must be the last element in the enum class
|
||||
};
|
||||
|
||||
@@ -72,10 +74,13 @@ public:
|
||||
static constexpr BYTE BRIGHT_CYAN = 14;
|
||||
static constexpr BYTE BRIGHT_WHITE = 15;
|
||||
|
||||
static constexpr size_t DEFAULT_FOREGROUND = 256;
|
||||
static constexpr size_t DEFAULT_BACKGROUND = 257;
|
||||
static constexpr size_t CURSOR_COLOR = 258;
|
||||
static constexpr size_t TABLE_SIZE = 259;
|
||||
// Entries 256 to 260 are reserved for XTerm compatibility.
|
||||
static constexpr size_t DEFAULT_FOREGROUND = 261;
|
||||
static constexpr size_t DEFAULT_BACKGROUND = 262;
|
||||
static constexpr size_t FRAME_FOREGROUND = 263;
|
||||
static constexpr size_t FRAME_BACKGROUND = 264;
|
||||
static constexpr size_t CURSOR_COLOR = 265;
|
||||
static constexpr size_t TABLE_SIZE = 266;
|
||||
|
||||
constexpr TextColor() noexcept :
|
||||
_meta{ ColorType::IsDefault },
|
||||
|
||||
@@ -47,7 +47,7 @@ void UnicodeStorage::Erase(const key_type key) noexcept
|
||||
// - rowMap - A map of the old row IDs to the new row IDs.
|
||||
// - width - The width of the new row. Remove any items that are beyond the row width.
|
||||
// - Use nullopt if we're not resizing the width of the row, just renumbering the rows.
|
||||
void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width)
|
||||
void UnicodeStorage::Remap(const std::unordered_map<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width)
|
||||
{
|
||||
// Make a temporary map to hold all the new row positioning
|
||||
std::unordered_map<key_type, mapped_type> newMap;
|
||||
@@ -87,7 +87,7 @@ void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const
|
||||
const auto newRowId = mapIter->second;
|
||||
|
||||
// Generate a new coordinate with the same X as the old one, but a new Y value.
|
||||
const auto newCoord = COORD{ oldCoord.X, newRowId };
|
||||
const auto newCoord = til::point{ oldCoord.X, newRowId };
|
||||
|
||||
// Put the adjusted coordinate into the map with the original value.
|
||||
newMap.emplace(newCoord, pair.second);
|
||||
|
||||
@@ -20,11 +20,11 @@ Author(s):
|
||||
#include <til/bit.h>
|
||||
#include <til/hash.h>
|
||||
|
||||
// std::unordered_map needs help to know how to hash a COORD
|
||||
// std::unordered_map needs help to know how to hash a til::point
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<COORD>
|
||||
struct hash<til::point>
|
||||
{
|
||||
// Routine Description:
|
||||
// - hashes a coord. coord will be hashed by storing the x and y values consecutively in the lower
|
||||
@@ -33,9 +33,9 @@ namespace std
|
||||
// - coord - the coord to hash
|
||||
// Return Value:
|
||||
// - the hashed coord
|
||||
constexpr size_t operator()(const COORD& coord) const noexcept
|
||||
constexpr size_t operator()(const til::point coord) const noexcept
|
||||
{
|
||||
return til::hash(til::bit_cast<uint32_t>(coord));
|
||||
return til::hash(til::bit_cast<uint64_t>(coord));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -43,7 +43,7 @@ namespace std
|
||||
class UnicodeStorage final
|
||||
{
|
||||
public:
|
||||
using key_type = typename COORD;
|
||||
using key_type = typename til::point;
|
||||
using mapped_type = typename std::vector<wchar_t>;
|
||||
|
||||
UnicodeStorage() noexcept;
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
void Erase(const key_type key) noexcept;
|
||||
|
||||
void Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width);
|
||||
void Remap(const std::unordered_map<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width);
|
||||
|
||||
private:
|
||||
std::unordered_map<key_type, mapped_type> _map;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
// - ulSize - The height of the cursor within this buffer
|
||||
Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
|
||||
_parentBuffer{ parentBuffer },
|
||||
_cPosition{ 0 },
|
||||
_fHasMoved(false),
|
||||
_fIsVisible(true),
|
||||
_fIsOn(true),
|
||||
@@ -23,7 +22,6 @@ Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
|
||||
_fIsConversionArea(false),
|
||||
_fIsPopupShown(false),
|
||||
_fDelayedEolWrap(false),
|
||||
_coordDelayedAt{ 0 },
|
||||
_fDeferCursorRedraw(false),
|
||||
_fHaveDeferredCursorRedraw(false),
|
||||
_ulSize(ulSize),
|
||||
@@ -35,7 +33,7 @@ Cursor::~Cursor()
|
||||
{
|
||||
}
|
||||
|
||||
COORD Cursor::GetPosition() const noexcept
|
||||
til::point Cursor::GetPosition() const noexcept
|
||||
{
|
||||
return _cPosition;
|
||||
}
|
||||
@@ -192,59 +190,58 @@ void Cursor::_RedrawCursorAlways() noexcept
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
void Cursor::SetPosition(const COORD cPosition) noexcept
|
||||
void Cursor::SetPosition(const til::point cPosition) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.X = cPosition.X;
|
||||
_cPosition.Y = cPosition.Y;
|
||||
_cPosition = cPosition;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
|
||||
void Cursor::SetXPosition(const int NewX) noexcept
|
||||
void Cursor::SetXPosition(const til::CoordType NewX) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.X = gsl::narrow<SHORT>(NewX);
|
||||
_cPosition.X = NewX;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
|
||||
void Cursor::SetYPosition(const int NewY) noexcept
|
||||
void Cursor::SetYPosition(const til::CoordType NewY) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.Y = gsl::narrow<SHORT>(NewY);
|
||||
_cPosition.Y = NewY;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
|
||||
void Cursor::IncrementXPosition(const int DeltaX) noexcept
|
||||
void Cursor::IncrementXPosition(const til::CoordType DeltaX) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.X += gsl::narrow<SHORT>(DeltaX);
|
||||
_cPosition.X += DeltaX;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
|
||||
void Cursor::IncrementYPosition(const int DeltaY) noexcept
|
||||
void Cursor::IncrementYPosition(const til::CoordType DeltaY) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.Y += gsl::narrow<SHORT>(DeltaY);
|
||||
_cPosition.Y += DeltaY;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
|
||||
void Cursor::DecrementXPosition(const int DeltaX) noexcept
|
||||
void Cursor::DecrementXPosition(const til::CoordType DeltaX) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.X -= gsl::narrow<SHORT>(DeltaX);
|
||||
_cPosition.X -= DeltaX;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
|
||||
void Cursor::DecrementYPosition(const int DeltaY) noexcept
|
||||
void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
|
||||
{
|
||||
_RedrawCursor();
|
||||
_cPosition.Y -= gsl::narrow<SHORT>(DeltaY);
|
||||
_cPosition.Y -= DeltaY;
|
||||
_RedrawCursor();
|
||||
ResetDelayEOLWrap();
|
||||
}
|
||||
@@ -284,7 +281,7 @@ void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept
|
||||
_cursorType = OtherCursor._cursorType;
|
||||
}
|
||||
|
||||
void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
|
||||
void Cursor::DelayEOLWrap(const til::point coordDelayedAt) noexcept
|
||||
{
|
||||
_coordDelayedAt = coordDelayedAt;
|
||||
_fDelayedEolWrap = true;
|
||||
@@ -292,11 +289,11 @@ void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
|
||||
|
||||
void Cursor::ResetDelayEOLWrap() noexcept
|
||||
{
|
||||
_coordDelayedAt = { 0 };
|
||||
_coordDelayedAt = {};
|
||||
_fDelayedEolWrap = false;
|
||||
}
|
||||
|
||||
COORD Cursor::GetDelayedAtPosition() const noexcept
|
||||
til::point Cursor::GetDelayedAtPosition() const noexcept
|
||||
{
|
||||
return _coordDelayedAt;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
bool IsPopupShown() const noexcept;
|
||||
bool GetDelay() const noexcept;
|
||||
ULONG GetSize() const noexcept;
|
||||
COORD GetPosition() const noexcept;
|
||||
til::point GetPosition() const noexcept;
|
||||
|
||||
const CursorType GetType() const noexcept;
|
||||
|
||||
@@ -66,19 +66,19 @@ public:
|
||||
void SetSize(const ULONG ulSize) noexcept;
|
||||
void SetStyle(const ULONG ulSize, const CursorType type) noexcept;
|
||||
|
||||
void SetPosition(const COORD cPosition) noexcept;
|
||||
void SetXPosition(const int NewX) noexcept;
|
||||
void SetYPosition(const int NewY) noexcept;
|
||||
void IncrementXPosition(const int DeltaX) noexcept;
|
||||
void IncrementYPosition(const int DeltaY) noexcept;
|
||||
void DecrementXPosition(const int DeltaX) noexcept;
|
||||
void DecrementYPosition(const int DeltaY) noexcept;
|
||||
void SetPosition(const til::point cPosition) noexcept;
|
||||
void SetXPosition(const til::CoordType NewX) noexcept;
|
||||
void SetYPosition(const til::CoordType NewY) noexcept;
|
||||
void IncrementXPosition(const til::CoordType DeltaX) noexcept;
|
||||
void IncrementYPosition(const til::CoordType DeltaY) noexcept;
|
||||
void DecrementXPosition(const til::CoordType DeltaX) noexcept;
|
||||
void DecrementYPosition(const til::CoordType DeltaY) noexcept;
|
||||
|
||||
void CopyProperties(const Cursor& OtherCursor) noexcept;
|
||||
|
||||
void DelayEOLWrap(const COORD coordDelayedAt) noexcept;
|
||||
void DelayEOLWrap(const til::point coordDelayedAt) noexcept;
|
||||
void ResetDelayEOLWrap() noexcept;
|
||||
COORD GetDelayedAtPosition() const noexcept;
|
||||
til::point GetDelayedAtPosition() const noexcept;
|
||||
bool IsDelayedEOLWrap() const noexcept;
|
||||
|
||||
void SetType(const CursorType type) noexcept;
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
|
||||
// NOTE: If you are adding a property here, go add it to CopyProperties.
|
||||
|
||||
COORD _cPosition; // current position on screen (in screen buffer coords).
|
||||
til::point _cPosition; // current position on screen (in screen buffer coords).
|
||||
|
||||
bool _fHasMoved;
|
||||
bool _fIsVisible; // whether cursor is visible (set only through the API)
|
||||
@@ -102,7 +102,7 @@ private:
|
||||
bool _fIsPopupShown; // if a popup is being shown, turn off, stop blinking.
|
||||
|
||||
bool _fDelayedEolWrap; // don't wrap at EOL till the next char comes in.
|
||||
COORD _coordDelayedAt; // coordinate the EOL wrap was delayed at.
|
||||
til::point _coordDelayedAt; // coordinate the EOL wrap was delayed at.
|
||||
|
||||
bool _fDeferCursorRedraw; // whether we should defer redrawing the cursor or not
|
||||
bool _fHaveDeferredCursorRedraw; // have we been asked to redraw the cursor while it was being deferred?
|
||||
|
||||
@@ -35,7 +35,6 @@ Abstract:
|
||||
#include <intsafe.h>
|
||||
|
||||
// private dependencies
|
||||
#include "../inc/operators.hpp"
|
||||
#include "../inc/unicode.hpp"
|
||||
#pragma warning(pop)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Search::Search(IUiaData& uiaData,
|
||||
const std::wstring& str,
|
||||
const Direction direction,
|
||||
const Sensitivity sensitivity,
|
||||
const COORD anchor) :
|
||||
const til::point anchor) :
|
||||
_direction(direction),
|
||||
_sensitivity(sensitivity),
|
||||
_needle(s_CreateNeedleFromString(str)),
|
||||
@@ -124,7 +124,7 @@ void Search::Color(const TextAttribute attr) const
|
||||
// been called and returned true.
|
||||
// Return Value:
|
||||
// - pair containing [start, end] coord positions of text found by search
|
||||
std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
|
||||
std::pair<til::point, til::point> Search::GetFoundLocation() const noexcept
|
||||
{
|
||||
return { _coordSelStart, _coordSelEnd };
|
||||
}
|
||||
@@ -140,7 +140,7 @@ std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
|
||||
// - direction - The intended direction of the search
|
||||
// Return Value:
|
||||
// - Coordinate to start the search from.
|
||||
COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
|
||||
til::point Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
|
||||
{
|
||||
const auto& textBuffer = uiaData.GetTextBuffer();
|
||||
const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
|
||||
@@ -187,10 +187,10 @@ COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direct
|
||||
// - end - If we found it, this is filled with the coordinate of the last character of the needle.
|
||||
// Return Value:
|
||||
// - True if we found it. False if not.
|
||||
bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const
|
||||
bool Search::_FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const
|
||||
{
|
||||
start = { 0 };
|
||||
end = { 0 };
|
||||
start = {};
|
||||
end = {};
|
||||
|
||||
auto bufferPos = pos;
|
||||
|
||||
@@ -269,7 +269,7 @@ wchar_t Search::_ApplySensitivity(const wchar_t wch) const noexcept
|
||||
// - Helper to increment a coordinate in respect to the associated screen buffer
|
||||
// Arguments
|
||||
// - coord - Updated by function to increment one position (will wrap X and Y direction)
|
||||
void Search::_IncrementCoord(COORD& coord) const noexcept
|
||||
void Search::_IncrementCoord(til::point& coord) const noexcept
|
||||
{
|
||||
_uiaData.GetTextBuffer().GetSize().IncrementInBoundsCircular(coord);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ void Search::_IncrementCoord(COORD& coord) const noexcept
|
||||
// - Helper to decrement a coordinate in respect to the associated screen buffer
|
||||
// Arguments
|
||||
// - coord - Updated by function to decrement one position (will wrap X and Y direction)
|
||||
void Search::_DecrementCoord(COORD& coord) const noexcept
|
||||
void Search::_DecrementCoord(til::point& coord) const noexcept
|
||||
{
|
||||
_uiaData.GetTextBuffer().GetSize().DecrementInBoundsCircular(coord);
|
||||
}
|
||||
@@ -314,7 +314,7 @@ void Search::_UpdateNextPosition()
|
||||
{
|
||||
if (_direction == Direction::Forward)
|
||||
{
|
||||
_coordNext = { 0 };
|
||||
_coordNext = {};
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -49,33 +49,33 @@ public:
|
||||
const std::wstring& str,
|
||||
const Direction dir,
|
||||
const Sensitivity sensitivity,
|
||||
const COORD anchor);
|
||||
const til::point anchor);
|
||||
|
||||
bool FindNext();
|
||||
void Select() const;
|
||||
void Color(const TextAttribute attr) const;
|
||||
|
||||
std::pair<COORD, COORD> GetFoundLocation() const noexcept;
|
||||
std::pair<til::point, til::point> GetFoundLocation() const noexcept;
|
||||
|
||||
private:
|
||||
wchar_t _ApplySensitivity(const wchar_t wch) const noexcept;
|
||||
bool _FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const;
|
||||
bool _FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const;
|
||||
bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept;
|
||||
void _UpdateNextPosition();
|
||||
|
||||
void _IncrementCoord(COORD& coord) const noexcept;
|
||||
void _DecrementCoord(COORD& coord) const noexcept;
|
||||
void _IncrementCoord(til::point& coord) const noexcept;
|
||||
void _DecrementCoord(til::point& coord) const noexcept;
|
||||
|
||||
static COORD s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
|
||||
static til::point s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
|
||||
|
||||
static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);
|
||||
|
||||
bool _reachedEnd = false;
|
||||
COORD _coordNext = { 0 };
|
||||
COORD _coordSelStart = { 0 };
|
||||
COORD _coordSelEnd = { 0 };
|
||||
til::point _coordNext;
|
||||
til::point _coordSelStart;
|
||||
til::point _coordSelEnd;
|
||||
|
||||
const COORD _coordAnchor;
|
||||
const til::point _coordAnchor;
|
||||
const std::vector<std::vector<wchar_t>> _needle;
|
||||
const Direction _direction;
|
||||
const Sensitivity _sensitivity;
|
||||
|
||||
@@ -30,7 +30,7 @@ using PointTree = interval_tree::IntervalTree<til::point, size_t>;
|
||||
// Return Value:
|
||||
// - constructed object
|
||||
// Note: may throw exception
|
||||
TextBuffer::TextBuffer(const COORD screenBufferSize,
|
||||
TextBuffer::TextBuffer(const til::size screenBufferSize,
|
||||
const TextAttribute defaultAttributes,
|
||||
const UINT cursorSize,
|
||||
const bool isActiveBuffer,
|
||||
@@ -47,10 +47,10 @@ TextBuffer::TextBuffer(const COORD screenBufferSize,
|
||||
_currentPatternId{ 0 }
|
||||
{
|
||||
// initialize ROWs
|
||||
_storage.reserve(static_cast<size_t>(screenBufferSize.Y));
|
||||
for (size_t i = 0; i < static_cast<size_t>(screenBufferSize.Y); ++i)
|
||||
_storage.reserve(gsl::narrow<size_t>(screenBufferSize.Y));
|
||||
for (til::CoordType i = 0; i < screenBufferSize.Y; ++i)
|
||||
{
|
||||
_storage.emplace_back(static_cast<SHORT>(i), screenBufferSize.X, _currentAttributes, this);
|
||||
_storage.emplace_back(i, screenBufferSize.X, _currentAttributes, this);
|
||||
}
|
||||
|
||||
_UpdateSize();
|
||||
@@ -74,9 +74,9 @@ void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer) noexcept
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - Total number of rows in the buffer
|
||||
UINT TextBuffer::TotalRowCount() const noexcept
|
||||
til::CoordType TextBuffer::TotalRowCount() const noexcept
|
||||
{
|
||||
return gsl::narrow<UINT>(_storage.size());
|
||||
return gsl::narrow_cast<til::CoordType>(_storage.size());
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -86,13 +86,11 @@ UINT TextBuffer::TotalRowCount() const noexcept
|
||||
// - Number of rows down from the first row of the buffer.
|
||||
// Return Value:
|
||||
// - const reference to the requested row. Asserts if out of bounds.
|
||||
const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
||||
const ROW& TextBuffer::GetRowByOffset(const til::CoordType index) const noexcept
|
||||
{
|
||||
const size_t totalRows = TotalRowCount();
|
||||
|
||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||
const auto offsetIndex = (_firstRow + index) % totalRows;
|
||||
return _storage.at(offsetIndex);
|
||||
const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
|
||||
return til::at(_storage, offsetIndex);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -102,13 +100,11 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
||||
// - Number of rows down from the first row of the buffer.
|
||||
// Return Value:
|
||||
// - reference to the requested row. Asserts if out of bounds.
|
||||
ROW& TextBuffer::GetRowByOffset(const size_t index)
|
||||
ROW& TextBuffer::GetRowByOffset(const til::CoordType index) noexcept
|
||||
{
|
||||
const size_t totalRows = TotalRowCount();
|
||||
|
||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||
const auto offsetIndex = (_firstRow + index) % totalRows;
|
||||
return _storage.at(offsetIndex);
|
||||
const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
|
||||
return til::at(_storage, offsetIndex);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -117,7 +113,7 @@ ROW& TextBuffer::GetRowByOffset(const size_t index)
|
||||
// - at - X,Y position in buffer for iterator start position
|
||||
// Return Value:
|
||||
// - Read-only iterator of text data only.
|
||||
TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
|
||||
TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at) const
|
||||
{
|
||||
return TextBufferTextIterator(GetCellDataAt(at));
|
||||
}
|
||||
@@ -128,7 +124,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
|
||||
// - at - X,Y position in buffer for iterator start position
|
||||
// Return Value:
|
||||
// - Read-only iterator of cell data.
|
||||
TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
|
||||
TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at) const
|
||||
{
|
||||
return TextBufferCellIterator(*this, at);
|
||||
}
|
||||
@@ -140,7 +136,7 @@ TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
|
||||
// - at - X,Y position in buffer for iterator start position
|
||||
// Return Value:
|
||||
// - Read-only iterator of text data only.
|
||||
TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
|
||||
TextBufferTextIterator TextBuffer::GetTextLineDataAt(const til::point at) const
|
||||
{
|
||||
return TextBufferTextIterator(GetCellLineDataAt(at));
|
||||
}
|
||||
@@ -152,9 +148,9 @@ TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
|
||||
// - at - X,Y position in buffer for iterator start position
|
||||
// Return Value:
|
||||
// - Read-only iterator of cell data.
|
||||
TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
|
||||
TextBufferCellIterator TextBuffer::GetCellLineDataAt(const til::point at) const
|
||||
{
|
||||
SMALL_RECT limit;
|
||||
til::inclusive_rect limit;
|
||||
limit.Top = at.Y;
|
||||
limit.Bottom = at.Y;
|
||||
limit.Left = 0;
|
||||
@@ -171,7 +167,7 @@ TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
|
||||
// - limit - boundaries for the iterator to operate within
|
||||
// Return Value:
|
||||
// - Read-only iterator of text data only.
|
||||
TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport limit) const
|
||||
TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at, const Viewport limit) const
|
||||
{
|
||||
return TextBufferTextIterator(GetCellDataAt(at, limit));
|
||||
}
|
||||
@@ -184,7 +180,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport
|
||||
// - limit - boundaries for the iterator to operate within
|
||||
// Return Value:
|
||||
// - Read-only iterator of cell data.
|
||||
TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at, const Viewport limit) const
|
||||
TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at, const Viewport limit) const
|
||||
{
|
||||
return TextBufferCellIterator(*this, at, limit);
|
||||
}
|
||||
@@ -337,7 +333,7 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt)
|
||||
// Return Value:
|
||||
// - The final position of the iterator
|
||||
OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const til::point target,
|
||||
const std::optional<bool> wrap)
|
||||
{
|
||||
// Make mutable copy so we can walk.
|
||||
@@ -374,9 +370,9 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
// Return Value:
|
||||
// - The iterator, but advanced to where we stopped writing. Use to find input consumed length or cells written length.
|
||||
OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const til::point target,
|
||||
const std::optional<bool> wrap,
|
||||
std::optional<size_t> limitRight)
|
||||
std::optional<til::CoordType> limitRight)
|
||||
{
|
||||
// If we're not in bounds, exit early.
|
||||
if (!GetSize().IsInBounds(target))
|
||||
@@ -390,7 +386,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
||||
|
||||
// Take the cell distance written and notify that it needs to be repainted.
|
||||
const auto written = newIt.GetCellDistance(givenIt);
|
||||
const auto paint = Viewport::FromDimensions(target, { gsl::narrow<SHORT>(written), 1 });
|
||||
const auto paint = Viewport::FromDimensions(target, { written, 1 });
|
||||
TriggerRedraw(paint);
|
||||
|
||||
return newIt;
|
||||
@@ -467,7 +463,7 @@ bool TextBuffer::InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttr
|
||||
// - <none> - Always sets to wrap
|
||||
//Return Value:
|
||||
// - <none>
|
||||
void TextBuffer::_SetWrapOnCurrentRow()
|
||||
void TextBuffer::_SetWrapOnCurrentRow() noexcept
|
||||
{
|
||||
_AdjustWrapOnCurrentRow(true);
|
||||
}
|
||||
@@ -479,10 +475,10 @@ void TextBuffer::_SetWrapOnCurrentRow()
|
||||
// - fSet - True if this row has a wrap. False otherwise.
|
||||
//Return Value:
|
||||
// - <none>
|
||||
void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet)
|
||||
void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet) noexcept
|
||||
{
|
||||
// The vertical position of the cursor represents the current row we're manipulating.
|
||||
const UINT uiCurrentRowOffset = GetCursor().GetPosition().Y;
|
||||
const auto uiCurrentRowOffset = GetCursor().GetPosition().Y;
|
||||
|
||||
// Set the wrap status as appropriate
|
||||
GetRowByOffset(uiCurrentRowOffset).SetWrapForced(fSet);
|
||||
@@ -501,7 +497,7 @@ bool TextBuffer::IncrementCursor()
|
||||
// Cursor position is stored as logical array indices (starts at 0) for the window
|
||||
// Buffer Size is specified as the "length" of the array. It would say 80 for valid values of 0-79.
|
||||
// So subtract 1 from buffer size in each direction to find the index of the final column in the buffer
|
||||
const short iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
|
||||
const auto iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
|
||||
|
||||
// Move the cursor one position to the right
|
||||
GetCursor().IncrementXPosition(1);
|
||||
@@ -604,17 +600,17 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
|
||||
// - The viewport
|
||||
//Return value:
|
||||
// - Coordinate position (relative to the text buffer)
|
||||
COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
|
||||
til::point TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
|
||||
{
|
||||
const auto viewport = viewOptional.has_value() ? viewOptional.value() : GetSize();
|
||||
|
||||
COORD coordEndOfText = { 0 };
|
||||
til::point coordEndOfText;
|
||||
// Search the given viewport by starting at the bottom.
|
||||
coordEndOfText.Y = viewport.BottomInclusive();
|
||||
|
||||
const auto& currRow = GetRowByOffset(coordEndOfText.Y);
|
||||
// The X position of the end of the valid text is the Right draw boundary (which is one beyond the final valid character)
|
||||
coordEndOfText.X = gsl::narrow<short>(currRow.GetCharRow().MeasureRight()) - 1;
|
||||
coordEndOfText.X = currRow.GetCharRow().MeasureRight() - 1;
|
||||
|
||||
// If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
|
||||
const auto viewportTop = viewport.Top();
|
||||
@@ -625,13 +621,13 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
|
||||
const auto& backupRow = GetRowByOffset(coordEndOfText.Y);
|
||||
// We need to back up to the previous row if this line is empty, AND there are more rows
|
||||
|
||||
coordEndOfText.X = gsl::narrow<short>(backupRow.GetCharRow().MeasureRight()) - 1;
|
||||
coordEndOfText.X = backupRow.GetCharRow().MeasureRight() - 1;
|
||||
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
|
||||
}
|
||||
|
||||
// don't allow negative results
|
||||
coordEndOfText.Y = std::max(coordEndOfText.Y, 0i16);
|
||||
coordEndOfText.X = std::max(coordEndOfText.X, 0i16);
|
||||
coordEndOfText.Y = std::max(coordEndOfText.Y, 0);
|
||||
coordEndOfText.X = std::max(coordEndOfText.X, 0);
|
||||
|
||||
return coordEndOfText;
|
||||
}
|
||||
@@ -643,7 +639,7 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
|
||||
// Return Value:
|
||||
// - Coordinate position in screen coordinates of the character just before the cursor.
|
||||
// - NOTE: Will return 0,0 if already in the top left corner
|
||||
COORD TextBuffer::_GetPreviousFromCursor() const
|
||||
til::point TextBuffer::_GetPreviousFromCursor() const noexcept
|
||||
{
|
||||
auto coordPosition = GetCursor().GetPosition();
|
||||
|
||||
@@ -668,7 +664,7 @@ COORD TextBuffer::_GetPreviousFromCursor() const
|
||||
return coordPosition;
|
||||
}
|
||||
|
||||
const SHORT TextBuffer::GetFirstRowIndex() const noexcept
|
||||
const til::CoordType TextBuffer::GetFirstRowIndex() const noexcept
|
||||
{
|
||||
return _firstRow;
|
||||
}
|
||||
@@ -680,15 +676,15 @@ const Viewport TextBuffer::GetSize() const noexcept
|
||||
|
||||
void TextBuffer::_UpdateSize()
|
||||
{
|
||||
_size = Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
|
||||
_size = Viewport::FromDimensions({ _storage.at(0).size(), gsl::narrow<til::CoordType>(_storage.size()) });
|
||||
}
|
||||
|
||||
void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex) noexcept
|
||||
void TextBuffer::_SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept
|
||||
{
|
||||
_firstRow = FirstRowIndex;
|
||||
}
|
||||
|
||||
void TextBuffer::ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta)
|
||||
void TextBuffer::ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta)
|
||||
{
|
||||
// If we don't have to move anything, leave early.
|
||||
if (delta == 0)
|
||||
@@ -825,9 +821,9 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
|
||||
const auto fillChar = L' ';
|
||||
auto fillAttrs = GetCurrentAttributes();
|
||||
fillAttrs.SetStandardErase();
|
||||
const size_t fillOffset = GetLineWidth(rowIndex);
|
||||
const auto fillLength = GetSize().Width() - fillOffset;
|
||||
const auto fillData = OutputCellIterator{ fillChar, fillAttrs, fillLength };
|
||||
const auto fillOffset = GetLineWidth(rowIndex);
|
||||
const auto fillLength = gsl::narrow<size_t>(GetSize().Width() - fillOffset);
|
||||
const OutputCellIterator fillData{ fillChar, fillAttrs, fillLength };
|
||||
row.WriteCells(fillData, fillOffset, false);
|
||||
// We also need to make sure the cursor is clamped within the new width.
|
||||
GetCursor().SetPosition(ClampPositionWithinLine(cursorPosition));
|
||||
@@ -836,7 +832,7 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
|
||||
}
|
||||
}
|
||||
|
||||
void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t endRow)
|
||||
void TextBuffer::ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept
|
||||
{
|
||||
for (auto row = startRow; row < endRow; row++)
|
||||
{
|
||||
@@ -844,40 +840,40 @@ void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t end
|
||||
}
|
||||
}
|
||||
|
||||
LineRendition TextBuffer::GetLineRendition(const size_t row) const
|
||||
LineRendition TextBuffer::GetLineRendition(const til::CoordType row) const noexcept
|
||||
{
|
||||
return GetRowByOffset(row).GetLineRendition();
|
||||
}
|
||||
|
||||
bool TextBuffer::IsDoubleWidthLine(const size_t row) const
|
||||
bool TextBuffer::IsDoubleWidthLine(const til::CoordType row) const noexcept
|
||||
{
|
||||
return GetLineRendition(row) != LineRendition::SingleWidth;
|
||||
}
|
||||
|
||||
SHORT TextBuffer::GetLineWidth(const size_t row) const
|
||||
til::CoordType TextBuffer::GetLineWidth(const til::CoordType row) const noexcept
|
||||
{
|
||||
// Use shift right to quickly divide the width by 2 for double width lines.
|
||||
const SHORT scale = IsDoubleWidthLine(row) ? 1 : 0;
|
||||
const auto scale = IsDoubleWidthLine(row) ? 1 : 0;
|
||||
return GetSize().Width() >> scale;
|
||||
}
|
||||
|
||||
COORD TextBuffer::ClampPositionWithinLine(const COORD position) const
|
||||
til::point TextBuffer::ClampPositionWithinLine(const til::point position) const noexcept
|
||||
{
|
||||
const SHORT rightmostColumn = GetLineWidth(position.Y) - 1;
|
||||
const auto rightmostColumn = GetLineWidth(position.Y) - 1;
|
||||
return { std::min(position.X, rightmostColumn), position.Y };
|
||||
}
|
||||
|
||||
COORD TextBuffer::ScreenToBufferPosition(const COORD position) const
|
||||
til::point TextBuffer::ScreenToBufferPosition(const til::point position) const noexcept
|
||||
{
|
||||
// Use shift right to quickly divide the X pos by 2 for double width lines.
|
||||
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||
const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||
return { position.X >> scale, position.Y };
|
||||
}
|
||||
|
||||
COORD TextBuffer::BufferToScreenPosition(const COORD position) const
|
||||
til::point TextBuffer::BufferToScreenPosition(const til::point position) const noexcept
|
||||
{
|
||||
// Use shift left to quickly multiply the X pos by 2 for double width lines.
|
||||
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||
const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||
return { position.X << scale, position.Y };
|
||||
}
|
||||
|
||||
@@ -900,7 +896,7 @@ void TextBuffer::Reset()
|
||||
// - newSize - new size of screen.
|
||||
// Return Value:
|
||||
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
|
||||
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const COORD newSize) noexcept
|
||||
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const til::size newSize) noexcept
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
|
||||
|
||||
@@ -909,12 +905,12 @@ void TextBuffer::Reset()
|
||||
const auto currentSize = GetSize().Dimensions();
|
||||
const auto attributes = GetCurrentAttributes();
|
||||
|
||||
SHORT TopRow = 0; // new top row of the screen buffer
|
||||
til::CoordType TopRow = 0; // new top row of the screen buffer
|
||||
if (newSize.Y <= GetCursor().GetPosition().Y)
|
||||
{
|
||||
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
|
||||
}
|
||||
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
|
||||
const auto TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
|
||||
|
||||
// rotate rows until the top row is at index 0
|
||||
for (auto i = 0; i < TopRowIndex; i++)
|
||||
@@ -934,7 +930,7 @@ void TextBuffer::Reset()
|
||||
// add rows if we're growing
|
||||
while (_storage.size() < static_cast<size_t>(newSize.Y))
|
||||
{
|
||||
_storage.emplace_back(static_cast<short>(_storage.size()), newSize.X, attributes, this);
|
||||
_storage.emplace_back(gsl::narrow_cast<til::CoordType>(_storage.size()), newSize.X, attributes, this);
|
||||
}
|
||||
|
||||
// Now that we've tampered with the row placement, refresh all the row IDs.
|
||||
@@ -983,7 +979,7 @@ void TextBuffer::TriggerRedraw(const Viewport& viewport)
|
||||
}
|
||||
}
|
||||
|
||||
void TextBuffer::TriggerRedrawCursor(const COORD position)
|
||||
void TextBuffer::TriggerRedrawCursor(const til::point position)
|
||||
{
|
||||
if (_isActiveBuffer)
|
||||
{
|
||||
@@ -1007,7 +1003,7 @@ void TextBuffer::TriggerScroll()
|
||||
}
|
||||
}
|
||||
|
||||
void TextBuffer::TriggerScroll(const COORD delta)
|
||||
void TextBuffer::TriggerScroll(const til::point delta)
|
||||
{
|
||||
if (_isActiveBuffer)
|
||||
{
|
||||
@@ -1032,10 +1028,10 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
|
||||
// any high unicode (UnicodeStorage) runs while we're already looping through the rows.
|
||||
// Arguments:
|
||||
// - newRowWidth - Optional new value for the row width.
|
||||
void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
|
||||
void TextBuffer::_RefreshRowIDs(std::optional<til::CoordType> newRowWidth)
|
||||
{
|
||||
std::unordered_map<SHORT, SHORT> rowMap;
|
||||
SHORT i = 0;
|
||||
std::unordered_map<til::CoordType, til::CoordType> rowMap;
|
||||
til::CoordType i = 0;
|
||||
for (auto& it : _storage)
|
||||
{
|
||||
// Build a map so we can update Unicode Storage
|
||||
@@ -1065,7 +1061,7 @@ void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - reference to the first row.
|
||||
ROW& TextBuffer::_GetFirstRow()
|
||||
ROW& TextBuffer::_GetFirstRow() noexcept
|
||||
{
|
||||
return GetRowByOffset(0);
|
||||
}
|
||||
@@ -1099,23 +1095,23 @@ ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
|
||||
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
||||
// Return Value:
|
||||
// - the delimiter class for the given char
|
||||
const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const
|
||||
DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the COORD for the beginning of the word you are on
|
||||
// - Get the til::point for the beginning of the word you are on
|
||||
// Arguments:
|
||||
// - target - a COORD on the word you are currently on
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - accessibilityMode - when enabled, we continue expanding left until we are at the beginning of a readable word.
|
||||
// Otherwise, expand left until a character of a new delimiter class is found
|
||||
// (or a row boundary is encountered)
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - The COORD for the first character on the "word" (inclusive)
|
||||
const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
// - The til::point for the first character on the "word" (inclusive)
|
||||
til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// Consider a buffer with this text in it:
|
||||
// " word other "
|
||||
@@ -1130,7 +1126,7 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
||||
#pragma warning(suppress : 26496)
|
||||
auto copy{ target };
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
if (target == bufferSize.Origin())
|
||||
{
|
||||
// can't expand left
|
||||
@@ -1140,12 +1136,12 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
||||
{
|
||||
// GH#7664: Treat EndExclusive as EndInclusive so
|
||||
// that it actually points to a space in the buffer
|
||||
copy = { bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
|
||||
copy = bufferSize.BottomRightInclusive();
|
||||
}
|
||||
else if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
|
||||
else if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||
{
|
||||
// if at/past the limit --> clamp to limit
|
||||
copy = limitOptional->to_win32_coord();
|
||||
copy = limitOptional.value_or(bufferSize.BottomRightInclusive());
|
||||
}
|
||||
|
||||
if (accessibilityMode)
|
||||
@@ -1159,13 +1155,13 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (accessibility definition) you are on
|
||||
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (accessibility definition) you are on
|
||||
// Arguments:
|
||||
// - target - a COORD on the word you are currently on
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The COORD for the first character on the current/previous READABLE "word" (inclusive)
|
||||
const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const
|
||||
// - The til::point for the first character on the current/previous READABLE "word" (inclusive)
|
||||
til::point TextBuffer::_GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
auto result = target;
|
||||
const auto bufferSize = GetSize();
|
||||
@@ -1204,13 +1200,13 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (selection definition) you are on
|
||||
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (selection definition) you are on
|
||||
// Arguments:
|
||||
// - target - a COORD on the word you are currently on
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The COORD for the first character on the current word or delimiter run (stopped by the left margin)
|
||||
const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const
|
||||
// - The til::point for the first character on the current word or delimiter run (stopped by the left margin)
|
||||
til::point TextBuffer::_GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
auto result = target;
|
||||
const auto bufferSize = GetSize();
|
||||
@@ -1233,17 +1229,17 @@ const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std:
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the COORD for the beginning of the NEXT word
|
||||
// - Get the til::point for the beginning of the NEXT word
|
||||
// Arguments:
|
||||
// - target - a COORD on the word you are currently on
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - accessibilityMode - when enabled, we continue expanding right until we are at the beginning of the next READABLE word
|
||||
// Otherwise, expand right until a character of a new delimiter class is found
|
||||
// (or a row boundary is encountered)
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - The COORD for the last character on the "word" (inclusive)
|
||||
const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
// - The til::point for the last character on the "word" (inclusive)
|
||||
til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// Consider a buffer with this text in it:
|
||||
// " word other "
|
||||
@@ -1257,15 +1253,15 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
||||
|
||||
// Already at/past the limit. Can't move forward.
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
if (accessibilityMode)
|
||||
{
|
||||
return _GetWordEndForAccessibility(target, wordDelimiters, limit.to_win32_coord());
|
||||
return _GetWordEndForAccessibility(target, wordDelimiters, limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1274,14 +1270,14 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordEnd(). Get the COORD for the beginning of the next READABLE word
|
||||
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the next READABLE word
|
||||
// Arguments:
|
||||
// - target - a COORD on the word you are currently on
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - limit - the last "valid" position in the text buffer (to improve performance)
|
||||
// Return Value:
|
||||
// - The COORD for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
||||
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const
|
||||
// - The til::point for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
||||
til::point TextBuffer::_GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const
|
||||
{
|
||||
const auto bufferSize{ GetSize() };
|
||||
auto result{ target };
|
||||
@@ -1325,13 +1321,13 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper method for GetWordEnd(). Get the COORD for the beginning of the NEXT word
|
||||
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the NEXT word
|
||||
// Arguments:
|
||||
// - target - a COORD on the word you are currently on
|
||||
// - target - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The COORD for the last character of the current word or delimiter run (stopped by right margin)
|
||||
const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const
|
||||
// - The til::point for the last character of the current word or delimiter run (stopped by right margin)
|
||||
til::point TextBuffer::_GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
@@ -1380,7 +1376,7 @@ void TextBuffer::_PruneHyperlinks()
|
||||
// we have found all hyperlink references in the first row and put them in refs,
|
||||
// now we need to search the rest of the buffer (i.e. all the rows except the first)
|
||||
// to see if those references are anywhere else
|
||||
for (size_t i = 1; i != total; ++i)
|
||||
for (til::CoordType i = 1; i < total; ++i)
|
||||
{
|
||||
const auto nextRowRefs = GetRowByOffset(i).GetAttrRow().GetHyperlinks();
|
||||
for (auto id : nextRowRefs)
|
||||
@@ -1408,22 +1404,22 @@ void TextBuffer::_PruneHyperlinks()
|
||||
// Method Description:
|
||||
// - Update pos to be the position of the first character of the next word. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a COORD on the word you are currently on
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
|
||||
// - pos - The til::point for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// move to the beginning of the next word
|
||||
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
|
||||
// This is also the inclusive start of the next word.
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit.to_win32_coord()) };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit) };
|
||||
|
||||
if (bufferSize.CompareInBounds(copy, limit.to_win32_coord(), true) >= 0)
|
||||
if (bufferSize.CompareInBounds(copy, limit, true) >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1435,12 +1431,12 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
|
||||
// Method Description:
|
||||
// - Update pos to be the position of the first character of the previous word. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a COORD on the word you are currently on
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters) const
|
||||
// - pos - The til::point for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToPreviousWord(til::point& pos, std::wstring_view wordDelimiters) const
|
||||
{
|
||||
// move to the beginning of the current word
|
||||
auto copy{ GetWordStart(pos, wordDelimiters, true) };
|
||||
@@ -1459,51 +1455,51 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
|
||||
// Method Description:
|
||||
// - Update pos to be the beginning of the current glyph/character. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a COORD on the word you are currently on
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - pos - The COORD for the first cell of the current glyph (inclusive)
|
||||
const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
|
||||
// - pos - The til::point for the first cell of the current glyph (inclusive)
|
||||
til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
auto resultPos = pos.to_win32_coord();
|
||||
auto resultPos = pos;
|
||||
const auto bufferSize = GetSize();
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
|
||||
// Clamp pos to limit
|
||||
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
|
||||
if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
|
||||
{
|
||||
resultPos = limit.to_win32_coord();
|
||||
resultPos = limit;
|
||||
}
|
||||
|
||||
// limit is exclusive, so we need to move back to be within valid bounds
|
||||
if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
||||
if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
||||
{
|
||||
bufferSize.DecrementInBounds(resultPos, true);
|
||||
}
|
||||
|
||||
return til::point{ resultPos };
|
||||
return resultPos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update pos to be the end of the current glyph/character.
|
||||
// Arguments:
|
||||
// - pos - a COORD on the word you are currently on
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - accessibilityMode - this is being used for accessibility; make the end exclusive.
|
||||
// Return Value:
|
||||
// - pos - The COORD for the last cell of the current glyph (exclusive)
|
||||
const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
// - pos - The til::point for the last cell of the current glyph (exclusive)
|
||||
til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
auto resultPos = pos.to_win32_coord();
|
||||
auto resultPos = pos;
|
||||
const auto bufferSize = GetSize();
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
|
||||
// Clamp pos to limit
|
||||
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
|
||||
if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
|
||||
{
|
||||
resultPos = limit.to_win32_coord();
|
||||
resultPos = limit;
|
||||
}
|
||||
|
||||
if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
|
||||
if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
|
||||
{
|
||||
bufferSize.IncrementInBounds(resultPos, true);
|
||||
}
|
||||
@@ -1513,24 +1509,24 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilit
|
||||
{
|
||||
bufferSize.IncrementInBounds(resultPos, true);
|
||||
}
|
||||
return til::point{ resultPos };
|
||||
return resultPos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update pos to be the beginning of the next glyph/character. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a COORD on the word you are currently on
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// - allowExclusiveEnd - allow result to be the exclusive limit (one past limit)
|
||||
// - limit - boundaries for the iterator to operate within
|
||||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The COORD for the first cell of the current glyph (inclusive)
|
||||
// - pos - The til::point for the first cell of the current glyph (inclusive)
|
||||
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
|
||||
const auto distanceToLimit{ bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) };
|
||||
const auto distanceToLimit{ bufferSize.CompareInBounds(pos, limit, true) };
|
||||
if (distanceToLimit >= 0)
|
||||
{
|
||||
// Corner Case: we're on/past the limit
|
||||
@@ -1547,7 +1543,7 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
|
||||
}
|
||||
|
||||
// Try to move forward, but if we hit the buffer boundary, we fail to move.
|
||||
auto iter{ GetCellDataAt(pos.to_win32_coord(), bufferSize) };
|
||||
auto iter{ GetCellDataAt(pos, bufferSize) };
|
||||
const bool success{ ++iter };
|
||||
|
||||
// Move again if we're on a wide glyph
|
||||
@@ -1556,24 +1552,24 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
|
||||
++iter;
|
||||
}
|
||||
|
||||
pos = til::point{ iter.Pos() };
|
||||
pos = iter.Pos();
|
||||
return success;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
|
||||
// Arguments:
|
||||
// - pos - a COORD on the word you are currently on
|
||||
// - pos - a til::point on the word you are currently on
|
||||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The COORD for the first cell of the previous glyph (inclusive)
|
||||
// - pos - The til::point for the first cell of the previous glyph (inclusive)
|
||||
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
auto resultPos = pos.to_win32_coord();
|
||||
auto resultPos = pos;
|
||||
const auto bufferSize = GetSize();
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||
|
||||
if (bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) > 0)
|
||||
if (bufferSize.CompareInBounds(pos, limit, true) > 0)
|
||||
{
|
||||
// we're past the end
|
||||
// clamp us to the limit
|
||||
@@ -1588,7 +1584,7 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
|
||||
bufferSize.DecrementInBounds(resultPos, true);
|
||||
}
|
||||
|
||||
pos = til::point{ resultPos };
|
||||
pos = resultPos;
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -1606,9 +1602,9 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
|
||||
// the buffer rather than the screen.
|
||||
// Return Value:
|
||||
// - the delimiter class for the given char
|
||||
const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const
|
||||
const std::vector<til::inclusive_rect> TextBuffer::GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const
|
||||
{
|
||||
std::vector<SMALL_RECT> textRects;
|
||||
std::vector<til::inclusive_rect> textRects;
|
||||
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
@@ -1619,11 +1615,11 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
|
||||
std::make_tuple(start, end) :
|
||||
std::make_tuple(end, start);
|
||||
|
||||
const auto textRectSize = base::ClampedNumeric<short>(1) + lowerCoord.Y - higherCoord.Y;
|
||||
const auto textRectSize = 1 + lowerCoord.Y - higherCoord.Y;
|
||||
textRects.reserve(textRectSize);
|
||||
for (auto row = higherCoord.Y; row <= lowerCoord.Y; row++)
|
||||
{
|
||||
SMALL_RECT textRow;
|
||||
til::inclusive_rect textRow;
|
||||
|
||||
textRow.Top = row;
|
||||
textRow.Bottom = row;
|
||||
@@ -1661,12 +1657,12 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
|
||||
// - selectionRow: the selection row to be expanded
|
||||
// Return Value:
|
||||
// - modifies selectionRow's Left and Right values to expand properly
|
||||
void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
|
||||
void TextBuffer::_ExpandTextRow(til::inclusive_rect& textRow) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
// expand left side of rect
|
||||
COORD targetPoint{ textRow.Left, textRow.Top };
|
||||
til::point targetPoint{ textRow.Left, textRow.Top };
|
||||
if (GetCellDataAt(targetPoint)->DbcsAttr().IsTrailing())
|
||||
{
|
||||
if (targetPoint.X == bufferSize.Left())
|
||||
@@ -1708,7 +1704,7 @@ void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
|
||||
// - The text, background color, and foreground color data of the selected region of the text buffer.
|
||||
const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
|
||||
const bool trimTrailingWhitespace,
|
||||
const std::vector<SMALL_RECT>& selectionRects,
|
||||
const std::vector<til::inclusive_rect>& selectionRects,
|
||||
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors,
|
||||
const bool formatWrappedRows) const
|
||||
{
|
||||
@@ -1725,9 +1721,9 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
|
||||
}
|
||||
|
||||
// for each row in the selection
|
||||
for (UINT i = 0; i < rows; i++)
|
||||
for (size_t i = 0; i < rows; i++)
|
||||
{
|
||||
const UINT iRow = selectionRects.at(i).Top;
|
||||
const auto iRow = selectionRects.at(i).Top;
|
||||
|
||||
const auto highlight = Viewport::FromInclusive(selectionRects.at(i));
|
||||
|
||||
@@ -2243,22 +2239,22 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
||||
const auto cOldCursorPos = oldCursor.GetPosition();
|
||||
const auto cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
|
||||
|
||||
const short cOldRowsTotal = cOldLastChar.Y + 1;
|
||||
const auto cOldRowsTotal = cOldLastChar.Y + 1;
|
||||
|
||||
COORD cNewCursorPos = { 0 };
|
||||
til::point cNewCursorPos;
|
||||
auto fFoundCursorPos = false;
|
||||
auto foundOldMutable = false;
|
||||
auto foundOldVisible = false;
|
||||
auto hr = S_OK;
|
||||
// Loop through all the rows of the old buffer and reprint them into the new buffer
|
||||
short iOldRow = 0;
|
||||
til::CoordType iOldRow = 0;
|
||||
for (; iOldRow < cOldRowsTotal; iOldRow++)
|
||||
{
|
||||
// Fetch the row and its "right" which is the last printable character.
|
||||
const auto& row = oldBuffer.GetRowByOffset(iOldRow);
|
||||
const auto cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
|
||||
const auto& charRow = row.GetCharRow();
|
||||
auto iRight = gsl::narrow_cast<short>(charRow.MeasureRight());
|
||||
auto iRight = charRow.MeasureRight();
|
||||
|
||||
// If we're starting a new row, try and preserve the line rendition
|
||||
// from the row in the original buffer.
|
||||
@@ -2296,7 +2292,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
||||
// Loop through every character in the current row (up to
|
||||
// the "right" boundary, which is one past the final valid
|
||||
// character)
|
||||
short iOldCol = 0;
|
||||
til::CoordType iOldCol = 0;
|
||||
const auto copyRight = iRight;
|
||||
for (; iOldCol < copyRight; iOldCol++)
|
||||
{
|
||||
@@ -2439,7 +2435,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
||||
const auto coordNewCursor = newCursor.GetPosition();
|
||||
if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
|
||||
{
|
||||
if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
|
||||
if (newBuffer.GetRowByOffset(coordNewCursor.Y - 1).WasWrapForced())
|
||||
{
|
||||
hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
|
||||
}
|
||||
@@ -2693,17 +2689,17 @@ void TextBuffer::CopyPatterns(const TextBuffer& OtherBuffer)
|
||||
// - The lastRow to search
|
||||
// Return value:
|
||||
// - An interval tree containing the patterns found
|
||||
PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) const
|
||||
PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const
|
||||
{
|
||||
PointTree::interval_vector intervals;
|
||||
|
||||
std::wstring concatAll;
|
||||
const auto rowSize = GetRowByOffset(0).size();
|
||||
concatAll.reserve(rowSize * (lastRow - firstRow + 1));
|
||||
concatAll.reserve(gsl::narrow_cast<size_t>(rowSize) * gsl::narrow_cast<size_t>(lastRow - firstRow + 1));
|
||||
|
||||
// to deal with text that spans multiple lines, we will first concatenate
|
||||
// all the text into one string and find the patterns in that string
|
||||
for (auto i = firstRow; i <= lastRow; ++i)
|
||||
for (til::CoordType i = firstRow; i <= lastRow; ++i)
|
||||
{
|
||||
auto& row = GetRowByOffset(i);
|
||||
concatAll += row.GetText();
|
||||
@@ -2718,21 +2714,21 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
|
||||
auto words_begin = std::wsregex_iterator(concatAll.begin(), concatAll.end(), regexObj);
|
||||
auto words_end = std::wsregex_iterator();
|
||||
|
||||
size_t lenUpToThis = 0;
|
||||
til::CoordType lenUpToThis = 0;
|
||||
for (auto i = words_begin; i != words_end; ++i)
|
||||
{
|
||||
// record the locations -
|
||||
// when we find a match, the prefix is text that is between this
|
||||
// match and the previous match, so we use the size of the prefix
|
||||
// along with the size of the match to determine the locations
|
||||
size_t prefixSize = 0;
|
||||
til::CoordType prefixSize = 0;
|
||||
for (const auto parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
|
||||
{
|
||||
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
|
||||
prefixSize += IsGlyphFullWidth(glyph) ? 2 : 1;
|
||||
}
|
||||
const auto start = lenUpToThis + prefixSize;
|
||||
size_t matchSize = 0;
|
||||
til::CoordType matchSize = 0;
|
||||
for (const auto parsedGlyph : Utf16Parser::Parse(i->str()))
|
||||
{
|
||||
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
|
||||
@@ -2741,8 +2737,8 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
|
||||
const auto end = start + matchSize;
|
||||
lenUpToThis = end;
|
||||
|
||||
const til::point startCoord{ gsl::narrow<SHORT>(start % rowSize), gsl::narrow<SHORT>(start / rowSize) };
|
||||
const til::point endCoord{ gsl::narrow<SHORT>(end % rowSize), gsl::narrow<SHORT>(end / rowSize) };
|
||||
const til::point startCoord{ start % rowSize, start / rowSize };
|
||||
const til::point endCoord{ end % rowSize, end / rowSize };
|
||||
|
||||
// store the intervals
|
||||
// NOTE: these intervals are relative to the VIEWPORT not the buffer
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Microsoft::Console::Render
|
||||
class TextBuffer final
|
||||
{
|
||||
public:
|
||||
TextBuffer(const COORD screenBufferSize,
|
||||
TextBuffer(const til::size screenBufferSize,
|
||||
const TextAttribute defaultAttributes,
|
||||
const UINT cursorSize,
|
||||
const bool isActiveBuffer,
|
||||
@@ -79,27 +79,27 @@ public:
|
||||
void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
|
||||
|
||||
// row manipulation
|
||||
const ROW& GetRowByOffset(const size_t index) const;
|
||||
ROW& GetRowByOffset(const size_t index);
|
||||
const ROW& GetRowByOffset(const til::CoordType index) const noexcept;
|
||||
ROW& GetRowByOffset(const til::CoordType index) noexcept;
|
||||
|
||||
TextBufferCellIterator GetCellDataAt(const COORD at) const;
|
||||
TextBufferCellIterator GetCellLineDataAt(const COORD at) const;
|
||||
TextBufferCellIterator GetCellDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
|
||||
TextBufferTextIterator GetTextDataAt(const COORD at) const;
|
||||
TextBufferTextIterator GetTextLineDataAt(const COORD at) const;
|
||||
TextBufferTextIterator GetTextDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
|
||||
TextBufferCellIterator GetCellDataAt(const til::point at) const;
|
||||
TextBufferCellIterator GetCellLineDataAt(const til::point at) const;
|
||||
TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
|
||||
TextBufferTextIterator GetTextDataAt(const til::point at) const;
|
||||
TextBufferTextIterator GetTextLineDataAt(const til::point at) const;
|
||||
TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
|
||||
|
||||
// Text insertion functions
|
||||
OutputCellIterator Write(const OutputCellIterator givenIt);
|
||||
|
||||
OutputCellIterator Write(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const til::point target,
|
||||
const std::optional<bool> wrap = true);
|
||||
|
||||
OutputCellIterator WriteLine(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const til::point target,
|
||||
const std::optional<bool> setWrap = std::nullopt,
|
||||
const std::optional<size_t> limitRight = std::nullopt);
|
||||
const std::optional<til::CoordType> limitRight = std::nullopt);
|
||||
|
||||
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
bool InsertCharacter(const std::wstring_view chars, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
@@ -109,36 +109,36 @@ public:
|
||||
// Scroll needs access to this to quickly rotate around the buffer.
|
||||
bool IncrementCircularBuffer(const bool inVtMode = false);
|
||||
|
||||
COORD GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
|
||||
til::point GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
|
||||
|
||||
Cursor& GetCursor() noexcept;
|
||||
const Cursor& GetCursor() const noexcept;
|
||||
|
||||
const SHORT GetFirstRowIndex() const noexcept;
|
||||
const til::CoordType GetFirstRowIndex() const noexcept;
|
||||
|
||||
const Microsoft::Console::Types::Viewport GetSize() const noexcept;
|
||||
|
||||
void ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta);
|
||||
void ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta);
|
||||
|
||||
UINT TotalRowCount() const noexcept;
|
||||
til::CoordType TotalRowCount() const noexcept;
|
||||
|
||||
[[nodiscard]] TextAttribute GetCurrentAttributes() const noexcept;
|
||||
|
||||
void SetCurrentAttributes(const TextAttribute& currentAttributes) noexcept;
|
||||
|
||||
void SetCurrentLineRendition(const LineRendition lineRendition);
|
||||
void ResetLineRenditionRange(const size_t startRow, const size_t endRow);
|
||||
LineRendition GetLineRendition(const size_t row) const;
|
||||
bool IsDoubleWidthLine(const size_t row) const;
|
||||
void ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept;
|
||||
LineRendition GetLineRendition(const til::CoordType row) const noexcept;
|
||||
bool IsDoubleWidthLine(const til::CoordType row) const noexcept;
|
||||
|
||||
SHORT GetLineWidth(const size_t row) const;
|
||||
COORD ClampPositionWithinLine(const COORD position) const;
|
||||
COORD ScreenToBufferPosition(const COORD position) const;
|
||||
COORD BufferToScreenPosition(const COORD position) const;
|
||||
til::CoordType GetLineWidth(const til::CoordType row) const noexcept;
|
||||
til::point ClampPositionWithinLine(const til::point position) const noexcept;
|
||||
til::point ScreenToBufferPosition(const til::point position) const noexcept;
|
||||
til::point BufferToScreenPosition(const til::point position) const noexcept;
|
||||
|
||||
void Reset();
|
||||
|
||||
[[nodiscard]] HRESULT ResizeTraditional(const COORD newSize) noexcept;
|
||||
[[nodiscard]] HRESULT ResizeTraditional(const til::size newSize) noexcept;
|
||||
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
@@ -149,23 +149,23 @@ public:
|
||||
Microsoft::Console::Render::Renderer& GetRenderer() noexcept;
|
||||
|
||||
void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport);
|
||||
void TriggerRedrawCursor(const COORD position);
|
||||
void TriggerRedrawCursor(const til::point position);
|
||||
void TriggerRedrawAll();
|
||||
void TriggerScroll();
|
||||
void TriggerScroll(const COORD delta);
|
||||
void TriggerScroll(const til::point delta);
|
||||
void TriggerNewTextNotification(const std::wstring_view newText);
|
||||
|
||||
const COORD GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
const COORD GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToPreviousWord(COORD& pos, const std::wstring_view wordDelimiters) const;
|
||||
til::point GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToPreviousWord(til::point& pos, const std::wstring_view wordDelimiters) const;
|
||||
|
||||
const til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
const til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
|
||||
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const;
|
||||
const std::vector<til::inclusive_rect> GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const;
|
||||
|
||||
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
||||
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
|
||||
const TextAndColor GetText(const bool includeCRLF,
|
||||
const bool trimTrailingWhitespace,
|
||||
const std::vector<SMALL_RECT>& textRects,
|
||||
const std::vector<til::inclusive_rect>& textRects,
|
||||
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors = nullptr,
|
||||
const bool formatWrappedRows = false) const;
|
||||
|
||||
@@ -200,8 +200,8 @@ public:
|
||||
|
||||
struct PositionInformation
|
||||
{
|
||||
short mutableViewportTop{ 0 };
|
||||
short visibleViewportTop{ 0 };
|
||||
til::CoordType mutableViewportTop{ 0 };
|
||||
til::CoordType visibleViewportTop{ 0 };
|
||||
};
|
||||
|
||||
static HRESULT Reflow(TextBuffer& oldBuffer,
|
||||
@@ -212,7 +212,7 @@ public:
|
||||
const size_t AddPatternRecognizer(const std::wstring_view regexString);
|
||||
void ClearPatternRecognizers() noexcept;
|
||||
void CopyPatterns(const TextBuffer& OtherBuffer);
|
||||
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const size_t firstRow, const size_t lastRow) const;
|
||||
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const;
|
||||
|
||||
private:
|
||||
void _UpdateSize();
|
||||
@@ -220,7 +220,7 @@ private:
|
||||
std::vector<ROW> _storage;
|
||||
Cursor _cursor;
|
||||
|
||||
SHORT _firstRow; // indexes top row (not necessarily 0)
|
||||
til::CoordType _firstRow; // indexes top row (not necessarily 0)
|
||||
|
||||
TextAttribute _currentAttributes;
|
||||
|
||||
@@ -234,29 +234,29 @@ private:
|
||||
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
||||
uint16_t _currentHyperlinkId;
|
||||
|
||||
void _RefreshRowIDs(std::optional<SHORT> newRowWidth);
|
||||
void _RefreshRowIDs(std::optional<til::CoordType> newRowWidth);
|
||||
|
||||
void _SetFirstRowIndex(const SHORT FirstRowIndex) noexcept;
|
||||
void _SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept;
|
||||
|
||||
COORD _GetPreviousFromCursor() const;
|
||||
til::point _GetPreviousFromCursor() const noexcept;
|
||||
|
||||
void _SetWrapOnCurrentRow();
|
||||
void _AdjustWrapOnCurrentRow(const bool fSet);
|
||||
void _SetWrapOnCurrentRow() noexcept;
|
||||
void _AdjustWrapOnCurrentRow(const bool fSet) noexcept;
|
||||
|
||||
// Assist with maintaining proper buffer state for Double Byte character sequences
|
||||
bool _PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
||||
bool _AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
||||
|
||||
ROW& _GetFirstRow();
|
||||
ROW& _GetFirstRow() noexcept;
|
||||
ROW& _GetPrevRowNoWrap(const ROW& row);
|
||||
|
||||
void _ExpandTextRow(SMALL_RECT& selectionRow) const;
|
||||
void _ExpandTextRow(til::inclusive_rect& selectionRow) const;
|
||||
|
||||
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
|
||||
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const;
|
||||
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||
DelimiterClass _GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||
til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
|
||||
til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||
|
||||
void _PruneHyperlinks();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ using namespace Microsoft::Console::Types;
|
||||
// Arguments:
|
||||
// - buffer - Text buffer to seek through
|
||||
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
|
||||
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos) :
|
||||
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos) :
|
||||
TextBufferCellIterator(buffer, pos, buffer.GetSize())
|
||||
{
|
||||
}
|
||||
@@ -30,7 +30,7 @@ TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD p
|
||||
// - buffer - Pointer to screen buffer to seek through
|
||||
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
|
||||
// - limits - Viewport limits to restrict the iterator within the buffer bounds (smaller than the buffer itself)
|
||||
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Viewport limits) :
|
||||
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Viewport limits) :
|
||||
_buffer(buffer),
|
||||
_pos(pos),
|
||||
_pRow(s_GetRow(buffer, pos)),
|
||||
@@ -126,7 +126,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
|
||||
const auto oldX = _pos.X;
|
||||
const auto oldY = _pos.Y;
|
||||
|
||||
// Under MSVC writing the individual members of a COORD generates worse assembly
|
||||
// Under MSVC writing the individual members of a til::point generates worse assembly
|
||||
// compared to having them be local variables. This causes a performance impact.
|
||||
auto newX = oldX;
|
||||
auto newY = oldY;
|
||||
@@ -289,7 +289,7 @@ ptrdiff_t TextBufferCellIterator::operator-(const TextBufferCellIterator& it)
|
||||
// - Sets the coordinate position that this iterator will inspect within the text buffer on dereference.
|
||||
// Arguments:
|
||||
// - newPos - The new coordinate position.
|
||||
void TextBufferCellIterator::_SetPos(const COORD newPos)
|
||||
void TextBufferCellIterator::_SetPos(const til::point newPos)
|
||||
{
|
||||
if (newPos.Y != _pos.Y)
|
||||
{
|
||||
@@ -317,7 +317,7 @@ void TextBufferCellIterator::_SetPos(const COORD newPos)
|
||||
// - pos - Position inside screen buffer bounds to retrieve row
|
||||
// Return Value:
|
||||
// - Pointer to the underlying CharRow structure
|
||||
const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const COORD pos)
|
||||
const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept
|
||||
{
|
||||
return &buffer.GetRowByOffset(pos.Y);
|
||||
}
|
||||
@@ -354,7 +354,7 @@ const OutputCellView* TextBufferCellIterator::operator->() const noexcept
|
||||
return &_view;
|
||||
}
|
||||
|
||||
COORD TextBufferCellIterator::Pos() const noexcept
|
||||
til::point TextBufferCellIterator::Pos() const noexcept
|
||||
{
|
||||
return _pos;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ class TextBuffer;
|
||||
class TextBufferCellIterator
|
||||
{
|
||||
public:
|
||||
TextBufferCellIterator(const TextBuffer& buffer, COORD pos);
|
||||
TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Microsoft::Console::Types::Viewport limits);
|
||||
TextBufferCellIterator(const TextBuffer& buffer, til::point pos);
|
||||
TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Microsoft::Console::Types::Viewport limits);
|
||||
|
||||
operator bool() const noexcept;
|
||||
|
||||
@@ -47,12 +47,12 @@ public:
|
||||
const OutputCellView& operator*() const noexcept;
|
||||
const OutputCellView* operator->() const noexcept;
|
||||
|
||||
COORD Pos() const noexcept;
|
||||
til::point Pos() const noexcept;
|
||||
|
||||
protected:
|
||||
void _SetPos(const COORD newPos);
|
||||
void _SetPos(const til::point newPos);
|
||||
void _GenerateView();
|
||||
static const ROW* s_GetRow(const TextBuffer& buffer, const COORD pos);
|
||||
static const ROW* s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept;
|
||||
|
||||
OutputCellView _view;
|
||||
|
||||
@@ -61,7 +61,7 @@ protected:
|
||||
const TextBuffer& _buffer;
|
||||
const Microsoft::Console::Types::Viewport _bounds;
|
||||
bool _exceeded;
|
||||
COORD _pos;
|
||||
til::point _pos;
|
||||
|
||||
#if UNIT_TESTING
|
||||
friend class TextBufferIteratorTests;
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace
|
||||
|
||||
struct TestBuffer
|
||||
{
|
||||
COORD size;
|
||||
til::size size;
|
||||
std::vector<TestRow> rows;
|
||||
COORD cursor;
|
||||
til::point cursor;
|
||||
};
|
||||
|
||||
struct TestCase
|
||||
@@ -737,7 +737,7 @@ class ReflowTests
|
||||
{
|
||||
auto buffer = std::make_unique<TextBuffer>(testBuffer.size, TextAttribute{ 0x7 }, 0, false, renderer);
|
||||
|
||||
size_t i{};
|
||||
til::CoordType i{};
|
||||
for (const auto& testRow : testBuffer.rows)
|
||||
{
|
||||
auto& row{ buffer->GetRowByOffset(i) };
|
||||
@@ -745,7 +745,7 @@ class ReflowTests
|
||||
auto& charRow{ row.GetCharRow() };
|
||||
row.SetWrapForced(testRow.wrap);
|
||||
|
||||
size_t j{};
|
||||
til::CoordType j{};
|
||||
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
|
||||
{
|
||||
// Yes, we're about to manually create a buffer. It is unpleasant.
|
||||
@@ -771,7 +771,7 @@ class ReflowTests
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const COORD newSize)
|
||||
static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const til::size newSize)
|
||||
{
|
||||
auto buffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, renderer);
|
||||
TextBuffer::Reflow(originalBuffer, *buffer, std::nullopt, std::nullopt);
|
||||
@@ -783,7 +783,7 @@ class ReflowTests
|
||||
VERIFY_ARE_EQUAL(testBuffer.cursor, buffer.GetCursor().GetPosition());
|
||||
VERIFY_ARE_EQUAL(testBuffer.size, buffer.GetSize().Dimensions());
|
||||
|
||||
size_t i{};
|
||||
til::CoordType i{};
|
||||
for (const auto& testRow : testBuffer.rows)
|
||||
{
|
||||
NoThrowString indexString;
|
||||
@@ -794,7 +794,7 @@ class ReflowTests
|
||||
indexString.Format(L"[Row %d]", i);
|
||||
VERIFY_ARE_EQUAL(testRow.wrap, row.WasWrapForced(), indexString);
|
||||
|
||||
size_t j{};
|
||||
til::CoordType j{};
|
||||
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
|
||||
{
|
||||
indexString.Format(L"[Cell %d, %d; Text line index %d]", it - charRow.begin(), i, j);
|
||||
|
||||
@@ -18,7 +18,7 @@ class UnicodeStorageTests
|
||||
TEST_METHOD(CanOverwriteEmoji)
|
||||
{
|
||||
UnicodeStorage storage;
|
||||
const COORD coord{ 1, 3 };
|
||||
const til::point coord{ 1, 3 };
|
||||
const std::vector<wchar_t> newMoon{ 0xD83C, 0xDF11 };
|
||||
const std::vector<wchar_t> fullMoon{ 0xD83C, 0xDF15 };
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ Abstract:
|
||||
|
||||
// private dependencies
|
||||
#include "../host/conddkrefs.h"
|
||||
#include "../inc/operators.hpp"
|
||||
#include "../inc/unicode.hpp"
|
||||
#pragma warning(pop)
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<!--
|
||||
These two properties are very important!
|
||||
@@ -140,10 +135,6 @@
|
||||
<!-- 16.3.0 - remove non-resources.pri PRI files since we just forced them back in. -->
|
||||
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.pri' and '%(Filename)' != 'resources'" />
|
||||
<AppxUploadPackagePayload Remove="@(AppxUploadPackagePayload)" Condition="'%(Extension)' == '.pri' and '%(Filename)' != 'resources'" />
|
||||
|
||||
<!-- Remove all of the xaml files, because we are using embedded xbf payloads (saves about 500kb on disk!) -->
|
||||
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.xaml'" />
|
||||
<AppxUploadPackagePayload Remove="@(AppxUploadPackagePayload)" Condition="'%(Extension)' == '.xaml'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
@@ -169,7 +160,13 @@
|
||||
</Target>
|
||||
|
||||
<!-- This is required to get the package dependency in the AppXManifest. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
<com:ProxyStub Id="DEC4804D-56D1-4F73-9FBE-6828E7C85C56" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
<com:ProxyStub Id="1833E661-CC81-4DD0-87C6-C2F74BD39EFA" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
<com:ProxyStub Id="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
<com:Interface Id="59D55CCE-FC8A-48B4-ACE8-0A9286C6557F" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
|
||||
@@ -230,7 +230,7 @@ HRESULT HwndTerminal::Initialize()
|
||||
RECT windowRect;
|
||||
GetWindowRect(_hwnd.get(), &windowRect);
|
||||
|
||||
const COORD windowSize{ gsl::narrow<short>(windowRect.right - windowRect.left), gsl::narrow<short>(windowRect.bottom - windowRect.top) };
|
||||
const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
|
||||
|
||||
// Fist set up the dx engine with the window size in pixels.
|
||||
// Then, using the font, get the number of characters that can fit.
|
||||
@@ -239,7 +239,7 @@ HRESULT HwndTerminal::Initialize()
|
||||
|
||||
_renderEngine = std::move(dxEngine);
|
||||
|
||||
_terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
|
||||
_terminal->Create({ 80, 25 }, 1000, *_renderer);
|
||||
_terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
|
||||
localPointerToThread->EnablePainting();
|
||||
|
||||
@@ -343,7 +343,7 @@ IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
|
||||
return _uiaProvider.Get();
|
||||
}
|
||||
|
||||
HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
|
||||
HRESULT HwndTerminal::Refresh(const til::size windowSize, _Out_ til::size* dimensions)
|
||||
{
|
||||
RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
|
||||
|
||||
@@ -357,8 +357,7 @@ HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
|
||||
_renderer->TriggerRedrawAll();
|
||||
|
||||
// Convert our new dimensions to characters
|
||||
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 },
|
||||
{ gsl::narrow<short>(windowSize.cx), gsl::narrow<short>(windowSize.cy) });
|
||||
const auto viewInPixels = Viewport::FromDimensions(windowSize);
|
||||
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
|
||||
|
||||
// If this function succeeds with S_FALSE, then the terminal didn't
|
||||
@@ -435,7 +434,7 @@ void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data)
|
||||
/// <param name="height">New height of the terminal in pixels</param>
|
||||
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
||||
/// <returns>HRESULT of the attempted resize.</returns>
|
||||
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
|
||||
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
|
||||
{
|
||||
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
||||
|
||||
@@ -448,7 +447,7 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _I
|
||||
static_cast<int>(height),
|
||||
0));
|
||||
|
||||
const SIZE windowSize{ width, height };
|
||||
const til::size windowSize{ width, height };
|
||||
return publicTerminal->Refresh(windowSize, dimensions);
|
||||
}
|
||||
|
||||
@@ -459,19 +458,19 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _I
|
||||
/// <param name="dimensionsInCharacters">New terminal size in row and column count.</param>
|
||||
/// <param name="dimensionsInPixels">Out parameter with the new size of the renderer.</param>
|
||||
/// <returns>HRESULT of the attempted resize.</returns>
|
||||
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensionsInCharacters, _Out_ SIZE* dimensionsInPixels)
|
||||
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensionsInCharacters, _Out_ til::size* dimensionsInPixels)
|
||||
{
|
||||
RETURN_HR_IF_NULL(E_INVALIDARG, dimensionsInPixels);
|
||||
|
||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||
|
||||
const auto viewInCharacters = Viewport::FromDimensions({ 0, 0 }, { (dimensionsInCharacters.X), (dimensionsInCharacters.Y) });
|
||||
const auto viewInCharacters = Viewport::FromDimensions(dimensionsInCharacters);
|
||||
const auto viewInPixels = publicTerminal->_renderEngine->GetViewportInPixels(viewInCharacters);
|
||||
|
||||
dimensionsInPixels->cx = viewInPixels.Width();
|
||||
dimensionsInPixels->cy = viewInPixels.Height();
|
||||
|
||||
COORD unused{ 0, 0 };
|
||||
til::size unused;
|
||||
|
||||
return TerminalTriggerResize(terminal, viewInPixels.Width(), viewInPixels.Height(), &unused);
|
||||
}
|
||||
@@ -484,7 +483,7 @@ HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ CO
|
||||
/// <param name="height">Height of the terminal area to calculate.</param>
|
||||
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
||||
/// <returns>HRESULT of the calculation.</returns>
|
||||
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
|
||||
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
|
||||
{
|
||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||
|
||||
@@ -548,11 +547,11 @@ try
|
||||
|
||||
if (multiClickMapper == 3)
|
||||
{
|
||||
_terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Line);
|
||||
_terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Line);
|
||||
}
|
||||
else if (multiClickMapper == 2)
|
||||
{
|
||||
_terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Word);
|
||||
_terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Word);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -593,13 +592,13 @@ try
|
||||
|
||||
if (distanceSquared >= maxDistanceSquared)
|
||||
{
|
||||
_terminal->SetSelectionAnchor((touchdownPoint / fontSize).to_win32_coord());
|
||||
_terminal->SetSelectionAnchor(touchdownPoint / fontSize);
|
||||
// stop tracking the touchdown point
|
||||
_singleClickTouchdownPos = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
this->_terminal->SetSelectionEnd((cursorPosition / fontSize).to_win32_coord());
|
||||
this->_terminal->SetSelectionEnd(cursorPosition / fontSize);
|
||||
this->_renderer->TriggerSelection();
|
||||
|
||||
return S_OK;
|
||||
@@ -701,9 +700,7 @@ try
|
||||
wheelDelta = HIWORD(wParam);
|
||||
|
||||
// If it's a *WHEEL event, it's in screen coordinates, not window (?!)
|
||||
auto coordsToTransform = cursorPosition.to_win32_point();
|
||||
ScreenToClient(_hwnd.get(), &coordsToTransform);
|
||||
cursorPosition = til::point{ coordsToTransform };
|
||||
ScreenToClient(_hwnd.get(), cursorPosition.as_win32_point());
|
||||
}
|
||||
|
||||
const TerminalInput::MouseButtonState state{
|
||||
@@ -712,7 +709,7 @@ try
|
||||
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
|
||||
};
|
||||
|
||||
return _terminal->SendMouseEvent((cursorPosition / fontSize).to_win32_coord(), uMsg, getControlKeyState(), wheelDelta, state);
|
||||
return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta, state);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -780,7 +777,7 @@ void _stdcall DestroyTerminal(void* terminal)
|
||||
}
|
||||
|
||||
// Updates the terminal font type, size, color, as well as the background/foreground colors to a specified theme.
|
||||
void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi)
|
||||
void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi)
|
||||
{
|
||||
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
||||
{
|
||||
@@ -810,8 +807,8 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
|
||||
RECT windowRect;
|
||||
GetWindowRect(publicTerminal->_hwnd.get(), &windowRect);
|
||||
|
||||
COORD dimensions = {};
|
||||
const SIZE windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
|
||||
til::size dimensions;
|
||||
const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
|
||||
publicTerminal->Refresh(windowSize, &dimensions);
|
||||
}
|
||||
|
||||
@@ -984,21 +981,21 @@ void HwndTerminal::_StringPaste(const wchar_t* const pData) noexcept
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
COORD HwndTerminal::GetFontSize() const noexcept
|
||||
til::size HwndTerminal::GetFontSize() const noexcept
|
||||
{
|
||||
return _actualFont.GetSize();
|
||||
}
|
||||
|
||||
RECT HwndTerminal::GetBounds() const noexcept
|
||||
til::rect HwndTerminal::GetBounds() const noexcept
|
||||
{
|
||||
RECT windowRect;
|
||||
GetWindowRect(_hwnd.get(), &windowRect);
|
||||
til::rect windowRect;
|
||||
GetWindowRect(_hwnd.get(), windowRect.as_win32_rect());
|
||||
return windowRect;
|
||||
}
|
||||
|
||||
RECT HwndTerminal::GetPadding() const noexcept
|
||||
til::rect HwndTerminal::GetPadding() const noexcept
|
||||
{
|
||||
return { 0 };
|
||||
return {};
|
||||
}
|
||||
|
||||
double HwndTerminal::GetScaleFactor() const noexcept
|
||||
@@ -1006,7 +1003,7 @@ double HwndTerminal::GetScaleFactor() const noexcept
|
||||
return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
|
||||
}
|
||||
|
||||
void HwndTerminal::ChangeViewport(const SMALL_RECT NewWindow)
|
||||
void HwndTerminal::ChangeViewport(const til::inclusive_rect& NewWindow)
|
||||
{
|
||||
_terminal->UserScrollViewport(NewWindow.Top);
|
||||
}
|
||||
|
||||
@@ -27,16 +27,16 @@ extern "C" {
|
||||
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
||||
__declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
|
||||
__declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
|
||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
|
||||
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
|
||||
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
||||
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
||||
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
|
||||
__declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
|
||||
__declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
|
||||
__declspec(dllexport) void _stdcall DestroyTerminal(void* terminal);
|
||||
__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
|
||||
__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
|
||||
__declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*));
|
||||
__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
|
||||
__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD flags, WORD scanCode);
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
HRESULT Initialize();
|
||||
void Teardown() noexcept;
|
||||
void SendOutput(std::wstring_view data);
|
||||
HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions);
|
||||
HRESULT Refresh(const til::size windowSize, _Out_ til::size* dimensions);
|
||||
void RegisterScrollCallback(std::function<void(int, int, int)> callback);
|
||||
void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
|
||||
::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
|
||||
@@ -91,9 +91,9 @@ private:
|
||||
std::optional<til::point> _singleClickTouchdownPos;
|
||||
|
||||
friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
||||
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
|
||||
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
|
||||
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
||||
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
||||
friend void _stdcall TerminalClearSelection(void* terminal);
|
||||
@@ -101,7 +101,7 @@ private:
|
||||
friend bool _stdcall TerminalIsSelectionActive(void* terminal);
|
||||
friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
|
||||
friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags);
|
||||
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
|
||||
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
|
||||
friend void _stdcall TerminalBlinkCursor(void* terminal);
|
||||
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
|
||||
friend void _stdcall TerminalSetFocus(void* terminal);
|
||||
@@ -128,10 +128,10 @@ private:
|
||||
void _SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept;
|
||||
|
||||
// Inherited via IControlAccessibilityInfo
|
||||
COORD GetFontSize() const noexcept override;
|
||||
RECT GetBounds() const noexcept override;
|
||||
til::size GetFontSize() const noexcept override;
|
||||
til::rect GetBounds() const noexcept override;
|
||||
double GetScaleFactor() const noexcept override;
|
||||
void ChangeViewport(const SMALL_RECT NewWindow) override;
|
||||
void ChangeViewport(const til::inclusive_rect& NewWindow) override;
|
||||
HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
|
||||
RECT GetPadding() const noexcept override;
|
||||
til::rect GetPadding() const noexcept override;
|
||||
};
|
||||
|
||||
@@ -97,7 +97,7 @@ HRESULT OpenTerminalHere::GetTitle(IShellItemArray* /*psiItemArray*/,
|
||||
return SHStrDup(resource.data(), ppszName);
|
||||
}
|
||||
|
||||
HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/,
|
||||
HRESULT OpenTerminalHere::GetState(IShellItemArray* psiItemArray,
|
||||
BOOL /*fOkToBeSlow*/,
|
||||
EXPCMDSTATE* pCmdState)
|
||||
{
|
||||
@@ -106,10 +106,25 @@ HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/,
|
||||
// E_PENDING and this object will be called back on a background thread with
|
||||
// fOkToBeSlow == TRUE
|
||||
|
||||
// We however don't need to bother with any of that, so we'll just return
|
||||
// ECS_ENABLED.
|
||||
// We however don't need to bother with any of that.
|
||||
|
||||
// If no item was selected when the context menu was opened and Explorer
|
||||
// is not at a valid path (e.g. This PC or Quick Access), we should hide
|
||||
// the verb from the context menu.
|
||||
if (psiItemArray == nullptr)
|
||||
{
|
||||
const auto path = this->_GetPathFromExplorer();
|
||||
*pCmdState = path.empty() ? ECS_HIDDEN : ECS_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
winrt::com_ptr<IShellItem> psi;
|
||||
psiItemArray->GetItemAt(0, psi.put());
|
||||
SFGAOF attributes;
|
||||
const bool isFileSystemItem = (psi->GetAttributes(SFGAO_FILESYSTEM, &attributes) == S_OK);
|
||||
*pCmdState = isFileSystemItem ? ECS_ENABLED : ECS_HIDDEN;
|
||||
}
|
||||
|
||||
*pCmdState = ECS_ENABLED;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -278,6 +278,55 @@ namespace winrt::TerminalApp::implementation
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleScrollToMark(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<ScrollToMarkArgs>())
|
||||
{
|
||||
_ApplyToActiveControls([&realArgs](auto& control) {
|
||||
control.ScrollToMark(realArgs.Direction());
|
||||
});
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
void TerminalPage::_HandleAddMark(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<AddMarkArgs>())
|
||||
{
|
||||
_ApplyToActiveControls([realArgs](auto& control) {
|
||||
Control::ScrollMark mark;
|
||||
if (realArgs.Color())
|
||||
{
|
||||
mark.Color.Color = realArgs.Color().Value();
|
||||
mark.Color.HasValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mark.Color.HasValue = false;
|
||||
}
|
||||
control.AddMark(mark);
|
||||
});
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
void TerminalPage::_HandleClearMark(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
_ApplyToActiveControls([](auto& control) {
|
||||
control.ClearMark();
|
||||
});
|
||||
args.Handled(true);
|
||||
}
|
||||
void TerminalPage::_HandleClearAllMarks(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
_ApplyToActiveControls([](auto& control) {
|
||||
control.ClearAllMarks();
|
||||
});
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleFindMatch(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
@@ -1043,4 +1092,24 @@ namespace winrt::TerminalApp::implementation
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleMarkMode(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
control.ToggleMarkMode();
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleBlockSelection(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
const auto handled = control.ToggleBlockSelection();
|
||||
args.Handled(handled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_root->Maximized(true);
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode) && !IsQuakeWindow())
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode))
|
||||
{
|
||||
_root->SetFullscreen(true);
|
||||
}
|
||||
|
||||
@@ -111,15 +111,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
|
||||
void DebugTapConnection::_OutputHandler(const hstring str)
|
||||
{
|
||||
auto output = til::visualize_control_codes(str);
|
||||
// To make the output easier to read, we introduce a line break whenever
|
||||
// an LF control is encountered. But at this point, the LF would have
|
||||
// been converted to U+240A (␊), so that's what we need to search for.
|
||||
for (size_t lfPos = 0; (lfPos = output.find(L'\u240A', lfPos)) != std::wstring::npos;)
|
||||
{
|
||||
output.insert(++lfPos, L"\r\n");
|
||||
}
|
||||
_TerminalOutputHandlers(output);
|
||||
_TerminalOutputHandlers(til::visualize_control_codes(str));
|
||||
}
|
||||
|
||||
// Called by the DebugInputTapConnection to print user input
|
||||
|
||||
@@ -119,7 +119,6 @@
|
||||
</resheader>
|
||||
<data name="AppName" xml:space="preserve">
|
||||
<value>Terminal</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppNameDev" xml:space="preserve">
|
||||
<value>Terminal Dev</value>
|
||||
@@ -127,11 +126,9 @@
|
||||
</data>
|
||||
<data name="AppNamePre" xml:space="preserve">
|
||||
<value>Terminal Preview</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppStoreName" xml:space="preserve">
|
||||
<value>Windows Terminal</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppStoreNameDev" xml:space="preserve">
|
||||
<value>Windows Terminal Dev</value>
|
||||
@@ -139,11 +136,9 @@
|
||||
</data>
|
||||
<data name="AppStoreNamePre" xml:space="preserve">
|
||||
<value>Windows Terminal Preview</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppShortName" xml:space="preserve">
|
||||
<value>Terminal</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppShortNameDev" xml:space="preserve">
|
||||
<value>Terminal Dev</value>
|
||||
@@ -151,7 +146,6 @@
|
||||
</data>
|
||||
<data name="AppShortNamePre" xml:space="preserve">
|
||||
<value>Terminal Preview</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppDescription" xml:space="preserve">
|
||||
<value>The New Windows Terminal</value>
|
||||
|
||||
@@ -60,8 +60,7 @@
|
||||
FontSize="12">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip Placement="Mouse">
|
||||
<TextBlock IsTextSelectionEnabled="False"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock IsTextSelectionEnabled="False">
|
||||
<Run x:Uid="NewTabRun" /> <LineBreak />
|
||||
<Run x:Uid="NewPaneRun"
|
||||
FontStyle="Italic" /> <LineBreak />
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
@@ -408,6 +407,13 @@
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
<!--
|
||||
By default, the PRI file will contain resource paths beginning with the
|
||||
project name. Since we enabled XBF embedding, this *also* includes App.xbf.
|
||||
|
||||
@@ -1107,8 +1107,8 @@ namespace winrt::TerminalApp::implementation
|
||||
L".",
|
||||
L"Azure",
|
||||
nullptr,
|
||||
::base::saturated_cast<uint32_t>(settings.InitialRows()),
|
||||
::base::saturated_cast<uint32_t>(settings.InitialCols()),
|
||||
settings.InitialRows(),
|
||||
settings.InitialCols(),
|
||||
winrt::guid());
|
||||
|
||||
if constexpr (Feature_VtPassthroughMode::IsEnabled())
|
||||
@@ -1158,8 +1158,8 @@ namespace winrt::TerminalApp::implementation
|
||||
newWorkingDirectory,
|
||||
settings.StartingTitle(),
|
||||
envMap.GetView(),
|
||||
::base::saturated_cast<uint32_t>(settings.InitialRows()),
|
||||
::base::saturated_cast<uint32_t>(settings.InitialCols()),
|
||||
settings.InitialRows(),
|
||||
settings.InitialCols(),
|
||||
winrt::guid());
|
||||
|
||||
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
||||
@@ -3274,9 +3274,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Request a summon of this window to the foreground
|
||||
_SummonWindowRequestedHandlers(*this, nullptr);
|
||||
|
||||
const IInspectable unused{ nullptr };
|
||||
_SetAsDefaultDismissHandler(unused, unused);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalXamlApplicationToolkit>true</TerminalXamlApplicationToolkit>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
@@ -93,6 +92,14 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace winrt;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
|
||||
static COORD GetConsoleScreenSize(HANDLE outputHandle)
|
||||
static til::point GetConsoleScreenSize(HANDLE outputHandle)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
|
||||
csbiex.cbSize = sizeof(csbiex);
|
||||
|
||||
@@ -75,8 +75,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
if (settings)
|
||||
{
|
||||
_initialRows = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows);
|
||||
_initialCols = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols);
|
||||
_initialRows = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows));
|
||||
_initialCols = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
||||
|
||||
private:
|
||||
uint32_t _initialRows{};
|
||||
uint32_t _initialCols{};
|
||||
til::CoordType _initialRows{};
|
||||
til::CoordType _initialCols{};
|
||||
|
||||
enum class AzureState
|
||||
{
|
||||
|
||||
@@ -53,12 +53,7 @@ CATCH_RETURN()
|
||||
HRESULT CTerminalHandoff::s_StopListening()
|
||||
{
|
||||
std::unique_lock lock{ _mtx };
|
||||
return s_StopListeningLocked();
|
||||
}
|
||||
|
||||
// See s_StopListening()
|
||||
HRESULT CTerminalHandoff::s_StopListeningLocked()
|
||||
{
|
||||
RETURN_HR_IF_NULL(E_NOT_VALID_STATE, _pfnHandoff);
|
||||
|
||||
_pfnHandoff = nullptr;
|
||||
@@ -106,16 +101,14 @@ HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE in, HANDLE out, HANDLE sign
|
||||
{
|
||||
try
|
||||
{
|
||||
std::unique_lock lock{ _mtx };
|
||||
|
||||
// s_StopListeningLocked sets _pfnHandoff to nullptr.
|
||||
// localPfnHandoff is tested for nullness below.
|
||||
#pragma warning(suppress : 26429) // Symbol '...' is never tested for nullness, it can be marked as not_null (f.23).
|
||||
// Stash a local copy of _pfnHandoff before we stop listening.
|
||||
auto localPfnHandoff = _pfnHandoff;
|
||||
|
||||
// Because we are REGCLS_SINGLEUSE... we need to `CoRevokeClassObject` after we handle this ONE call.
|
||||
// COM does not automatically clean that up for us. We must do it.
|
||||
LOG_IF_FAILED(s_StopListeningLocked());
|
||||
s_StopListening();
|
||||
|
||||
std::unique_lock lock{ _mtx };
|
||||
|
||||
// Report an error if no one registered a handoff function before calling this.
|
||||
THROW_HR_IF_NULL(E_NOT_VALID_STATE, localPfnHandoff);
|
||||
|
||||
@@ -43,9 +43,6 @@ struct __declspec(uuid(__CLSID_CTerminalHandoff))
|
||||
|
||||
static HRESULT s_StartListening(NewHandoffFunction pfnHandoff);
|
||||
static HRESULT s_StopListening();
|
||||
|
||||
private:
|
||||
static HRESULT s_StopListeningLocked();
|
||||
};
|
||||
|
||||
// Disable warnings from the CoCreatableClass macro as the value it provides for
|
||||
|
||||
@@ -293,7 +293,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
_transitionToState(ConnectionState::Connecting);
|
||||
|
||||
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
|
||||
const til::size dimensions{ gsl::narrow<til::CoordType>(_initialCols), gsl::narrow<til::CoordType>(_initialRows) };
|
||||
|
||||
// If we do not have pipes already, then this is a fresh connection... not an inbound one that is a received
|
||||
// handoff from an already-started PTY process.
|
||||
@@ -309,7 +309,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, flags, &_inPipe, &_outPipe, &_hPC));
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(til::unwrap_coord_size(dimensions), flags, &_inPipe, &_outPipe, &_hPC));
|
||||
|
||||
if (_initialParentHwnd != 0)
|
||||
{
|
||||
@@ -338,7 +338,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
|
||||
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), dimensions));
|
||||
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), til::unwrap_coord_size(dimensions)));
|
||||
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
||||
|
||||
if (_initialVisibility)
|
||||
|
||||
@@ -67,8 +67,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
void _indicateExitWithStatus(unsigned int status) noexcept;
|
||||
void _ClientTerminated() noexcept;
|
||||
|
||||
uint32_t _initialRows{};
|
||||
uint32_t _initialCols{};
|
||||
til::CoordType _initialRows{};
|
||||
til::CoordType _initialCols{};
|
||||
uint64_t _initialParentHwnd{ 0 };
|
||||
hstring _commandline{};
|
||||
hstring _startingDirectory{};
|
||||
|
||||
@@ -37,6 +37,28 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const til::color& c)
|
||||
{
|
||||
Core::OptionalColor result;
|
||||
result.Color = c;
|
||||
result.HasValue = true;
|
||||
return result;
|
||||
}
|
||||
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const std::optional<til::color>& c)
|
||||
{
|
||||
Core::OptionalColor result;
|
||||
if (c.has_value())
|
||||
{
|
||||
result.Color = *c;
|
||||
result.HasValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.HasValue = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Helper static function to ensure that all ambiguous-width glyphs are reported as narrow.
|
||||
// See microsoft/terminal#2066 for more info.
|
||||
static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */)
|
||||
@@ -93,9 +115,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnTitleChanged = std::bind(&ControlCore::_terminalTitleChanged, this, std::placeholders::_1);
|
||||
_terminal->SetTitleChangedCallback(pfnTitleChanged);
|
||||
|
||||
auto pfnTabColorChanged = std::bind(&ControlCore::_terminalTabColorChanged, this, std::placeholders::_1);
|
||||
_terminal->SetTabColorChangedCallback(pfnTabColorChanged);
|
||||
|
||||
auto pfnScrollPositionChanged = std::bind(&ControlCore::_terminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
_terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged);
|
||||
|
||||
@@ -108,6 +127,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnShowWindowChanged = std::bind(&ControlCore::_terminalShowWindowChanged, this, std::placeholders::_1);
|
||||
_terminal->SetShowWindowCallback(pfnShowWindowChanged);
|
||||
|
||||
auto pfnPlayMidiNote = std::bind(&ControlCore::_terminalPlayMidiNote, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
_terminal->SetPlayMidiNoteCallback(pfnPlayMidiNote);
|
||||
|
||||
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
|
||||
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
|
||||
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
|
||||
@@ -126,6 +148,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread));
|
||||
|
||||
_renderer->SetBackgroundColorChangedCallback([this]() { _rendererBackgroundColorChanged(); });
|
||||
_renderer->SetFrameColorChangedCallback([this]() { _rendererTabColorChanged(); });
|
||||
|
||||
_renderer->SetRendererEnteredErrorStateCallback([weakThis = get_weak()]() {
|
||||
if (auto strongThis{ weakThis.get() })
|
||||
@@ -172,12 +195,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
});
|
||||
|
||||
// NOTE: Calling UpdatePatternLocations from a background
|
||||
// thread is a workaround for us to hit GH#12607 less often.
|
||||
_updatePatternLocations = std::make_unique<til::throttled_func_trailing<>>(
|
||||
_updatePatternLocations = std::make_shared<ThrottledFuncTrailing<>>(
|
||||
_dispatcher,
|
||||
UpdatePatternLocationsInterval,
|
||||
[weakThis = get_weak()]() {
|
||||
if (auto core{ weakThis.get() })
|
||||
if (auto core{ weakThis.get() }; !core->_IsClosing())
|
||||
{
|
||||
core->UpdatePatternLocations();
|
||||
}
|
||||
@@ -204,6 +226,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
_renderer->TriggerTeardown();
|
||||
}
|
||||
|
||||
_shutdownMidiAudio();
|
||||
}
|
||||
|
||||
bool ControlCore::Initialize(const double actualWidth,
|
||||
@@ -248,8 +272,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// and react accordingly.
|
||||
_updateFont(true);
|
||||
|
||||
const COORD windowSize{ static_cast<short>(windowWidth),
|
||||
static_cast<short>(windowHeight) };
|
||||
const til::size windowSize{ static_cast<til::CoordType>(windowWidth),
|
||||
static_cast<til::CoordType>(windowHeight) };
|
||||
|
||||
// First set up the dx engine with the window size in pixels.
|
||||
// Then, using the font, get the number of characters that can fit.
|
||||
@@ -393,11 +417,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
vkey != VK_SNAPSHOT &&
|
||||
keyDown)
|
||||
{
|
||||
// try to update the selection
|
||||
if (const auto updateSlnParams{ ::Terminal::ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) })
|
||||
if (_terminal->IsInMarkMode() && modifiers.IsCtrlPressed() && vkey == 'A')
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->UpdateSelection(updateSlnParams->first, updateSlnParams->second);
|
||||
_terminal->SelectAll();
|
||||
_renderer->TriggerSelection();
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to update the selection
|
||||
if (const auto updateSlnParams{ _terminal->ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) })
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->UpdateSelection(updateSlnParams->first, updateSlnParams->second, modifiers);
|
||||
_renderer->TriggerSelection();
|
||||
return true;
|
||||
}
|
||||
@@ -434,7 +466,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const short wheelDelta,
|
||||
const TerminalInput::MouseButtonState state)
|
||||
{
|
||||
return _terminal->SendMouseEvent(viewportPos.to_win32_coord(), uiButton, states, wheelDelta, state);
|
||||
return _terminal->SendMouseEvent(viewportPos, uiButton, states, wheelDelta, state);
|
||||
}
|
||||
|
||||
void ControlCore::UserScrollViewport(const int viewTop)
|
||||
@@ -446,7 +478,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// itself - it was initiated by the mouse wheel, or the scrollbar.
|
||||
_terminal->UserScrollViewport(viewTop);
|
||||
|
||||
(*_updatePatternLocations)();
|
||||
_updatePatternLocations->Run();
|
||||
}
|
||||
|
||||
void ControlCore::AdjustOpacity(const double adjustment)
|
||||
@@ -558,12 +590,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_lastHoveredCell = terminalPosition;
|
||||
uint16_t newId{ 0u };
|
||||
// we can't use auto here because we're pre-declaring newInterval.
|
||||
decltype(_terminal->GetHyperlinkIntervalFromPosition(COORD{})) newInterval{ std::nullopt };
|
||||
decltype(_terminal->GetHyperlinkIntervalFromPosition({})) newInterval{ std::nullopt };
|
||||
if (terminalPosition.has_value())
|
||||
{
|
||||
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||
newId = _terminal->GetHyperlinkIdAtPosition(terminalPosition->to_win32_coord());
|
||||
newInterval = _terminal->GetHyperlinkIntervalFromPosition(terminalPosition->to_win32_coord());
|
||||
newId = _terminal->GetHyperlinkIdAtPosition(*terminalPosition);
|
||||
newInterval = _terminal->GetHyperlinkIntervalFromPosition(*terminalPosition);
|
||||
}
|
||||
|
||||
// If the hyperlink ID changed or the interval changed, trigger a redraw all
|
||||
@@ -593,7 +625,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// Lock for the duration of our reads.
|
||||
auto lock = _terminal->LockForReading();
|
||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }.to_win32_coord()) };
|
||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }) };
|
||||
}
|
||||
|
||||
winrt::hstring ControlCore::HoveredUriText() const
|
||||
@@ -601,7 +633,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||
if (_lastHoveredCell.has_value())
|
||||
{
|
||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(_lastHoveredCell->to_win32_coord()) };
|
||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(*_lastHoveredCell) };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -648,6 +680,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Inform the renderer of our opacity
|
||||
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
|
||||
|
||||
// Trigger a redraw to repaint the window background and tab colors.
|
||||
_renderer->TriggerRedrawAll(true, true);
|
||||
|
||||
_updateAntiAliasingMode();
|
||||
|
||||
if (sizeChanged)
|
||||
@@ -768,7 +803,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool ControlCore::_setFontSizeUnderLock(int fontSize)
|
||||
{
|
||||
// Make sure we have a non-zero font size
|
||||
const auto newSize = std::max<short>(gsl::narrow_cast<short>(fontSize), 1);
|
||||
const auto newSize = std::max(fontSize, 1);
|
||||
const auto fontFace = _settings->FontFace();
|
||||
const auto fontWeight = _settings->FontWeight();
|
||||
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
|
||||
@@ -824,8 +859,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - <none>
|
||||
void ControlCore::_refreshSizeUnderLock()
|
||||
{
|
||||
auto cx = gsl::narrow_cast<short>(_panelWidth * _compositionScale);
|
||||
auto cy = gsl::narrow_cast<short>(_panelHeight * _compositionScale);
|
||||
auto cx = gsl::narrow_cast<til::CoordType>(_panelWidth * _compositionScale);
|
||||
auto cy = gsl::narrow_cast<til::CoordType>(_panelHeight * _compositionScale);
|
||||
|
||||
// Don't actually resize so small that a single character wouldn't fit
|
||||
// in either dimension. The buffer really doesn't like being size 0.
|
||||
@@ -893,17 +928,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_refreshSizeUnderLock();
|
||||
}
|
||||
|
||||
void ControlCore::SetSelectionAnchor(const til::point& position)
|
||||
void ControlCore::SetSelectionAnchor(const til::point position)
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->SetSelectionAnchor(position.to_win32_coord());
|
||||
_terminal->SetSelectionAnchor(position);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
|
||||
// Arguments:
|
||||
// - position: the point in terminal coordinates (in cells, not pixels)
|
||||
void ControlCore::SetEndSelectionPoint(const til::point& position)
|
||||
void ControlCore::SetEndSelectionPoint(const til::point position)
|
||||
{
|
||||
if (!_terminal->IsSelectionActive())
|
||||
{
|
||||
@@ -920,7 +955,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
};
|
||||
|
||||
// save location (for rendering) + render
|
||||
_terminal->SetSelectionEnd(terminalPosition.to_win32_coord());
|
||||
_terminal->SetSelectionEnd(terminalPosition);
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
|
||||
@@ -934,14 +969,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Method Description:
|
||||
// - Given a copy-able selection, get the selected text from the buffer and send it to the
|
||||
// Windows Clipboard (CascadiaWin32:main.cpp).
|
||||
// - CopyOnSelect does NOT clear the selection
|
||||
// Arguments:
|
||||
// - singleLine: collapse all of the text to one line
|
||||
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
|
||||
// if we should defer which formats are copied to the global setting
|
||||
// - clearSelection: if true, clear the selection. Used for CopyOnSelect.
|
||||
bool ControlCore::CopySelectionToClipboard(bool singleLine,
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats,
|
||||
bool clearSelection)
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats)
|
||||
{
|
||||
// no selection --> nothing to copy
|
||||
if (!_terminal->IsSelectionActive())
|
||||
@@ -981,7 +1015,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bgColor) :
|
||||
"";
|
||||
|
||||
if (clearSelection)
|
||||
if (!_settings->CopyOnSelect())
|
||||
{
|
||||
_terminal->ClearSelection();
|
||||
_renderer->TriggerSelection();
|
||||
@@ -1003,9 +1037,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
|
||||
const bool ControlCore::IsInQuickEditMode() const noexcept
|
||||
bool ControlCore::ToggleBlockSelection()
|
||||
{
|
||||
return _terminal->IsInQuickEditMode();
|
||||
auto lock = _terminal->LockForWriting();
|
||||
if (_terminal->IsSelectionActive())
|
||||
{
|
||||
_terminal->SetBlockSelection(!_terminal->IsBlockSelection());
|
||||
_renderer->TriggerSelection();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ControlCore::ToggleMarkMode()
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->ToggleMarkMode();
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
|
||||
bool ControlCore::IsInMarkMode() const
|
||||
{
|
||||
return _terminal->IsInMarkMode();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1151,21 +1204,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_TitleChangedHandlers(*this, winrt::make<TitleChangedEventArgs>(winrt::hstring{ wstr }));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called for the Terminal's TabColorChanged callback. This will re-raise
|
||||
// a new winrt TypedEvent that can be listened to.
|
||||
// - The listeners to this event will re-query the control for the current
|
||||
// value of TabColor().
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ControlCore::_terminalTabColorChanged(const std::optional<til::color> /*color*/)
|
||||
{
|
||||
// Raise a TabColorChanged event
|
||||
_TabColorChangedHandlers(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the position and size of the scrollbar to match the given
|
||||
// viewport top, viewport height, and buffer size.
|
||||
@@ -1180,6 +1218,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const int viewHeight,
|
||||
const int bufferSize)
|
||||
{
|
||||
if (!_initializedTerminal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
|
||||
// We're **NOT** taking the lock here unlike _scrollbarChangeHandler because
|
||||
// we are already under lock (since this usually happens as a result of writing).
|
||||
@@ -1200,7 +1242,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// Additionally, start the throttled update of where our links are.
|
||||
(*_updatePatternLocations)();
|
||||
_updatePatternLocations->Run();
|
||||
}
|
||||
|
||||
void ControlCore::_terminalCursorPositionChanged()
|
||||
@@ -1224,6 +1266,66 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Plays a single MIDI note, blocking for the duration.
|
||||
// Arguments:
|
||||
// - noteNumber - The MIDI note number to be played (0 - 127).
|
||||
// - velocity - The force with which the note should be played (0 - 127).
|
||||
// - duration - How long the note should be sustained (in microseconds).
|
||||
void ControlCore::_terminalPlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration)
|
||||
{
|
||||
// We create the audio instance on demand, and lock it for the duration
|
||||
// of the note output so it can't be destroyed while in use.
|
||||
auto& midiAudio = _getMidiAudio();
|
||||
midiAudio.Lock();
|
||||
|
||||
// We then unlock the terminal, so the UI doesn't hang while we're busy.
|
||||
auto& terminalLock = _terminal->GetReadWriteLock();
|
||||
terminalLock.unlock();
|
||||
|
||||
// This call will block for the duration, unless shutdown early.
|
||||
midiAudio.PlayNote(noteNumber, velocity, duration);
|
||||
|
||||
// Once complete, we reacquire the terminal lock and unlock the audio.
|
||||
// If the terminal has shutdown in the meantime, the Unlock call
|
||||
// will throw an exception, forcing the thread to exit ASAP.
|
||||
terminalLock.lock();
|
||||
midiAudio.Unlock();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the MIDI audio instance, created on demand.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a reference to the MidiAudio instance.
|
||||
MidiAudio& ControlCore::_getMidiAudio()
|
||||
{
|
||||
if (!_midiAudio)
|
||||
{
|
||||
_midiAudio = std::make_unique<MidiAudio>();
|
||||
_midiAudio->Initialize();
|
||||
}
|
||||
return *_midiAudio;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Shuts down the MIDI audio system if previously instantiated.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ControlCore::_shutdownMidiAudio()
|
||||
{
|
||||
if (_midiAudio)
|
||||
{
|
||||
// We lock the terminal here to make sure the shutdown promise is
|
||||
// set before the audio is unlocked in the thread that is playing.
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_midiAudio->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
bool ControlCore::HasSelection() const
|
||||
{
|
||||
return _terminal->IsSelectionActive();
|
||||
@@ -1366,6 +1468,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_BackgroundColorChangedHandlers(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_rendererTabColorChanged()
|
||||
{
|
||||
_TabColorChangedHandlers(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::BlinkAttributeTick()
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
@@ -1419,7 +1526,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
auto lock = _terminal->LockForReading();
|
||||
return _terminal->GetViewportRelativeCursorPosition().to_core_point();
|
||||
return _terminal->GetCursorPosition().to_core_point();
|
||||
}
|
||||
|
||||
// This one's really pushing the boundary of what counts as "encapsulation".
|
||||
@@ -1471,7 +1578,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// If shift is pressed and there is a selection we extend it using
|
||||
// the selection mode (expand the "end" selection point)
|
||||
_terminal->SetSelectionEnd(terminalPosition.to_win32_coord(), mode);
|
||||
_terminal->SetSelectionEnd(terminalPosition, mode);
|
||||
selectionNeedsToBeCopied = true;
|
||||
}
|
||||
else if (mode != ::Terminal::SelectionExpansion::Char || shiftEnabled)
|
||||
@@ -1479,7 +1586,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// If we are handling a double / triple-click or shift+single click
|
||||
// we establish selection using the selected mode
|
||||
// (expand both "start" and "end" selection points)
|
||||
_terminal->MultiClickSelection(terminalPosition.to_win32_coord(), mode);
|
||||
_terminal->MultiClickSelection(terminalPosition, mode);
|
||||
selectionNeedsToBeCopied = true;
|
||||
}
|
||||
|
||||
@@ -1509,10 +1616,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
void ControlCore::_connectionOutputHandler(const hstring& hstr)
|
||||
{
|
||||
_terminal->Write(hstr);
|
||||
try
|
||||
{
|
||||
_terminal->Write(hstr);
|
||||
|
||||
// Start the throttled update of where our hyperlinks are.
|
||||
(*_updatePatternLocations)();
|
||||
// Start the throttled update of where our hyperlinks are.
|
||||
_updatePatternLocations->Run();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// We're expecting to receive an exception here if the terminal
|
||||
// is closed while we're blocked playing a MIDI note.
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1744,24 +1859,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - This is related to work done for GH#2988.
|
||||
void ControlCore::GotFocus()
|
||||
{
|
||||
_focusChanged(true);
|
||||
_terminal->FocusChanged(true);
|
||||
}
|
||||
|
||||
// See GotFocus.
|
||||
void ControlCore::LostFocus()
|
||||
{
|
||||
_focusChanged(false);
|
||||
}
|
||||
|
||||
void ControlCore::_focusChanged(bool focused)
|
||||
{
|
||||
// GH#13461 - temporarily turn off read-only mode, send the focus event,
|
||||
// then turn it back on. Even in focus mode, focus events are fine to
|
||||
// send. We don't want to pop a warning every time the control is
|
||||
// focused.
|
||||
const auto previous = std::exchange(_isReadOnly, false);
|
||||
const auto restore = wil::scope_exit([&]() { _isReadOnly = previous; });
|
||||
_terminal->FocusChanged(focused);
|
||||
_terminal->FocusChanged(false);
|
||||
}
|
||||
|
||||
bool ControlCore::_isBackgroundTransparent()
|
||||
@@ -1793,4 +1897,140 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
_owningHwnd = owner;
|
||||
}
|
||||
|
||||
Windows::Foundation::Collections::IVector<Control::ScrollMark> ControlCore::ScrollMarks() const
|
||||
{
|
||||
auto internalMarks{ _terminal->GetScrollMarks() };
|
||||
auto v = winrt::single_threaded_observable_vector<Control::ScrollMark>();
|
||||
for (const auto& mark : internalMarks)
|
||||
{
|
||||
Control::ScrollMark m{};
|
||||
|
||||
// sneaky: always evaluate the color of the mark to a real value
|
||||
// before shoving it into the optional. If the mark doesn't have a
|
||||
// specific color set, we'll use the value from the color table
|
||||
// that's appropriate for this category of mark. If we do have a
|
||||
// color set, then great we'll use that. The TermControl can then
|
||||
// always use the value in the Mark regardless if it was actually
|
||||
// set or not.
|
||||
m.Color = OptionalFromColor(_terminal->GetColorForMark(mark));
|
||||
m.Start = mark.start.to_core_point();
|
||||
m.End = mark.end.to_core_point();
|
||||
|
||||
v.Append(m);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void ControlCore::AddMark(const Control::ScrollMark& mark)
|
||||
{
|
||||
::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark m{};
|
||||
|
||||
if (mark.Color.HasValue)
|
||||
{
|
||||
m.color = til::color{ mark.Color.Color };
|
||||
}
|
||||
|
||||
if (HasSelection())
|
||||
{
|
||||
m.start = til::point{ _terminal->GetSelectionAnchor() };
|
||||
m.end = til::point{ _terminal->GetSelectionEnd() };
|
||||
}
|
||||
else
|
||||
{
|
||||
m.start = m.end = til::point{ _terminal->GetTextBuffer().GetCursor().GetPosition() };
|
||||
}
|
||||
|
||||
// The version of this that only accepts a ScrollMark will automatically
|
||||
// set the start & end to the cursor position.
|
||||
_terminal->AddMark(m, m.start, m.end);
|
||||
}
|
||||
void ControlCore::ClearMark() { _terminal->ClearMark(); }
|
||||
void ControlCore::ClearAllMarks() { _terminal->ClearAllMarks(); }
|
||||
|
||||
void ControlCore::ScrollToMark(const Control::ScrollToMarkDirection& direction)
|
||||
{
|
||||
const auto currentOffset = ScrollOffset();
|
||||
const auto& marks{ _terminal->GetScrollMarks() };
|
||||
|
||||
std::optional<DispatchTypes::ScrollMark> tgt;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case ScrollToMarkDirection::Last:
|
||||
{
|
||||
int highest = currentOffset;
|
||||
for (const auto& mark : marks)
|
||||
{
|
||||
const auto newY = mark.start.y;
|
||||
if (newY > highest)
|
||||
{
|
||||
tgt = mark;
|
||||
highest = newY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ScrollToMarkDirection::First:
|
||||
{
|
||||
int lowest = currentOffset;
|
||||
for (const auto& mark : marks)
|
||||
{
|
||||
const auto newY = mark.start.y;
|
||||
if (newY < lowest)
|
||||
{
|
||||
tgt = mark;
|
||||
lowest = newY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ScrollToMarkDirection::Next:
|
||||
{
|
||||
int minDistance = INT_MAX;
|
||||
for (const auto& mark : marks)
|
||||
{
|
||||
const auto delta = mark.start.y - currentOffset;
|
||||
if (delta > 0 && delta < minDistance)
|
||||
{
|
||||
tgt = mark;
|
||||
minDistance = delta;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ScrollToMarkDirection::Previous:
|
||||
default:
|
||||
{
|
||||
int minDistance = INT_MAX;
|
||||
for (const auto& mark : marks)
|
||||
{
|
||||
const auto delta = currentOffset - mark.start.y;
|
||||
if (delta > 0 && delta < minDistance)
|
||||
{
|
||||
tgt = mark;
|
||||
minDistance = delta;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tgt.has_value())
|
||||
{
|
||||
UserScrollViewport(tgt->start.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (direction == ScrollToMarkDirection::Last || direction == ScrollToMarkDirection::Next)
|
||||
{
|
||||
UserScrollViewport(BufferHeight());
|
||||
}
|
||||
else if (direction == ScrollToMarkDirection::First || direction == ScrollToMarkDirection::Previous)
|
||||
{
|
||||
UserScrollViewport(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ControlCore.g.h"
|
||||
#include "ControlSettings.h"
|
||||
#include "../../audio/midi/MidiAudio.hpp"
|
||||
#include "../../renderer/base/Renderer.hpp"
|
||||
#include "../../cascadia/TerminalCore/Terminal.hpp"
|
||||
#include "../buffer/out/search.h"
|
||||
@@ -79,9 +80,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void SendInput(const winrt::hstring& wstr);
|
||||
void PasteText(const winrt::hstring& hstr);
|
||||
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats, bool clearSelection = true);
|
||||
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void SelectAll();
|
||||
const bool IsInQuickEditMode() const noexcept;
|
||||
bool ToggleBlockSelection();
|
||||
void ToggleMarkMode();
|
||||
bool IsInMarkMode() const;
|
||||
|
||||
void GotFocus();
|
||||
void LostFocus();
|
||||
@@ -116,6 +119,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
int BufferHeight() const;
|
||||
|
||||
bool BracketedPasteEnabled() const noexcept;
|
||||
|
||||
Windows::Foundation::Collections::IVector<Control::ScrollMark> ScrollMarks() const;
|
||||
void AddMark(const Control::ScrollMark& mark);
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ITerminalInput
|
||||
@@ -149,8 +159,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool HasSelection() const;
|
||||
bool CopyOnSelect() const;
|
||||
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
|
||||
void SetSelectionAnchor(const til::point& position);
|
||||
void SetEndSelectionPoint(const til::point& position);
|
||||
void SetSelectionAnchor(const til::point position);
|
||||
void SetEndSelectionPoint(const til::point position);
|
||||
|
||||
void Search(const winrt::hstring& text,
|
||||
const bool goForward,
|
||||
@@ -251,7 +261,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
winrt::Windows::System::DispatcherQueue _dispatcher{ nullptr };
|
||||
std::shared_ptr<ThrottledFuncTrailing<>> _tsfTryRedrawCanvas;
|
||||
std::unique_ptr<til::throttled_func_trailing<>> _updatePatternLocations;
|
||||
std::shared_ptr<ThrottledFuncTrailing<>> _updatePatternLocations;
|
||||
std::shared_ptr<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>> _updateScrollBar;
|
||||
|
||||
winrt::fire_and_forget _asyncCloseConnection();
|
||||
@@ -266,19 +276,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _terminalCopyToClipboard(std::wstring_view wstr);
|
||||
void _terminalWarningBell();
|
||||
void _terminalTitleChanged(std::wstring_view wstr);
|
||||
void _terminalTabColorChanged(const std::optional<til::color> color);
|
||||
void _terminalScrollPositionChanged(const int viewTop,
|
||||
const int viewHeight,
|
||||
const int bufferSize);
|
||||
void _terminalCursorPositionChanged();
|
||||
void _terminalTaskbarProgressChanged();
|
||||
void _terminalShowWindowChanged(bool showOrHide);
|
||||
void _terminalPlayMidiNote(const int noteNumber,
|
||||
const int velocity,
|
||||
const std::chrono::microseconds duration);
|
||||
#pragma endregion
|
||||
|
||||
std::unique_ptr<MidiAudio> _midiAudio;
|
||||
|
||||
MidiAudio& _getMidiAudio();
|
||||
void _shutdownMidiAudio();
|
||||
|
||||
#pragma region RendererCallbacks
|
||||
void _rendererWarning(const HRESULT hr);
|
||||
void _renderEngineSwapChainChanged();
|
||||
void _rendererBackgroundColorChanged();
|
||||
void _rendererTabColorChanged();
|
||||
#pragma endregion
|
||||
|
||||
void _raiseReadOnlyWarning();
|
||||
@@ -288,7 +306,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _setOpacity(const double opacity);
|
||||
|
||||
bool _isBackgroundTransparent();
|
||||
void _focusChanged(bool focused);
|
||||
|
||||
inline bool _IsClosing() const noexcept
|
||||
{
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Microsoft.Terminal.Control
|
||||
IsRightButtonDown = 0x4
|
||||
};
|
||||
|
||||
|
||||
enum ClearBufferType
|
||||
{
|
||||
Screen,
|
||||
@@ -66,7 +65,10 @@ namespace Microsoft.Terminal.Control
|
||||
void SendInput(String text);
|
||||
void PasteText(String text);
|
||||
void SelectAll();
|
||||
Boolean ToggleBlockSelection();
|
||||
void ToggleMarkMode();
|
||||
void ClearBuffer(ClearBufferType clearType);
|
||||
Boolean IsInMarkMode();
|
||||
|
||||
void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
|
||||
void ClearHoveredCell();
|
||||
|
||||
@@ -142,14 +142,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Method Description:
|
||||
// - Given a copy-able selection, get the selected text from the buffer and send it to the
|
||||
// Windows Clipboard (CascadiaWin32:main.cpp).
|
||||
// - CopyOnSelect does NOT clear the selection
|
||||
// Arguments:
|
||||
// - singleLine: collapse all of the text to one line
|
||||
// - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr
|
||||
// if we should defer which formats are copied to the global setting
|
||||
// - clearSelection: if true, clear the selection after copying it. Used for CopyOnSelect.
|
||||
bool ControlInteractivity::CopySelectionToClipboard(bool singleLine,
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats,
|
||||
bool clearSelection)
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats)
|
||||
{
|
||||
if (_core)
|
||||
{
|
||||
@@ -165,7 +164,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Mark the current selection as copied
|
||||
_selectionNeedsToBeCopied = false;
|
||||
|
||||
return _core->CopySelectionToClipboard(singleLine, formats, clearSelection);
|
||||
return _core->CopySelectionToClipboard(singleLine, formats);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -258,26 +257,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown))
|
||||
{
|
||||
if (_core->CopyOnSelect())
|
||||
// CopyOnSelect right click always pastes
|
||||
if (_core->CopyOnSelect() || !_core->HasSelection())
|
||||
{
|
||||
// CopyOnSelect:
|
||||
// 1. keyboard selection? --> copy the new content first
|
||||
// 2. right click always pastes!
|
||||
if (_core->IsInQuickEditMode())
|
||||
{
|
||||
CopySelectionToClipboard(shiftEnabled, nullptr);
|
||||
}
|
||||
RequestPasteTextFromClipboard();
|
||||
}
|
||||
else if (_core->HasSelection())
|
||||
{
|
||||
// copy selected text
|
||||
CopySelectionToClipboard(shiftEnabled, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no selection --> paste
|
||||
RequestPasteTextFromClipboard();
|
||||
CopySelectionToClipboard(shiftEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,10 +383,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
isLeftMouseRelease &&
|
||||
_selectionNeedsToBeCopied)
|
||||
{
|
||||
// IMPORTANT!
|
||||
// Set clearSelection to false here!
|
||||
// Otherwise, the selection will be cleared immediately after you make it.
|
||||
CopySelectionToClipboard(false, nullptr, /*clearSelection*/ false);
|
||||
CopySelectionToClipboard(false, nullptr);
|
||||
}
|
||||
|
||||
_singleClickTouchdownPos = std::nullopt;
|
||||
@@ -631,7 +615,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Get the size of the font, which is in pixels
|
||||
const til::size fontSize{ _core->GetFont().GetSize() };
|
||||
// Convert the location in pixels to characters within the current viewport.
|
||||
return til::point{ pixelPosition / fontSize };
|
||||
return pixelPosition / fontSize;
|
||||
}
|
||||
|
||||
bool ControlInteractivity::_sendMouseEventHelper(const til::point terminalPosition,
|
||||
|
||||
@@ -80,8 +80,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
#pragma endregion
|
||||
|
||||
bool CopySelectionToClipboard(bool singleLine,
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats,
|
||||
bool clearSelection = true);
|
||||
const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void RequestPasteTextFromClipboard();
|
||||
void SetEndSelectionPoint(const Core::Point pixelPosition);
|
||||
bool ManglePathsForWsl();
|
||||
@@ -124,7 +123,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// terminal.
|
||||
bool _selectionNeedsToBeCopied;
|
||||
|
||||
std::optional<COORD> _lastHoveredCell{ std::nullopt };
|
||||
std::optional<til::point> _lastHoveredCell{ std::nullopt };
|
||||
// Track the last hyperlink ID we hovered over
|
||||
uint16_t _lastHoveredId{ 0 };
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace Microsoft.Terminal.Control
|
||||
// Experimental Settings
|
||||
Boolean ForceFullRepaintRendering { get; };
|
||||
Boolean SoftwareRendering { get; };
|
||||
Boolean ShowMarks { get; };
|
||||
Boolean UseBackgroundImageForWindow { get; };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,32 @@
|
||||
|
||||
namespace Microsoft.Terminal.Control
|
||||
{
|
||||
enum MarkCategory
|
||||
{
|
||||
Prompt = 0,
|
||||
Error = 1,
|
||||
Warning = 2,
|
||||
Info = 3
|
||||
};
|
||||
|
||||
struct ScrollMark
|
||||
{
|
||||
// There are other members of DispatchTypes::ScrollMark, but these are
|
||||
// all we need to expose up and set downwards currently. Additional
|
||||
// members can be bubbled as necessary.
|
||||
Microsoft.Terminal.Core.Point Start;
|
||||
Microsoft.Terminal.Core.Point End; // exclusive
|
||||
Microsoft.Terminal.Core.OptionalColor Color;
|
||||
};
|
||||
|
||||
enum ScrollToMarkDirection
|
||||
{
|
||||
Previous,
|
||||
Next,
|
||||
First,
|
||||
Last
|
||||
};
|
||||
|
||||
// These are properties of the TerminalCore that should be queryable by the
|
||||
// rest of the app.
|
||||
interface ICoreState
|
||||
@@ -27,5 +53,11 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
UInt64 OwningHwnd;
|
||||
|
||||
void AddMark(ScrollMark mark);
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
void ScrollToMark(ScrollToMarkDirection direction);
|
||||
IVector<ScrollMark> ScrollMarks { get; };
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -146,14 +146,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IControlAccessibilityInfo
|
||||
COORD InteractivityAutomationPeer::GetFontSize() const noexcept
|
||||
til::size InteractivityAutomationPeer::GetFontSize() const noexcept
|
||||
{
|
||||
return til::size{ til::math::rounding, _interactivity->Core().FontSize() }.to_win32_coord();
|
||||
return { til::math::rounding, _interactivity->Core().FontSize() };
|
||||
}
|
||||
|
||||
RECT InteractivityAutomationPeer::GetBounds() const noexcept
|
||||
til::rect InteractivityAutomationPeer::GetBounds() const noexcept
|
||||
{
|
||||
return _controlBounds.to_win32_rect();
|
||||
return _controlBounds;
|
||||
}
|
||||
|
||||
HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
|
||||
@@ -164,9 +164,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RECT InteractivityAutomationPeer::GetPadding() const noexcept
|
||||
til::rect InteractivityAutomationPeer::GetPadding() const noexcept
|
||||
{
|
||||
return _controlPadding.to_win32_rect();
|
||||
return _controlPadding;
|
||||
}
|
||||
|
||||
double InteractivityAutomationPeer::GetScaleFactor() const noexcept
|
||||
@@ -174,7 +174,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
|
||||
}
|
||||
|
||||
void InteractivityAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow)
|
||||
void InteractivityAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
|
||||
{
|
||||
_interactivity->UpdateScrollbar(NewWindow.Top);
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
#pragma region IControlAccessibilityInfo Pattern
|
||||
// Inherited via IControlAccessibilityInfo
|
||||
virtual COORD GetFontSize() const noexcept override;
|
||||
virtual RECT GetBounds() const noexcept override;
|
||||
virtual RECT GetPadding() const noexcept override;
|
||||
virtual til::size GetFontSize() const noexcept override;
|
||||
virtual til::rect GetBounds() const noexcept override;
|
||||
virtual til::rect GetPadding() const noexcept override;
|
||||
virtual double GetScaleFactor() const noexcept override;
|
||||
virtual void ChangeViewport(SMALL_RECT NewWindow) override;
|
||||
virtual void ChangeViewport(const til::inclusive_rect& NewWindow) override;
|
||||
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
|
||||
#pragma endregion
|
||||
|
||||
|
||||
@@ -124,20 +124,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
[weakThis = get_weak()](const auto& update) {
|
||||
if (auto control{ weakThis.get() }; !control->_IsClosing())
|
||||
{
|
||||
control->_isInternalScrollBarUpdate = true;
|
||||
|
||||
auto scrollBar = control->ScrollBar();
|
||||
if (update.newValue)
|
||||
{
|
||||
scrollBar.Value(*update.newValue);
|
||||
}
|
||||
scrollBar.Maximum(update.newMaximum);
|
||||
scrollBar.Minimum(update.newMinimum);
|
||||
scrollBar.ViewportSize(update.newViewportSize);
|
||||
// scroll one full screen worth at a time when the scroll bar is clicked
|
||||
scrollBar.LargeChange(std::max(update.newViewportSize - 1, 0.));
|
||||
|
||||
control->_isInternalScrollBarUpdate = false;
|
||||
control->_throttledUpdateScrollbar(update);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -148,6 +135,57 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_ApplyUISettings();
|
||||
}
|
||||
|
||||
void TermControl::_throttledUpdateScrollbar(const ScrollBarUpdate& update)
|
||||
{
|
||||
// Assumptions:
|
||||
// * we're already not closing
|
||||
// * caller already checked weak ptr to make sure we're still alive
|
||||
|
||||
_isInternalScrollBarUpdate = true;
|
||||
|
||||
auto scrollBar = ScrollBar();
|
||||
if (update.newValue)
|
||||
{
|
||||
scrollBar.Value(*update.newValue);
|
||||
}
|
||||
scrollBar.Maximum(update.newMaximum);
|
||||
scrollBar.Minimum(update.newMinimum);
|
||||
scrollBar.ViewportSize(update.newViewportSize);
|
||||
// scroll one full screen worth at a time when the scroll bar is clicked
|
||||
scrollBar.LargeChange(std::max(update.newViewportSize - 1, 0.));
|
||||
|
||||
_isInternalScrollBarUpdate = false;
|
||||
|
||||
if (_showMarksInScrollbar)
|
||||
{
|
||||
// Update scrollbar marks
|
||||
ScrollBarCanvas().Children().Clear();
|
||||
const auto marks{ _core.ScrollMarks() };
|
||||
const auto fullHeight{ ScrollBarCanvas().ActualHeight() };
|
||||
const auto totalBufferRows{ update.newMaximum + update.newViewportSize };
|
||||
|
||||
for (const auto m : marks)
|
||||
{
|
||||
Windows::UI::Xaml::Shapes::Rectangle r;
|
||||
Media::SolidColorBrush brush{};
|
||||
// Sneaky: technically, a mark doesn't need to have a color set,
|
||||
// it might want to just use the color from the palette for that
|
||||
// kind of mark. Fortunately, ControlCore is kind enough to
|
||||
// pre-evaluate that for us, and shove the real value into the
|
||||
// Color member, regardless if the mark has a literal value set.
|
||||
brush.Color(static_cast<til::color>(m.Color.Color));
|
||||
r.Fill(brush);
|
||||
r.Width(16.0f / 3.0f); // pip width - 1/3rd of the scrollbar width.
|
||||
r.Height(2);
|
||||
const auto markRow = m.Start.Y;
|
||||
const auto fractionalHeight = markRow / totalBufferRows;
|
||||
const auto relativePos = fractionalHeight * fullHeight;
|
||||
ScrollBarCanvas().Children().Append(r);
|
||||
Windows::UI::Xaml::Controls::Canvas::SetTop(r, relativePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Loads the search box from the xaml UI and focuses it.
|
||||
void TermControl::CreateSearchBoxControl()
|
||||
@@ -404,6 +442,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
newMargin.Right,
|
||||
newMargin.Bottom });
|
||||
}
|
||||
|
||||
_showMarksInScrollbar = settings.ShowMarks();
|
||||
// Clear out all the current marks
|
||||
ScrollBarCanvas().Children().Clear();
|
||||
// When we hot reload the settings, the core will send us a scrollbar
|
||||
// update. If we enabled scrollbar marks, then great, when we handle
|
||||
// that message, we'll redraw them.
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -637,7 +682,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// clever way around asking the core for this.
|
||||
til::point TermControl::GetFontSize() const
|
||||
{
|
||||
return til::point{ til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
|
||||
return { til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
|
||||
}
|
||||
|
||||
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
||||
@@ -1137,7 +1182,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// Manually show the cursor when a key is pressed. Restarting
|
||||
// the timer prevents flickering.
|
||||
_core.CursorOn(true);
|
||||
_core.CursorOn(!_core.IsInMarkMode());
|
||||
_cursorTimer->Start();
|
||||
}
|
||||
|
||||
@@ -1608,7 +1653,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
if (_cursorTimer)
|
||||
{
|
||||
// When the terminal focuses, show the cursor immediately
|
||||
_core.CursorOn(true);
|
||||
_core.CursorOn(!_core.IsInMarkMode());
|
||||
_cursorTimer->Start();
|
||||
}
|
||||
|
||||
@@ -1859,6 +1904,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_core.SelectAll();
|
||||
}
|
||||
|
||||
bool TermControl::ToggleBlockSelection()
|
||||
{
|
||||
return _core.ToggleBlockSelection();
|
||||
}
|
||||
|
||||
void TermControl::ToggleMarkMode()
|
||||
{
|
||||
_core.ToggleMarkMode();
|
||||
}
|
||||
|
||||
void TermControl::Close()
|
||||
{
|
||||
if (!_IsClosing())
|
||||
@@ -1964,7 +2019,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// The family is only used to determine if the font is truetype or
|
||||
// not, but DX doesn't use that info at all.
|
||||
// The Codepage is additionally not actually used by the DX engine at all.
|
||||
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, gsl::narrow_cast<short>(fontSize) }, CP_UTF8, false };
|
||||
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontSize }, CP_UTF8, false };
|
||||
FontInfoDesired desiredFont = { actualFont };
|
||||
|
||||
// Create a DX engine and initialize it with our font and DPI. We'll
|
||||
@@ -2853,4 +2908,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.OwningHwnd();
|
||||
}
|
||||
|
||||
void TermControl::AddMark(const Control::ScrollMark& mark)
|
||||
{
|
||||
_core.AddMark(mark);
|
||||
}
|
||||
void TermControl::ClearMark() { _core.ClearMark(); }
|
||||
void TermControl::ClearAllMarks() { _core.ClearAllMarks(); }
|
||||
void TermControl::ScrollToMark(const Control::ScrollToMarkDirection& direction) { _core.ScrollToMark(direction); }
|
||||
|
||||
Windows::Foundation::Collections::IVector<Control::ScrollMark> TermControl::ScrollMarks() const
|
||||
{
|
||||
return _core.ScrollMarks();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void PasteTextFromClipboard();
|
||||
void SelectAll();
|
||||
bool ToggleBlockSelection();
|
||||
void ToggleMarkMode();
|
||||
void Close();
|
||||
Windows::Foundation::Size CharacterDimensions() const;
|
||||
Windows::Foundation::Size MinimumSize();
|
||||
@@ -65,6 +67,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
uint64_t OwningHwnd();
|
||||
void OwningHwnd(uint64_t owner);
|
||||
|
||||
Windows::Foundation::Collections::IVector<Control::ScrollMark> ScrollMarks() const;
|
||||
void AddMark(const Control::ScrollMark& mark);
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void ScrollViewport(int viewTop);
|
||||
@@ -193,6 +202,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
std::optional<Windows::UI::Xaml::DispatcherTimer> _blinkTimer;
|
||||
|
||||
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
||||
bool _showMarksInScrollbar{ false };
|
||||
|
||||
inline bool _IsClosing() const noexcept
|
||||
{
|
||||
@@ -285,6 +295,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
|
||||
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreFoundMatch(const IInspectable& sender, const Control::FoundResultsArgs& args);
|
||||
void _throttledUpdateScrollbar(const ScrollBarUpdate& update);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ namespace Microsoft.Terminal.Control
|
||||
Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference<CopyFormat> formats);
|
||||
void PasteTextFromClipboard();
|
||||
void SelectAll();
|
||||
Boolean ToggleBlockSelection();
|
||||
void ToggleMarkMode();
|
||||
void ClearBuffer(ClearBufferType clearType);
|
||||
void Close();
|
||||
Windows.Foundation.Size CharacterDimensions { get; };
|
||||
|
||||
@@ -1243,6 +1243,30 @@
|
||||
Style="{StaticResource ForkedScrollbarTemplate}"
|
||||
ValueChanged="_ScrollbarChangeHandler"
|
||||
ViewportSize="10" />
|
||||
|
||||
<Grid x:Name="ScrollMarksGrid"
|
||||
Grid.Column="1"
|
||||
Width="{StaticResource ScrollBarSize}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Stretch">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0"
|
||||
Height="{StaticResource ScrollBarSize}" />
|
||||
<Canvas x:Name="ScrollBarCanvas"
|
||||
Grid.Row="1"
|
||||
Width="{StaticResource ScrollBarSize}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Stretch" />
|
||||
<Border Grid.Row="2"
|
||||
Height="{StaticResource ScrollBarSize}" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
<local:TSFInputControl x:Name="TSFInputControl"
|
||||
|
||||
@@ -147,9 +147,14 @@
|
||||
<PRIResource Include="Resources\en-US\Resources.resw" />
|
||||
<OCResourceDirectory Include="Resources" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(WindowsTerminalBranding)'=='' or '$(WindowsTerminalBranding)'=='Dev' or '$(WindowsTerminalBranding)'=='Preview'">
|
||||
<!-- GH#13252 Only vend this dependency for Dev and Preview builds. -->
|
||||
<SDKReference Include="Microsoft.Midi.GmDls, Version=10.0.22000.0" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Project References ======================== -->
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\types\lib\types.vcxproj" />
|
||||
<ProjectReference Include="..\..\audio\midi\lib\midi.vcxproj" />
|
||||
<ProjectReference Include="..\..\buffer\out\lib\bufferout.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\renderer\base\lib\base.vcxproj" />
|
||||
<ProjectReference Include="..\..\renderer\atlas\atlas.vcxproj" />
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Interop.h>
|
||||
#include <winrt/Windows.ui.xaml.markup.h>
|
||||
#include <winrt/Windows.ui.xaml.shapes.h>
|
||||
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
|
||||
|
||||
@@ -24,6 +24,15 @@ namespace Microsoft.Terminal.Core
|
||||
UInt8 A;
|
||||
};
|
||||
|
||||
// Yes, this is also just an IReference<Color>. However, IReference has some
|
||||
// weird ownership semantics that just make it a pain for something as
|
||||
// simple as "maybe this color doesn't have a value set".
|
||||
struct OptionalColor
|
||||
{
|
||||
Boolean HasValue;
|
||||
Microsoft.Terminal.Core.Color Color;
|
||||
};
|
||||
|
||||
// TerminalCore declares its own Color struct to avoid depending on
|
||||
// Windows.UI. Windows.Foundation.Point also exists, but it's composed of
|
||||
// floating-point coordinates, when we almost always need integer coordinates.
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace Microsoft.Terminal.Core
|
||||
|
||||
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> TabColor;
|
||||
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> StartingTabColor;
|
||||
|
||||
Boolean AutoMarkPrompts;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ namespace Microsoft::Terminal::Core
|
||||
ITerminalInput& operator=(ITerminalInput&&) = default;
|
||||
|
||||
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
|
||||
virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
|
||||
virtual bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
|
||||
virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT UserResize(const COORD size) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UserResize(const til::size size) noexcept = 0;
|
||||
virtual void UserScrollViewport(const int viewTop) = 0;
|
||||
virtual int GetScrollOffset() = 0;
|
||||
|
||||
|
||||
@@ -45,11 +45,12 @@ Terminal::Terminal() :
|
||||
_snapOnInput{ true },
|
||||
_altGrAliasing{ true },
|
||||
_blockSelection{ false },
|
||||
_quickEditMode{ false },
|
||||
_markMode{ false },
|
||||
_selection{ std::nullopt },
|
||||
_taskbarState{ 0 },
|
||||
_taskbarProgress{ 0 },
|
||||
_trimBlockSelection{ false }
|
||||
_trimBlockSelection{ false },
|
||||
_autoMarkPrompts{ false }
|
||||
{
|
||||
auto passAlongInput = [&](std::deque<std::unique_ptr<IInputEvent>>& inEventsToWrite) {
|
||||
if (!_pfnWriteInput)
|
||||
@@ -66,12 +67,12 @@ Terminal::Terminal() :
|
||||
_renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, RGB(0, 0, 0));
|
||||
}
|
||||
|
||||
void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& renderer)
|
||||
void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Renderer& renderer)
|
||||
{
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
|
||||
_scrollbackLines = scrollbackLines;
|
||||
const COORD bufferSize{ viewportSize.X,
|
||||
Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
|
||||
const til::size bufferSize{ viewportSize.X,
|
||||
Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
|
||||
const TextAttribute attr{};
|
||||
const UINT cursorSize = 12;
|
||||
_mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, renderer);
|
||||
@@ -97,8 +98,8 @@ void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& rende
|
||||
void Terminal::CreateFromSettings(ICoreSettings settings,
|
||||
Renderer& renderer)
|
||||
{
|
||||
const COORD viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
|
||||
Utils::ClampToShortMax(settings.InitialRows(), 1) };
|
||||
const til::size viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
|
||||
Utils::ClampToShortMax(settings.InitialRows(), 1) };
|
||||
|
||||
// TODO:MSFT:20642297 - Support infinite scrollback here, if HistorySize is -1
|
||||
Create(viewportSize, Utils::ClampToShortMax(settings.HistorySize(), 0), renderer);
|
||||
@@ -121,16 +122,17 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
_suppressApplicationTitle = settings.SuppressApplicationTitle();
|
||||
_startingTitle = settings.StartingTitle();
|
||||
_trimBlockSelection = settings.TrimBlockSelection();
|
||||
_autoMarkPrompts = settings.AutoMarkPrompts();
|
||||
|
||||
_terminalInput->ForceDisableWin32InputMode(settings.ForceVTInput());
|
||||
|
||||
if (settings.TabColor() == nullptr)
|
||||
{
|
||||
_tabColor = std::nullopt;
|
||||
_renderSettings.SetColorTableEntry(TextColor::FRAME_BACKGROUND, INVALID_COLOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tabColor = settings.TabColor().Value();
|
||||
_renderSettings.SetColorTableEntry(TextColor::FRAME_BACKGROUND, til::color{ settings.TabColor().Value() });
|
||||
}
|
||||
|
||||
if (!_startingTabColor && settings.StartingTabColor())
|
||||
@@ -138,11 +140,6 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
_startingTabColor = settings.StartingTabColor().Value();
|
||||
}
|
||||
|
||||
if (_pfnTabColorChanged)
|
||||
{
|
||||
_pfnTabColorChanged(GetTabColor());
|
||||
}
|
||||
|
||||
// TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we
|
||||
// have a smaller scrollback. We should do this carefully - if the new buffer
|
||||
// size is smaller than where the mutable viewport currently is, we'll want
|
||||
@@ -216,6 +213,11 @@ void Terminal::UpdateAppearance(const ICoreAppearance& appearance)
|
||||
}
|
||||
|
||||
_defaultCursorShape = cursorShape;
|
||||
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks whose color
|
||||
// may have changed.
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
|
||||
@@ -248,7 +250,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
// - S_OK if we successfully resized the terminal, S_FALSE if there was
|
||||
// nothing to do (the viewportSize is the same as our current size), or an
|
||||
// appropriate HRESULT for failing to resize.
|
||||
[[nodiscard]] HRESULT Terminal::UserResize(const COORD viewportSize) noexcept
|
||||
[[nodiscard]] HRESULT Terminal::UserResize(const til::size viewportSize) noexcept
|
||||
{
|
||||
const auto oldDimensions = _GetMutableViewport().Dimensions();
|
||||
if (viewportSize == oldDimensions)
|
||||
@@ -263,7 +265,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
if (_inAltBuffer())
|
||||
{
|
||||
// stash this resize for the future.
|
||||
_deferredResize = til::size{ viewportSize };
|
||||
_deferredResize = viewportSize;
|
||||
|
||||
_altBuffer->GetCursor().StartDeferDrawing();
|
||||
// we're capturing `this` here because when we exit, we want to EndDefer on the (newly created) active buffer.
|
||||
@@ -278,19 +280,19 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
// Since the _mutableViewport is no longer the size of the actual
|
||||
// viewport, then update our _altBufferSize tracker we're using to help
|
||||
// us out here.
|
||||
_altBufferSize = til::size{ viewportSize };
|
||||
_altBufferSize = viewportSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const auto dx = ::base::ClampSub(viewportSize.X, oldDimensions.X);
|
||||
const short newBufferHeight = ::base::ClampAdd(viewportSize.Y, _scrollbackLines);
|
||||
const auto dx = viewportSize.X - oldDimensions.X;
|
||||
const auto newBufferHeight = std::clamp(viewportSize.Y + _scrollbackLines, 0, SHRT_MAX);
|
||||
|
||||
COORD bufferSize{ viewportSize.X, newBufferHeight };
|
||||
til::size bufferSize{ viewportSize.X, newBufferHeight };
|
||||
|
||||
// This will be used to determine where the viewport should be in the new buffer.
|
||||
const auto oldViewportTop = _mutableViewport.Top();
|
||||
auto newViewportTop = oldViewportTop;
|
||||
auto newVisibleTop = ::base::saturated_cast<short>(_VisibleStartIndex());
|
||||
auto newVisibleTop = _VisibleStartIndex();
|
||||
|
||||
// If the original buffer had _no_ scroll offset, then we should be at the
|
||||
// bottom in the new buffer as well. Track that case now.
|
||||
@@ -334,7 +336,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
oldRows.mutableViewportTop = oldViewportTop;
|
||||
oldRows.visibleViewportTop = newVisibleTop;
|
||||
|
||||
const std::optional<short> oldViewStart{ oldViewportTop };
|
||||
const std::optional oldViewStart{ oldViewportTop };
|
||||
RETURN_IF_FAILED(TextBuffer::Reflow(*_mainBuffer.get(),
|
||||
*newTextBuffer.get(),
|
||||
_mutableViewport,
|
||||
@@ -388,7 +390,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
|
||||
const auto maxRow = std::max(newLastChar.Y, newCursorPos.Y);
|
||||
|
||||
const short proposedTopFromLastLine = ::base::ClampAdd(::base::ClampSub(maxRow, viewportSize.Y), 1);
|
||||
const auto proposedTopFromLastLine = maxRow - viewportSize.Y + 1;
|
||||
const auto proposedTopFromScrollback = newViewportTop;
|
||||
|
||||
auto proposedTop = std::max(proposedTopFromLastLine,
|
||||
@@ -438,7 +440,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
|
||||
// Make sure the proposed viewport is within the bounds of the buffer.
|
||||
// First make sure the top is >=0
|
||||
proposedTop = std::max(static_cast<short>(0), proposedTop);
|
||||
proposedTop = std::max(0, proposedTop);
|
||||
|
||||
// If the new bottom would be below the bottom of the buffer, then slide the
|
||||
// top up so that we'll still fit within the buffer.
|
||||
@@ -457,7 +459,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
||||
// Make sure that we don't scroll past the mutableViewport at the bottom of the buffer
|
||||
newVisibleTop = std::min(newVisibleTop, _mutableViewport.Top());
|
||||
// Make sure we don't scroll past the top of the scrollback
|
||||
newVisibleTop = std::max<short>(newVisibleTop, 0);
|
||||
newVisibleTop = std::max(newVisibleTop, 0);
|
||||
|
||||
// If the old scrolloffset was 0, then we weren't scrolled back at all
|
||||
// before, and shouldn't be now either.
|
||||
@@ -560,7 +562,7 @@ bool Terminal::ShouldSendAlternateScroll(const unsigned int uiButton,
|
||||
// - Given a coord, get the URI at that location
|
||||
// Arguments:
|
||||
// - The position
|
||||
std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
|
||||
std::wstring Terminal::GetHyperlinkAtPosition(const til::point position)
|
||||
{
|
||||
auto attr = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr();
|
||||
if (attr.IsHyperlink())
|
||||
@@ -576,8 +578,8 @@ std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
|
||||
const auto end = result->stop;
|
||||
std::wstring uri;
|
||||
|
||||
const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start.to_win32_coord()));
|
||||
const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end.to_win32_coord()));
|
||||
const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start));
|
||||
const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end));
|
||||
for (auto iter = startIter; iter != endIter; ++iter)
|
||||
{
|
||||
uri += iter->Chars();
|
||||
@@ -593,7 +595,7 @@ std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
|
||||
// - The position of the text
|
||||
// Return value:
|
||||
// - The hyperlink ID
|
||||
uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
|
||||
uint16_t Terminal::GetHyperlinkIdAtPosition(const til::point position)
|
||||
{
|
||||
return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr().GetHyperlinkId();
|
||||
}
|
||||
@@ -604,9 +606,9 @@ uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
|
||||
// - The position
|
||||
// Return value:
|
||||
// - The interval representing the start and end coordinates
|
||||
std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const COORD position)
|
||||
std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const til::point position)
|
||||
{
|
||||
const auto results = _patternIntervalTree.findOverlapping(til::point{ position.X + 1, position.Y }, til::point{ position });
|
||||
const auto results = _patternIntervalTree.findOverlapping({ position.X + 1, position.Y }, position);
|
||||
if (results.size() > 0)
|
||||
{
|
||||
for (const auto& result : results)
|
||||
@@ -721,16 +723,14 @@ bool Terminal::SendKeyEvent(const WORD vkey,
|
||||
// Return Value:
|
||||
// - true if we translated the key event, and it should not be processed any further.
|
||||
// - false if we did not translate the key, and it should be processed into a character.
|
||||
bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
|
||||
bool Terminal::SendMouseEvent(til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
|
||||
{
|
||||
// GH#6401: VT applications should be able to receive mouse events from outside the
|
||||
// terminal buffer. This is likely to happen when the user drags the cursor offscreen.
|
||||
// We shouldn't throw away perfectly good events when they're offscreen, so we just
|
||||
// clamp them to be within the range [(0, 0), (W, H)].
|
||||
#pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below
|
||||
auto clampedPos{ viewportPos };
|
||||
_GetMutableViewport().ToOrigin().Clamp(clampedPos);
|
||||
return _terminalInput->HandleMouse(til::point{ clampedPos }, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
|
||||
_GetMutableViewport().ToOrigin().Clamp(viewportPos);
|
||||
return _terminalInput->HandleMouse(viewportPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -757,6 +757,22 @@ bool Terminal::SendCharEvent(const wchar_t ch, const WORD scanCode, const Contro
|
||||
vkey = _VirtualKeyFromCharacter(ch);
|
||||
}
|
||||
|
||||
// GH#1527: When the user has auto mark prompts enabled, we're going to try
|
||||
// and heuristically detect if this was the line the prompt was on.
|
||||
// * If the key was an Enter keypress (Terminal.app also marks ^C keypresses
|
||||
// as prompts. That's omitted for now.)
|
||||
// * AND we're not in the alt buffer
|
||||
//
|
||||
// Then treat this line like it's a prompt mark.
|
||||
if (_autoMarkPrompts && vkey == VK_RETURN && !_inAltBuffer())
|
||||
{
|
||||
DispatchTypes::ScrollMark mark;
|
||||
mark.category = DispatchTypes::MarkCategory::Prompt;
|
||||
// Don't set the color - we'll automatically use the DEFAULT_FOREGROUND
|
||||
// color for any MarkCategory::Prompt marks without one set.
|
||||
AddMark(mark);
|
||||
}
|
||||
|
||||
// Unfortunately, the UI doesn't give us both a character down and a
|
||||
// character up event, only a character received event. So fake sending both
|
||||
// to the terminal input translator. Unless it's in win32-input-mode, it'll
|
||||
@@ -789,8 +805,8 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
|
||||
{
|
||||
const auto vis = _VisibleStartIndex();
|
||||
auto invalidate = [=](const PointTree::interval& interval) {
|
||||
COORD startCoord{ gsl::narrow<SHORT>(interval.start.x), gsl::narrow<SHORT>(interval.start.y + vis) };
|
||||
COORD endCoord{ gsl::narrow<SHORT>(interval.stop.x), gsl::narrow<SHORT>(interval.stop.y + vis) };
|
||||
til::point startCoord{ interval.start.x, interval.start.y + vis };
|
||||
til::point endCoord{ interval.stop.x, interval.stop.y + vis };
|
||||
_InvalidateFromCoords(startCoord, endCoord);
|
||||
};
|
||||
tree.visit_all(invalidate);
|
||||
@@ -800,30 +816,30 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
|
||||
// - Given start and end coords, invalidates all the regions between them
|
||||
// Arguments:
|
||||
// - The start and end coords
|
||||
void Terminal::_InvalidateFromCoords(const COORD start, const COORD end)
|
||||
void Terminal::_InvalidateFromCoords(const til::point start, const til::point end)
|
||||
{
|
||||
if (start.Y == end.Y)
|
||||
{
|
||||
SMALL_RECT region{ start.X, start.Y, end.X, end.Y };
|
||||
til::inclusive_rect region{ start.X, start.Y, end.X, end.Y };
|
||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto rowSize = gsl::narrow<SHORT>(_activeBuffer().GetRowByOffset(0).size());
|
||||
const auto rowSize = _activeBuffer().GetRowByOffset(0).size();
|
||||
|
||||
// invalidate the first line
|
||||
SMALL_RECT region{ start.X, start.Y, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(start.Y) };
|
||||
til::inclusive_rect region{ start.X, start.Y, rowSize - 1, start.Y };
|
||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||
|
||||
if ((end.Y - start.Y) > 1)
|
||||
{
|
||||
// invalidate the lines in between the first and last line
|
||||
region = SMALL_RECT{ 0, start.Y + 1, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(end.Y - 1) };
|
||||
region = til::inclusive_rect{ 0, start.Y + 1, rowSize - 1, end.Y - 1 };
|
||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||
}
|
||||
|
||||
// invalidate the last line
|
||||
region = SMALL_RECT{ 0, end.Y, end.X, end.Y };
|
||||
region = til::inclusive_rect{ 0, end.Y, end.X, end.Y };
|
||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||
}
|
||||
}
|
||||
@@ -968,16 +984,25 @@ WORD Terminal::_TakeVirtualKeyFromLastKeyEvent(const WORD scanCode) noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get a reference to the the terminal's read/write lock.
|
||||
// Return Value:
|
||||
// - a ticket_lock which can be used to manually lock or unlock the terminal.
|
||||
til::ticket_lock& Terminal::GetReadWriteLock() noexcept
|
||||
{
|
||||
return _readWriteLock;
|
||||
}
|
||||
|
||||
Viewport Terminal::_GetMutableViewport() const noexcept
|
||||
{
|
||||
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
||||
// viewport's size hasn't been updated yet. In that case, use the
|
||||
// temporarily stashed _altBufferSize instead.
|
||||
return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize.to_win32_coord()) :
|
||||
return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize) :
|
||||
_mutableViewport;
|
||||
}
|
||||
|
||||
short Terminal::GetBufferHeight() const noexcept
|
||||
til::CoordType Terminal::GetBufferHeight() const noexcept
|
||||
{
|
||||
return _GetMutableViewport().BottomExclusive();
|
||||
}
|
||||
@@ -1011,8 +1036,8 @@ Viewport Terminal::_GetVisibleViewport() const noexcept
|
||||
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
||||
// viewport's size hasn't been updated yet. In that case, use the
|
||||
// temporarily stashed _altBufferSize instead.
|
||||
const COORD origin{ 0, gsl::narrow<short>(_VisibleStartIndex()) };
|
||||
const auto size{ _inAltBuffer() ? _altBufferSize.to_win32_coord() :
|
||||
const til::point origin{ 0, _VisibleStartIndex() };
|
||||
const auto size{ _inAltBuffer() ? _altBufferSize :
|
||||
_mutableViewport.Dimensions() };
|
||||
return Viewport::FromDimensions(origin,
|
||||
size);
|
||||
@@ -1056,7 +1081,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
|
||||
{
|
||||
// If "wch" was a surrogate character, we just consumed 2 code units above.
|
||||
// -> Increment "i" by 1 in that case and thus by 2 in total in this iteration.
|
||||
proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance);
|
||||
proposedCursorPosition.X += cellDistance;
|
||||
i += inputDistance - 1;
|
||||
}
|
||||
else
|
||||
@@ -1095,7 +1120,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
|
||||
cursor.EndDeferDrawing();
|
||||
}
|
||||
|
||||
void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
||||
void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
|
||||
{
|
||||
#pragma warning(suppress : 26496) // cpp core checks wants this const but it's modified below.
|
||||
auto proposedCursorPosition = proposedPosition;
|
||||
@@ -1104,7 +1129,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
||||
|
||||
// If we're about to scroll past the bottom of the buffer, instead cycle the
|
||||
// buffer.
|
||||
SHORT rowsPushedOffTopOfBuffer = 0;
|
||||
til::CoordType rowsPushedOffTopOfBuffer = 0;
|
||||
const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
|
||||
if (proposedCursorPosition.Y >= bufferSize.Height())
|
||||
{
|
||||
@@ -1159,7 +1184,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
||||
// In the alt buffer, we never need to adjust _mutableViewport, which is the viewport of the main buffer.
|
||||
if (newViewTop != _mutableViewport.Top())
|
||||
{
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, gsl::narrow<short>(newViewTop) },
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, newViewTop },
|
||||
_mutableViewport.Dimensions());
|
||||
updatedViewport = true;
|
||||
}
|
||||
@@ -1196,10 +1221,21 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
||||
|
||||
if (rowsPushedOffTopOfBuffer != 0)
|
||||
{
|
||||
if (_scrollMarks.size() > 0)
|
||||
{
|
||||
for (auto& mark : _scrollMarks)
|
||||
{
|
||||
mark.start.y -= rowsPushedOffTopOfBuffer;
|
||||
}
|
||||
_scrollMarks.erase(std::remove_if(_scrollMarks.begin(),
|
||||
_scrollMarks.end(),
|
||||
[](const VirtualTerminal::DispatchTypes::ScrollMark& m) { return m.start.y < 0; }),
|
||||
_scrollMarks.end());
|
||||
}
|
||||
// We have to report the delta here because we might have circled the text buffer.
|
||||
// That didn't change the viewport and therefore the TriggerScroll(void)
|
||||
// method can't detect the delta on its own.
|
||||
COORD delta{ 0, gsl::narrow_cast<short>(-rowsPushedOffTopOfBuffer) };
|
||||
til::point delta{ 0, -rowsPushedOffTopOfBuffer };
|
||||
_activeBuffer().TriggerScroll(delta);
|
||||
}
|
||||
}
|
||||
@@ -1273,11 +1309,6 @@ void Terminal::SetTitleChangedCallback(std::function<void(std::wstring_view)> pf
|
||||
_pfnTitleChanged.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetTabColorChangedCallback(std::function<void(const std::optional<til::color>)> pfn) noexcept
|
||||
{
|
||||
_pfnTabColorChanged.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetCopyToClipboardCallback(std::function<void(std::wstring_view)> pfn) noexcept
|
||||
{
|
||||
_pfnCopyToClipboard.swap(pfn);
|
||||
@@ -1312,6 +1343,15 @@ void Terminal::SetShowWindowCallback(std::function<void(bool)> pfn) noexcept
|
||||
_pfnShowWindowChanged.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Allows setting a callback for playing MIDI notes.
|
||||
// Arguments:
|
||||
// - pfn: a function callback that takes a note number, a velocity level, and a duration
|
||||
void Terminal::SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept
|
||||
{
|
||||
_pfnPlayMidiNote.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the cursor to be currently on. On/Off is tracked independently of
|
||||
// cursor visibility (hidden/visible). On/off is controlled by the cursor
|
||||
@@ -1329,7 +1369,7 @@ void Terminal::SetCursorOn(const bool isOn)
|
||||
bool Terminal::IsCursorBlinkingAllowed() const noexcept
|
||||
{
|
||||
const auto& cursor = _activeBuffer().GetCursor();
|
||||
return cursor.IsBlinkingAllowed();
|
||||
return !_markMode && cursor.IsBlinkingAllowed();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1358,10 +1398,18 @@ void Terminal::ClearPatternTree() noexcept
|
||||
|
||||
// Method Description:
|
||||
// - Returns the tab color
|
||||
// If the starting color exits, it's value is preferred
|
||||
// If the starting color exists, its value is preferred
|
||||
const std::optional<til::color> Terminal::GetTabColor() const noexcept
|
||||
{
|
||||
return _startingTabColor.has_value() ? _startingTabColor : _tabColor;
|
||||
if (_startingTabColor.has_value())
|
||||
{
|
||||
return _startingTabColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto tabColor = _renderSettings.GetColorAlias(ColorAlias::FrameBackground);
|
||||
return tabColor == INVALID_COLOR ? std::nullopt : std::optional<til::color>{ tabColor };
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1436,6 +1484,11 @@ void Terminal::ApplyScheme(const Scheme& colorScheme)
|
||||
_renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, til::color{ colorScheme.CursorColor });
|
||||
|
||||
_renderSettings.MakeAdjustedColorArray();
|
||||
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks whose color
|
||||
// may have changed.
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
bool Terminal::_inAltBuffer() const noexcept
|
||||
@@ -1463,11 +1516,100 @@ void Terminal::_updateUrlDetection()
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the position of the cursor relative to the active viewport
|
||||
til::point Terminal::GetViewportRelativeCursorPosition() const noexcept
|
||||
void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
|
||||
const til::point& start,
|
||||
const til::point& end)
|
||||
{
|
||||
const til::point absoluteCursorPosition{ GetCursorPosition() };
|
||||
const auto viewport{ _GetMutableViewport() };
|
||||
return absoluteCursorPosition - til::point{ viewport.Origin() };
|
||||
if (_inAltBuffer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DispatchTypes::ScrollMark m = mark;
|
||||
m.start = start;
|
||||
m.end = end;
|
||||
|
||||
_scrollMarks.push_back(m);
|
||||
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
void Terminal::ClearMark()
|
||||
{
|
||||
// Look for one where the cursor is, or where the selection is if we have
|
||||
// one. Any mark that intersects the cursor/selection, on either side
|
||||
// (inclusive), will get cleared.
|
||||
const til::point cursor{ _activeBuffer().GetCursor().GetPosition() };
|
||||
til::point start{ cursor };
|
||||
til::point end{ cursor };
|
||||
|
||||
if (IsSelectionActive())
|
||||
{
|
||||
start = til::point{ GetSelectionAnchor() };
|
||||
end = til::point{ GetSelectionEnd() };
|
||||
}
|
||||
|
||||
_scrollMarks.erase(std::remove_if(_scrollMarks.begin(),
|
||||
_scrollMarks.end(),
|
||||
[&start, &end](const auto& m) {
|
||||
return (m.start >= start && m.start <= end) ||
|
||||
(m.end >= start && m.end <= end);
|
||||
}),
|
||||
_scrollMarks.end());
|
||||
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
void Terminal::ClearAllMarks()
|
||||
{
|
||||
_scrollMarks.clear();
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark>& Terminal::GetScrollMarks() const
|
||||
{
|
||||
// TODO: GH#11000 - when the marks are stored per-buffer, get rid of this.
|
||||
// We want to return _no_ marks when we're in the alt buffer, to effectively
|
||||
// hide them. We need to return a reference, so we can't just ctor an empty
|
||||
// list here just for when we're in the alt buffer.
|
||||
static std::vector<DispatchTypes::ScrollMark> _altBufferMarks{};
|
||||
return _inAltBuffer() ? _altBufferMarks : _scrollMarks;
|
||||
}
|
||||
|
||||
til::color Terminal::GetColorForMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) const
|
||||
{
|
||||
if (mark.color.has_value())
|
||||
{
|
||||
return *mark.color;
|
||||
}
|
||||
|
||||
switch (mark.category)
|
||||
{
|
||||
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Prompt:
|
||||
{
|
||||
return _renderSettings.GetColorAlias(ColorAlias::DefaultForeground);
|
||||
}
|
||||
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Error:
|
||||
{
|
||||
return _renderSettings.GetColorTableEntry(TextColor::BRIGHT_RED);
|
||||
}
|
||||
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Warning:
|
||||
{
|
||||
return _renderSettings.GetColorTableEntry(TextColor::BRIGHT_YELLOW);
|
||||
}
|
||||
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Success:
|
||||
{
|
||||
return _renderSettings.GetColorTableEntry(TextColor::BRIGHT_GREEN);
|
||||
}
|
||||
default:
|
||||
case Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Info:
|
||||
{
|
||||
return _renderSettings.GetColorAlias(ColorAlias::DefaultForeground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ public:
|
||||
Terminal& operator=(const Terminal&) = default;
|
||||
Terminal& operator=(Terminal&&) = default;
|
||||
|
||||
void Create(COORD viewportSize,
|
||||
SHORT scrollbackLines,
|
||||
void Create(til::size viewportSize,
|
||||
til::CoordType scrollbackLines,
|
||||
Microsoft::Console::Render::Renderer& renderer);
|
||||
|
||||
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
|
||||
@@ -84,8 +84,6 @@ public:
|
||||
bool IsXtermBracketedPasteModeEnabled() const;
|
||||
std::wstring_view GetWorkingDirectory();
|
||||
|
||||
til::point GetViewportRelativeCursorPosition() const noexcept;
|
||||
|
||||
// Write comes from the PTY and goes to our parser to be stored in the output buffer
|
||||
void Write(std::wstring_view stringView);
|
||||
|
||||
@@ -94,8 +92,9 @@ public:
|
||||
|
||||
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForReading();
|
||||
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
|
||||
til::ticket_lock& GetReadWriteLock() noexcept;
|
||||
|
||||
short GetBufferHeight() const noexcept;
|
||||
til::CoordType GetBufferHeight() const noexcept;
|
||||
|
||||
int ViewStartIndex() const noexcept;
|
||||
int ViewEndIndex() const noexcept;
|
||||
@@ -103,6 +102,11 @@ public:
|
||||
RenderSettings& GetRenderSettings() noexcept { return _renderSettings; };
|
||||
const RenderSettings& GetRenderSettings() const noexcept { return _renderSettings; };
|
||||
|
||||
const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark>& GetScrollMarks() const;
|
||||
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
|
||||
const til::point& start,
|
||||
const til::point& end);
|
||||
|
||||
#pragma region ITerminalApi
|
||||
// These methods are defined in TerminalApi.cpp
|
||||
void PrintString(const std::wstring_view string) override;
|
||||
@@ -119,28 +123,36 @@ public:
|
||||
void LineFeed(const bool withReturn) override;
|
||||
void SetWindowTitle(const std::wstring_view title) override;
|
||||
CursorType GetUserDefaultCursorStyle() const override;
|
||||
bool ResizeWindow(const size_t width, const size_t height) override;
|
||||
bool ResizeWindow(const til::CoordType width, const til::CoordType height) override;
|
||||
void SetConsoleOutputCP(const unsigned int codepage) override;
|
||||
unsigned int GetConsoleOutputCP() const override;
|
||||
void EnableXtermBracketedPasteMode(const bool enabled) override;
|
||||
void CopyToClipboard(std::wstring_view content) override;
|
||||
void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) override;
|
||||
void SetWorkingDirectory(std::wstring_view uri) override;
|
||||
void PlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) override;
|
||||
void ShowWindow(bool showOrHide) override;
|
||||
void UseAlternateScreenBuffer() override;
|
||||
void UseMainScreenBuffer() override;
|
||||
|
||||
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) override;
|
||||
|
||||
bool IsConsolePty() const override;
|
||||
bool IsVtInputEnabled() const override;
|
||||
void NotifyAccessibilityChange(const til::rect& changedRect) override;
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
void ClearAllMarks();
|
||||
til::color GetColorForMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) const;
|
||||
|
||||
#pragma region ITerminalInput
|
||||
// These methods are defined in Terminal.cpp
|
||||
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
|
||||
bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
|
||||
bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
|
||||
bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
|
||||
|
||||
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
|
||||
[[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept override;
|
||||
void UserScrollViewport(const int viewTop) override;
|
||||
int GetScrollOffset() noexcept override;
|
||||
|
||||
@@ -150,14 +162,14 @@ public:
|
||||
|
||||
void FocusChanged(const bool focused) noexcept override;
|
||||
|
||||
std::wstring GetHyperlinkAtPosition(const COORD position);
|
||||
uint16_t GetHyperlinkIdAtPosition(const COORD position);
|
||||
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const COORD position);
|
||||
std::wstring GetHyperlinkAtPosition(const til::point position);
|
||||
uint16_t GetHyperlinkIdAtPosition(const til::point position);
|
||||
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const til::point position);
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IBaseData(base to IRenderData and IUiaData)
|
||||
Microsoft::Console::Types::Viewport GetViewport() noexcept override;
|
||||
COORD GetTextBufferEndPosition() const noexcept override;
|
||||
til::point GetTextBufferEndPosition() const noexcept override;
|
||||
const TextBuffer& GetTextBuffer() const noexcept override;
|
||||
const FontInfo& GetFontInfo() const noexcept override;
|
||||
|
||||
@@ -167,7 +179,7 @@ public:
|
||||
|
||||
#pragma region IRenderData
|
||||
// These methods are defined in TerminalRenderData.cpp
|
||||
COORD GetCursorPosition() const noexcept override;
|
||||
til::point GetCursorPosition() const noexcept override;
|
||||
bool IsCursorVisible() const noexcept override;
|
||||
bool IsCursorOn() const noexcept override;
|
||||
ULONG GetCursorHeight() const noexcept override;
|
||||
@@ -178,7 +190,7 @@ public:
|
||||
const bool IsGridLineDrawingAllowed() noexcept override;
|
||||
const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
|
||||
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
|
||||
const std::vector<size_t> GetPatternId(const COORD location) const noexcept override;
|
||||
const std::vector<size_t> GetPatternId(const til::point location) const noexcept override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IUiaData
|
||||
@@ -187,23 +199,23 @@ public:
|
||||
const bool IsSelectionActive() const noexcept override;
|
||||
const bool IsBlockSelection() const noexcept override;
|
||||
void ClearSelection() override;
|
||||
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
|
||||
const COORD GetSelectionAnchor() const noexcept override;
|
||||
const COORD GetSelectionEnd() const noexcept override;
|
||||
void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override;
|
||||
const til::point GetSelectionAnchor() const noexcept override;
|
||||
const til::point GetSelectionEnd() const noexcept override;
|
||||
const std::wstring_view GetConsoleTitle() const noexcept override;
|
||||
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
|
||||
void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute) override;
|
||||
const bool IsUiaDataInitialized() const noexcept override;
|
||||
#pragma endregion
|
||||
|
||||
void SetWriteInputCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
||||
void SetWarningBellCallback(std::function<void()> pfn) noexcept;
|
||||
void SetTitleChangedCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
||||
void SetTabColorChangedCallback(std::function<void(const std::optional<til::color>)> pfn) noexcept;
|
||||
void SetCopyToClipboardCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
||||
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
|
||||
void SetCursorPositionChangedCallback(std::function<void()> pfn) noexcept;
|
||||
void TaskbarProgressChangedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
|
||||
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
|
||||
|
||||
void SetCursorOn(const bool isOn);
|
||||
bool IsCursorBlinkingAllowed() const noexcept;
|
||||
@@ -237,16 +249,17 @@ public:
|
||||
Viewport,
|
||||
Buffer
|
||||
};
|
||||
void MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode);
|
||||
void SetSelectionAnchor(const COORD position);
|
||||
void SetSelectionEnd(const COORD position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
|
||||
void MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode);
|
||||
void SetSelectionAnchor(const til::point position);
|
||||
void SetSelectionEnd(const til::point position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
|
||||
void SetBlockSelection(const bool isEnabled) noexcept;
|
||||
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode);
|
||||
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
|
||||
void SelectAll();
|
||||
bool IsInQuickEditMode() const noexcept;
|
||||
bool IsInMarkMode() const;
|
||||
void ToggleMarkMode();
|
||||
|
||||
using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
|
||||
static UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey);
|
||||
UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const;
|
||||
|
||||
const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace);
|
||||
#pragma endregion
|
||||
@@ -270,9 +283,9 @@ private:
|
||||
|
||||
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
|
||||
std::function<void()> _pfnCursorPositionChanged;
|
||||
std::function<void(const std::optional<til::color>)> _pfnTabColorChanged;
|
||||
std::function<void()> _pfnTaskbarProgressChanged;
|
||||
std::function<void(bool)> _pfnShowWindowChanged;
|
||||
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
@@ -280,7 +293,6 @@ private:
|
||||
|
||||
std::optional<std::wstring> _title;
|
||||
std::wstring _startingTitle;
|
||||
std::optional<til::color> _tabColor;
|
||||
std::optional<til::color> _startingTabColor;
|
||||
|
||||
CursorType _defaultCursorShape;
|
||||
@@ -290,6 +302,7 @@ private:
|
||||
bool _suppressApplicationTitle;
|
||||
bool _bracketedPasteMode;
|
||||
bool _trimBlockSelection;
|
||||
bool _autoMarkPrompts;
|
||||
|
||||
size_t _taskbarState;
|
||||
size_t _taskbarProgress;
|
||||
@@ -303,26 +316,26 @@ private:
|
||||
FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
|
||||
#pragma region Text Selection
|
||||
// a selection is represented as a range between two COORDs (start and end)
|
||||
// the pivot is the COORD that remains selected when you extend a selection in any direction
|
||||
// the pivot is the til::point that remains selected when you extend a selection in any direction
|
||||
// this is particularly useful when a word selection is extended over its starting point
|
||||
// see TerminalSelection.cpp for more information
|
||||
struct SelectionAnchors
|
||||
{
|
||||
COORD start;
|
||||
COORD end;
|
||||
COORD pivot;
|
||||
til::point start;
|
||||
til::point end;
|
||||
til::point pivot;
|
||||
};
|
||||
std::optional<SelectionAnchors> _selection;
|
||||
bool _blockSelection;
|
||||
std::wstring _wordDelimiters;
|
||||
SelectionExpansion _multiClickSelectionMode;
|
||||
bool _quickEditMode;
|
||||
bool _markMode;
|
||||
#pragma endregion
|
||||
|
||||
std::unique_ptr<TextBuffer> _mainBuffer;
|
||||
std::unique_ptr<TextBuffer> _altBuffer;
|
||||
Microsoft::Console::Types::Viewport _mutableViewport;
|
||||
SHORT _scrollbackLines;
|
||||
til::CoordType _scrollbackLines;
|
||||
bool _detectURLs{ false };
|
||||
|
||||
til::size _altBufferSize;
|
||||
@@ -346,7 +359,7 @@ private:
|
||||
|
||||
interval_tree::IntervalTree<til::point, size_t> _patternIntervalTree;
|
||||
void _InvalidatePatternTree(interval_tree::IntervalTree<til::point, size_t>& tree);
|
||||
void _InvalidateFromCoords(const COORD start, const COORD end);
|
||||
void _InvalidateFromCoords(const til::point start, const til::point end);
|
||||
|
||||
// Since virtual keys are non-zero, you assume that this field is empty/invalid if it is.
|
||||
struct KeyEventCodes
|
||||
@@ -356,6 +369,8 @@ private:
|
||||
};
|
||||
std::optional<KeyEventCodes> _lastKeyEventCodes;
|
||||
|
||||
std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark> _scrollMarks;
|
||||
|
||||
static WORD _ScanCodeFromVirtualKey(const WORD vkey) noexcept;
|
||||
static WORD _VirtualKeyFromScanCode(const WORD scanCode) noexcept;
|
||||
static WORD _VirtualKeyFromCharacter(const wchar_t ch) noexcept;
|
||||
@@ -372,7 +387,7 @@ private:
|
||||
|
||||
void _WriteBuffer(const std::wstring_view& stringView);
|
||||
|
||||
void _AdjustCursorPosition(const COORD proposedPosition);
|
||||
void _AdjustCursorPosition(const til::point proposedPosition);
|
||||
|
||||
void _NotifyScrollEvent() noexcept;
|
||||
|
||||
@@ -384,14 +399,14 @@ private:
|
||||
|
||||
#pragma region TextSelection
|
||||
// These methods are defined in TerminalSelection.cpp
|
||||
std::vector<SMALL_RECT> _GetSelectionRects() const noexcept;
|
||||
std::pair<COORD, COORD> _PivotSelection(const COORD targetPos, bool& targetStart) const;
|
||||
std::pair<COORD, COORD> _ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const;
|
||||
COORD _ConvertToBufferCell(const COORD viewportPos) const;
|
||||
void _MoveByChar(SelectionDirection direction, COORD& pos);
|
||||
void _MoveByWord(SelectionDirection direction, COORD& pos);
|
||||
void _MoveByViewport(SelectionDirection direction, COORD& pos);
|
||||
void _MoveByBuffer(SelectionDirection direction, COORD& pos);
|
||||
std::vector<til::inclusive_rect> _GetSelectionRects() const noexcept;
|
||||
std::pair<til::point, til::point> _PivotSelection(const til::point targetPos, bool& targetStart) const;
|
||||
std::pair<til::point, til::point> _ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const;
|
||||
til::point _ConvertToBufferCell(const til::point viewportPos) const;
|
||||
void _MoveByChar(SelectionDirection direction, til::point& pos);
|
||||
void _MoveByWord(SelectionDirection direction, til::point& pos);
|
||||
void _MoveByViewport(SelectionDirection direction, til::point& pos);
|
||||
void _MoveByBuffer(SelectionDirection direction, til::point& pos);
|
||||
#pragma endregion
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
|
||||
@@ -45,7 +45,7 @@ void Terminal::SetViewportPosition(const til::point position)
|
||||
if (!_inAltBuffer())
|
||||
{
|
||||
const auto dimensions = _GetMutableViewport().Dimensions();
|
||||
_mutableViewport = Viewport::FromDimensions(position.to_win32_coord(), dimensions);
|
||||
_mutableViewport = Viewport::FromDimensions(position, dimensions);
|
||||
Terminal::_NotifyScrollEvent();
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ CursorType Terminal::GetUserDefaultCursorStyle() const
|
||||
return _defaultCursorShape;
|
||||
}
|
||||
|
||||
bool Terminal::ResizeWindow(const size_t /*width*/, const size_t /*height*/)
|
||||
bool Terminal::ResizeWindow(const til::CoordType /*width*/, const til::CoordType /*height*/)
|
||||
{
|
||||
// TODO: This will be needed to support various resizing sequences. See also GH#1860.
|
||||
return false;
|
||||
@@ -188,10 +188,15 @@ void Terminal::SetWorkingDirectory(std::wstring_view uri)
|
||||
_workingDirectory = uri;
|
||||
}
|
||||
|
||||
void Terminal::PlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration)
|
||||
{
|
||||
_pfnPlayMidiNote(noteNumber, velocity, duration);
|
||||
}
|
||||
|
||||
void Terminal::UseAlternateScreenBuffer()
|
||||
{
|
||||
// the new alt buffer is exactly the size of the viewport.
|
||||
_altBufferSize = til::size{ _mutableViewport.Dimensions() };
|
||||
_altBufferSize = _mutableViewport.Dimensions();
|
||||
|
||||
const auto cursorSize = _mainBuffer->GetCursor().GetSize();
|
||||
|
||||
@@ -199,7 +204,7 @@ void Terminal::UseAlternateScreenBuffer()
|
||||
_mainBuffer->ClearPatternRecognizers();
|
||||
|
||||
// Create a new alt buffer
|
||||
_altBuffer = std::make_unique<TextBuffer>(_altBufferSize.to_win32_coord(),
|
||||
_altBuffer = std::make_unique<TextBuffer>(_altBufferSize,
|
||||
TextAttribute{},
|
||||
cursorSize,
|
||||
true,
|
||||
@@ -270,7 +275,7 @@ void Terminal::UseMainScreenBuffer()
|
||||
|
||||
if (_deferredResize.has_value())
|
||||
{
|
||||
LOG_IF_FAILED(UserResize(_deferredResize.value().to_win32_coord()));
|
||||
LOG_IF_FAILED(UserResize(_deferredResize.value()));
|
||||
_deferredResize = std::nullopt;
|
||||
}
|
||||
|
||||
@@ -293,6 +298,12 @@ void Terminal::UseMainScreenBuffer()
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark)
|
||||
{
|
||||
const til::point cursorPos{ _activeBuffer().GetCursor().GetPosition() };
|
||||
AddMark(mark, cursorPos, cursorPos);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Reacts to a client asking us to show or hide the window.
|
||||
// Arguments:
|
||||
|
||||
@@ -43,9 +43,9 @@ using namespace Microsoft::Terminal::Core;
|
||||
// - Helper to determine the selected region of the buffer. Used for rendering.
|
||||
// Return Value:
|
||||
// - A vector of rectangles representing the regions to select, line by line. They are absolute coordinates relative to the buffer origin.
|
||||
std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
|
||||
std::vector<til::inclusive_rect> Terminal::_GetSelectionRects() const noexcept
|
||||
{
|
||||
std::vector<SMALL_RECT> result;
|
||||
std::vector<til::inclusive_rect> result;
|
||||
|
||||
if (!IsSelectionActive())
|
||||
{
|
||||
@@ -66,7 +66,7 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
|
||||
// - None
|
||||
// Return Value:
|
||||
// - None
|
||||
const COORD Terminal::GetSelectionAnchor() const noexcept
|
||||
const til::point Terminal::GetSelectionAnchor() const noexcept
|
||||
{
|
||||
return _selection->start;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ const COORD Terminal::GetSelectionAnchor() const noexcept
|
||||
// - None
|
||||
// Return Value:
|
||||
// - None
|
||||
const COORD Terminal::GetSelectionEnd() const noexcept
|
||||
const til::point Terminal::GetSelectionEnd() const noexcept
|
||||
{
|
||||
return _selection->end;
|
||||
}
|
||||
@@ -96,17 +96,12 @@ const bool Terminal::IsBlockSelection() const noexcept
|
||||
return _blockSelection;
|
||||
}
|
||||
|
||||
bool Terminal::IsInQuickEditMode() const noexcept
|
||||
{
|
||||
return _quickEditMode;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Perform a multi-click selection at viewportPos expanding according to the expansionMode
|
||||
// Arguments:
|
||||
// - viewportPos: the (x,y) coordinate on the visible viewport
|
||||
// - expansionMode: the SelectionExpansion to dictate the boundaries of the selection anchors
|
||||
void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode)
|
||||
void Terminal::MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode)
|
||||
{
|
||||
// set the selection pivot to expand the selection using SetSelectionEnd()
|
||||
_selection = SelectionAnchors{};
|
||||
@@ -124,7 +119,7 @@ void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion e
|
||||
// - Record the position of the beginning of a selection
|
||||
// Arguments:
|
||||
// - position: the (x,y) coordinate on the visible viewport
|
||||
void Terminal::SetSelectionAnchor(const COORD viewportPos)
|
||||
void Terminal::SetSelectionAnchor(const til::point viewportPos)
|
||||
{
|
||||
_selection = SelectionAnchors{};
|
||||
_selection->pivot = _ConvertToBufferCell(viewportPos);
|
||||
@@ -141,7 +136,7 @@ void Terminal::SetSelectionAnchor(const COORD viewportPos)
|
||||
// Arguments:
|
||||
// - viewportPos: the (x,y) coordinate on the visible viewport
|
||||
// - newExpansionMode: overwrites the _multiClickSelectionMode for this function call. Used for ShiftClick
|
||||
void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionExpansion> newExpansionMode)
|
||||
void Terminal::SetSelectionEnd(const til::point viewportPos, std::optional<SelectionExpansion> newExpansionMode)
|
||||
{
|
||||
if (!_selection.has_value())
|
||||
{
|
||||
@@ -185,7 +180,7 @@ void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionE
|
||||
// - targetStart: if true, target will be the new start. Otherwise, target will be the new end.
|
||||
// Return Value:
|
||||
// - the new start/end for a selection
|
||||
std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& targetStart) const
|
||||
std::pair<til::point, til::point> Terminal::_PivotSelection(const til::point targetPos, bool& targetStart) const
|
||||
{
|
||||
if (targetStart = _activeBuffer().GetSize().CompareInBounds(targetPos, _selection->pivot) <= 0)
|
||||
{
|
||||
@@ -207,7 +202,7 @@ std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& t
|
||||
// - anchors: a pair of selection anchors representing a desired selection
|
||||
// Return Value:
|
||||
// - the new start/end for a selection
|
||||
std::pair<COORD, COORD> Terminal::_ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const
|
||||
std::pair<til::point, til::point> Terminal::_ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const
|
||||
{
|
||||
auto start = anchors.first;
|
||||
auto end = anchors.second;
|
||||
@@ -240,13 +235,41 @@ void Terminal::SetBlockSelection(const bool isEnabled) noexcept
|
||||
_blockSelection = isEnabled;
|
||||
}
|
||||
|
||||
Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey)
|
||||
bool Terminal::IsInMarkMode() const
|
||||
{
|
||||
if (mods.IsShiftPressed() && !mods.IsAltPressed())
|
||||
return _markMode;
|
||||
}
|
||||
|
||||
void Terminal::ToggleMarkMode()
|
||||
{
|
||||
if (_markMode)
|
||||
{
|
||||
// Exit Mark Mode
|
||||
ClearSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enter Mark Mode
|
||||
// NOTE: directly set cursor state. We already should have locked before calling this function.
|
||||
_activeBuffer().GetCursor().SetIsOn(false);
|
||||
const auto cursorPos{ _activeBuffer().GetCursor().GetPosition() };
|
||||
_selection = SelectionAnchors{};
|
||||
_selection->start = cursorPos;
|
||||
_selection->end = cursorPos;
|
||||
_selection->pivot = cursorPos;
|
||||
_markMode = true;
|
||||
_blockSelection = false;
|
||||
}
|
||||
}
|
||||
|
||||
Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const
|
||||
{
|
||||
if ((_markMode || mods.IsShiftPressed()) && !mods.IsAltPressed())
|
||||
{
|
||||
if (mods.IsCtrlPressed())
|
||||
{
|
||||
// Ctrl + Shift + _
|
||||
// (Mark Mode) Ctrl + _
|
||||
switch (vkey)
|
||||
{
|
||||
case VK_LEFT:
|
||||
@@ -262,6 +285,7 @@ Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams
|
||||
else
|
||||
{
|
||||
// Shift + _
|
||||
// (Mark Mode) Just the vkeys
|
||||
switch (vkey)
|
||||
{
|
||||
case VK_HOME:
|
||||
@@ -286,14 +310,22 @@ Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion mode)
|
||||
// Method Description:
|
||||
// - updates the selection endpoints based on a direction and expansion mode. Primarily used for keyboard selection.
|
||||
// Arguments:
|
||||
// - direction: the direction to move the selection endpoint in
|
||||
// - mode: the type of movement to be performed (i.e. move by word)
|
||||
// - mods: the key modifiers pressed when performing this update
|
||||
void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods)
|
||||
{
|
||||
// 1. Figure out which endpoint to update
|
||||
// One of the endpoints is the pivot, signifying that the other endpoint is the one we want to move.
|
||||
const auto movingEnd{ _selection->start == _selection->pivot };
|
||||
// If we're in mark mode, shift dictates whether you are moving the end or not.
|
||||
// Otherwise, we're updating an existing selection, so one of the endpoints is the pivot,
|
||||
// signifying that the other endpoint is the one we want to move.
|
||||
const auto movingEnd{ _markMode ? mods.IsShiftPressed() : _selection->start == _selection->pivot };
|
||||
auto targetPos{ movingEnd ? _selection->end : _selection->start };
|
||||
|
||||
// 2 Perform the movement
|
||||
// 2. Perform the movement
|
||||
switch (mode)
|
||||
{
|
||||
case SelectionExpansion::Char:
|
||||
@@ -312,14 +344,28 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
|
||||
|
||||
// 3. Actually modify the selection
|
||||
// NOTE: targetStart doesn't matter here
|
||||
auto targetStart = false;
|
||||
_quickEditMode = true;
|
||||
std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);
|
||||
if (_markMode)
|
||||
{
|
||||
// [Mark Mode]
|
||||
// - moveSelectionEnd --> just move end (i.e. shift + arrow keys)
|
||||
// - !moveSelectionEnd --> move all three (i.e. just use arrow keys)
|
||||
_selection->end = targetPos;
|
||||
if (!movingEnd)
|
||||
{
|
||||
_selection->start = targetPos;
|
||||
_selection->pivot = targetPos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto targetStart = false;
|
||||
std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);
|
||||
}
|
||||
|
||||
// 4. Scroll (if necessary)
|
||||
if (const auto visibleViewport = _GetVisibleViewport(); !visibleViewport.IsInBounds(targetPos))
|
||||
if (const auto viewport = _GetVisibleViewport(); !viewport.IsInBounds(targetPos))
|
||||
{
|
||||
if (const auto amtAboveView = visibleViewport.Top() - targetPos.Y; amtAboveView > 0)
|
||||
if (const auto amtAboveView = viewport.Top() - targetPos.Y; amtAboveView > 0)
|
||||
{
|
||||
// anchor is above visible viewport, scroll by that amount
|
||||
_scrollOffset += amtAboveView;
|
||||
@@ -327,7 +373,7 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
|
||||
else
|
||||
{
|
||||
// anchor is below visible viewport, scroll by that amount
|
||||
const auto amtBelowView = targetPos.Y - visibleViewport.BottomInclusive();
|
||||
const auto amtBelowView = targetPos.Y - viewport.BottomInclusive();
|
||||
_scrollOffset -= amtBelowView;
|
||||
}
|
||||
_NotifyScrollEvent();
|
||||
@@ -344,41 +390,39 @@ void Terminal::SelectAll()
|
||||
_selection->pivot = _selection->end;
|
||||
}
|
||||
|
||||
void Terminal::_MoveByChar(SelectionDirection direction, COORD& pos)
|
||||
void Terminal::_MoveByChar(SelectionDirection direction, til::point& pos)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case SelectionDirection::Left:
|
||||
_activeBuffer().GetSize().DecrementInBounds(pos);
|
||||
pos = _activeBuffer().GetGlyphStart(til::point{ pos }).to_win32_coord();
|
||||
pos = _activeBuffer().GetGlyphStart(pos);
|
||||
break;
|
||||
case SelectionDirection::Right:
|
||||
_activeBuffer().GetSize().IncrementInBounds(pos);
|
||||
pos = _activeBuffer().GetGlyphEnd(til::point{ pos }).to_win32_coord();
|
||||
pos = _activeBuffer().GetGlyphEnd(pos);
|
||||
break;
|
||||
case SelectionDirection::Up:
|
||||
{
|
||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||
const auto newY{ base::ClampSub<short, short>(pos.Y, 1).RawValue() };
|
||||
pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY };
|
||||
pos = { pos.X, std::clamp(pos.Y - 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
|
||||
break;
|
||||
}
|
||||
case SelectionDirection::Down:
|
||||
{
|
||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||
const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
|
||||
const auto newY{ base::ClampAdd<short, short>(pos.Y, 1).RawValue() };
|
||||
pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY };
|
||||
pos = { pos.X, std::clamp(pos.Y + 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
||||
void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case SelectionDirection::Left:
|
||||
{
|
||||
const auto wordStartPos{ _activeBuffer().GetWordStart(pos, _wordDelimiters) };
|
||||
if (_activeBuffer().GetSize().CompareInBounds(_selection->pivot, pos) < 0)
|
||||
{
|
||||
@@ -399,7 +443,9 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
||||
pos = wordStartPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SelectionDirection::Right:
|
||||
{
|
||||
const auto wordEndPos{ _activeBuffer().GetWordEnd(pos, _wordDelimiters) };
|
||||
if (_activeBuffer().GetSize().CompareInBounds(pos, _selection->pivot) < 0)
|
||||
{
|
||||
@@ -420,6 +466,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
||||
pos = wordEndPos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SelectionDirection::Up:
|
||||
_MoveByChar(direction, pos);
|
||||
pos = _activeBuffer().GetWordStart(pos, _wordDelimiters);
|
||||
@@ -431,7 +478,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
|
||||
void Terminal::_MoveByViewport(SelectionDirection direction, til::point& pos)
|
||||
{
|
||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||
switch (direction)
|
||||
@@ -445,22 +492,22 @@ void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
|
||||
case SelectionDirection::Up:
|
||||
{
|
||||
const auto viewportHeight{ _GetMutableViewport().Height() };
|
||||
const auto newY{ base::ClampSub<short, short>(pos.Y, viewportHeight) };
|
||||
pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY };
|
||||
const auto newY{ pos.Y - viewportHeight };
|
||||
pos = newY < bufferSize.Top() ? bufferSize.Origin() : til::point{ pos.X, newY };
|
||||
break;
|
||||
}
|
||||
case SelectionDirection::Down:
|
||||
{
|
||||
const auto viewportHeight{ _GetMutableViewport().Height() };
|
||||
const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
|
||||
const auto newY{ base::ClampAdd<short, short>(pos.Y, viewportHeight) };
|
||||
pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY };
|
||||
const auto newY{ pos.Y + viewportHeight };
|
||||
pos = newY > mutableBottom ? til::point{ bufferSize.RightInclusive(), mutableBottom } : til::point{ pos.X, newY };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::_MoveByBuffer(SelectionDirection direction, COORD& pos)
|
||||
void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos)
|
||||
{
|
||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||
switch (direction)
|
||||
@@ -482,7 +529,7 @@ void Terminal::_MoveByBuffer(SelectionDirection direction, COORD& pos)
|
||||
void Terminal::ClearSelection()
|
||||
{
|
||||
_selection = std::nullopt;
|
||||
_quickEditMode = false;
|
||||
_markMode = false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -517,10 +564,10 @@ const TextBuffer::TextAndColor Terminal::RetrieveSelectedTextFromBuffer(bool sin
|
||||
// - viewportPos: a coordinate on the viewport
|
||||
// Return Value:
|
||||
// - the corresponding location on the buffer
|
||||
COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
|
||||
til::point Terminal::_ConvertToBufferCell(const til::point viewportPos) const
|
||||
{
|
||||
const auto yPos = base::ClampedNumeric<short>(_VisibleStartIndex()) + viewportPos.Y;
|
||||
COORD bufferPos = { viewportPos.X, yPos };
|
||||
const auto yPos = _VisibleStartIndex() + viewportPos.Y;
|
||||
til::point bufferPos = { viewportPos.X, yPos };
|
||||
_activeBuffer().GetSize().Clamp(bufferPos);
|
||||
return bufferPos;
|
||||
}
|
||||
@@ -532,7 +579,7 @@ COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
|
||||
// - coordSelectionStart - Not used
|
||||
// - coordSelectionEnd - Not used
|
||||
// - attr - Not used.
|
||||
void Terminal::ColorSelection(const COORD, const COORD, const TextAttribute)
|
||||
void Terminal::ColorSelection(const til::point, const til::point, const TextAttribute)
|
||||
{
|
||||
THROW_HR(E_NOTIMPL);
|
||||
}
|
||||
|
||||
@@ -14,13 +14,12 @@ Viewport Terminal::GetViewport() noexcept
|
||||
return _GetVisibleViewport();
|
||||
}
|
||||
|
||||
COORD Terminal::GetTextBufferEndPosition() const noexcept
|
||||
til::point Terminal::GetTextBufferEndPosition() const noexcept
|
||||
{
|
||||
// We use the end line of mutableViewport as the end
|
||||
// of the text buffer, it always moves with the written
|
||||
// text
|
||||
COORD endPosition{ _GetMutableViewport().Width() - 1, gsl::narrow<short>(ViewEndIndex()) };
|
||||
return endPosition;
|
||||
return { _GetMutableViewport().Width() - 1, ViewEndIndex() };
|
||||
}
|
||||
|
||||
const TextBuffer& Terminal::GetTextBuffer() const noexcept
|
||||
@@ -38,7 +37,7 @@ void Terminal::SetFontInfo(const FontInfo& fontInfo)
|
||||
_fontInfo = fontInfo;
|
||||
}
|
||||
|
||||
COORD Terminal::GetCursorPosition() const noexcept
|
||||
til::point Terminal::GetCursorPosition() const noexcept
|
||||
{
|
||||
const auto& cursor = _activeBuffer().GetCursor();
|
||||
return cursor.GetPosition();
|
||||
@@ -104,10 +103,10 @@ const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkCustomId(uin
|
||||
// - The location
|
||||
// Return value:
|
||||
// - The pattern IDs of the location
|
||||
const std::vector<size_t> Terminal::GetPatternId(const COORD location) const noexcept
|
||||
const std::vector<size_t> Terminal::GetPatternId(const til::point location) const noexcept
|
||||
{
|
||||
// Look through our interval tree for this location
|
||||
const auto intervals = _patternIntervalTree.findOverlapping(til::point{ location.X + 1, location.Y }, til::point{ location });
|
||||
const auto intervals = _patternIntervalTree.findOverlapping({ location.X + 1, location.Y }, location);
|
||||
if (intervals.size() == 0)
|
||||
{
|
||||
return {};
|
||||
@@ -147,7 +146,7 @@ catch (...)
|
||||
return {};
|
||||
}
|
||||
|
||||
void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
||||
void Terminal::SelectNewRegion(const til::point coordStart, const til::point coordEnd)
|
||||
{
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26496) // cpp core checks wants these const, but they're decremented below.
|
||||
@@ -178,8 +177,8 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
realCoordStart.Y -= gsl::narrow<short>(_VisibleStartIndex());
|
||||
realCoordEnd.Y -= gsl::narrow<short>(_VisibleStartIndex());
|
||||
realCoordStart.Y -= _VisibleStartIndex();
|
||||
realCoordEnd.Y -= _VisibleStartIndex();
|
||||
|
||||
SetSelectionAnchor(realCoordStart);
|
||||
SetSelectionEnd(realCoordEnd, SelectionExpansion::Char);
|
||||
|
||||
@@ -36,22 +36,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
static constexpr std::wstring_view SelectionBackgroundColorTag{ L"SelectionBackground" };
|
||||
|
||||
static const std::array<hstring, 16> TableColorNames = {
|
||||
RS_(L"ColorScheme_Black/Text"),
|
||||
RS_(L"ColorScheme_Red/Text"),
|
||||
RS_(L"ColorScheme_Green/Text"),
|
||||
RS_(L"ColorScheme_Yellow/Text"),
|
||||
RS_(L"ColorScheme_Blue/Text"),
|
||||
RS_(L"ColorScheme_Purple/Text"),
|
||||
RS_(L"ColorScheme_Cyan/Text"),
|
||||
RS_(L"ColorScheme_White/Text"),
|
||||
RS_(L"ColorScheme_BrightBlack/Text"),
|
||||
RS_(L"ColorScheme_BrightRed/Text"),
|
||||
RS_(L"ColorScheme_BrightGreen/Text"),
|
||||
RS_(L"ColorScheme_BrightYellow/Text"),
|
||||
RS_(L"ColorScheme_BrightBlue/Text"),
|
||||
RS_(L"ColorScheme_BrightPurple/Text"),
|
||||
RS_(L"ColorScheme_BrightCyan/Text"),
|
||||
RS_(L"ColorScheme_BrightWhite/Text")
|
||||
RS_(L"ColorScheme_Black/Header"),
|
||||
RS_(L"ColorScheme_Red/Header"),
|
||||
RS_(L"ColorScheme_Green/Header"),
|
||||
RS_(L"ColorScheme_Yellow/Header"),
|
||||
RS_(L"ColorScheme_Blue/Header"),
|
||||
RS_(L"ColorScheme_Purple/Header"),
|
||||
RS_(L"ColorScheme_Cyan/Header"),
|
||||
RS_(L"ColorScheme_White/Header"),
|
||||
RS_(L"ColorScheme_BrightBlack/Header"),
|
||||
RS_(L"ColorScheme_BrightRed/Header"),
|
||||
RS_(L"ColorScheme_BrightGreen/Header"),
|
||||
RS_(L"ColorScheme_BrightYellow/Header"),
|
||||
RS_(L"ColorScheme_BrightBlue/Header"),
|
||||
RS_(L"ColorScheme_BrightPurple/Header"),
|
||||
RS_(L"ColorScheme_BrightCyan/Header"),
|
||||
RS_(L"ColorScheme_BrightWhite/Header")
|
||||
};
|
||||
|
||||
static const std::array<std::wstring, 9> InBoxSchemes = {
|
||||
@@ -187,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (std::find(std::begin(InBoxSchemes), std::end(InBoxSchemes), schemeName) != std::end(InBoxSchemes))
|
||||
{
|
||||
// load disclaimer for in-box profiles
|
||||
disclaimer = RS_(L"ColorScheme_DeleteButtonDisclaimerInBox/Text");
|
||||
disclaimer = RS_(L"ColorScheme_DeleteButtonDisclaimerInBox");
|
||||
}
|
||||
DeleteButtonDisclaimer().Text(disclaimer);
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<!-- profile name -->
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="20" />
|
||||
<!-- author and version -->
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
@@ -109,20 +109,25 @@
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
Height="20"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Height="20"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Author}" />
|
||||
Text="{x:Bind Author}"
|
||||
Visibility="{x:Bind local:Converters.StringNotEmptyToVisibility(Author)}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Height="20"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Version}" />
|
||||
Text="{x:Bind Version}"
|
||||
Visibility="{x:Bind local:Converters.StringNotEmptyToVisibility(Version)}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
</Frame>
|
||||
<!-- Explicitly set the background color on grid to prevent the navigation animation from overflowing it -->
|
||||
<Grid Grid.Row="1"
|
||||
Height="80"
|
||||
Height="55"
|
||||
BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,1,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -196,14 +196,14 @@
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<Button x:Name="ResetButton"
|
||||
x:Uid="Settings_ResetSettingsButton"
|
||||
Click="ResetButton_Click" />
|
||||
<Button x:Name="SaveButton"
|
||||
x:Uid="Settings_SaveSettingsButton"
|
||||
Margin="10,0,0,0"
|
||||
Click="SaveButton_Click"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
<Button x:Name="ResetButton"
|
||||
x:Uid="Settings_ResetSettingsButton"
|
||||
Margin="10,0,0,0"
|
||||
Click="ResetButton_Click" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
<TerminalMUX>true</TerminalMUX>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
|
||||
@@ -354,5 +353,12 @@
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
using namespace ::winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace ::winrt::Windows::Foundation;
|
||||
|
||||
static constexpr std::wstring_view PreviewText{ L"Windows Terminal\r\nCopyright (c) Microsoft Corporation\r\n\nC:\\Windows\\Terminal> " };
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
PreviewConnection::PreviewConnection() noexcept
|
||||
PreviewConnection::PreviewConnection(const winrt::hstring previewString) noexcept :
|
||||
_previewString{ previewString }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -21,7 +20,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// First send a sequence to disable cursor blinking
|
||||
_TerminalOutputHandlers(L"\x1b[?12l");
|
||||
// Send the preview text
|
||||
_TerminalOutputHandlers(PreviewText);
|
||||
_TerminalOutputHandlers(_previewString);
|
||||
}
|
||||
|
||||
void PreviewConnection::Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) noexcept
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
class PreviewConnection : public winrt::implements<PreviewConnection, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection>
|
||||
{
|
||||
public:
|
||||
PreviewConnection() noexcept;
|
||||
PreviewConnection(const winrt::hstring previewString) noexcept;
|
||||
|
||||
void Initialize(const Windows::Foundation::Collections::ValueSet& settings) noexcept;
|
||||
void Start() noexcept;
|
||||
@@ -31,5 +31,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
WINRT_CALLBACK(TerminalOutput, winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputHandler);
|
||||
TYPED_EVENT(StateChanged, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection, IInspectable);
|
||||
|
||||
private:
|
||||
const winrt::hstring _previewString;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
static const winrt::hstring PreviewText{ L"Windows Terminal\r\nCopyright (c) Microsoft Corporation\r\n\nC:\\Windows\\Terminal> " };
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
Profiles_Appearance::Profiles_Appearance() :
|
||||
_previewControl{ Control::TermControl(Model::TerminalSettings{}, nullptr, make<PreviewConnection>()) }
|
||||
_previewControl{ Control::TermControl(Model::TerminalSettings{}, nullptr, make<PreviewConnection>(PreviewText)) }
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
@@ -139,43 +139,43 @@
|
||||
<value>Background</value>
|
||||
<comment>This is the header for a control that lets the user select the background color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Black.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Black.Header" xml:space="preserve">
|
||||
<value>Black</value>
|
||||
<comment>This is the header for a control that lets the user select the black color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Blue.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Blue.Header" xml:space="preserve">
|
||||
<value>Blue</value>
|
||||
<comment>This is the header for a control that lets the user select the blue color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightBlack.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightBlack.Header" xml:space="preserve">
|
||||
<value>Bright black</value>
|
||||
<comment>This is the header for a control that lets the user select the bright black color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightBlue.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightBlue.Header" xml:space="preserve">
|
||||
<value>Bright blue</value>
|
||||
<comment>This is the header for a control that lets the user select the bright blue color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightCyan.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightCyan.Header" xml:space="preserve">
|
||||
<value>Bright cyan</value>
|
||||
<comment>This is the header for a control that lets the user select the bright cyan color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightGreen.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightGreen.Header" xml:space="preserve">
|
||||
<value>Bright green</value>
|
||||
<comment>This is the header for a control that lets the user select the bright green color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightPurple.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightPurple.Header" xml:space="preserve">
|
||||
<value>Bright purple</value>
|
||||
<comment>This is the header for a control that lets the user select the bright purple color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightRed.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightRed.Header" xml:space="preserve">
|
||||
<value>Bright red</value>
|
||||
<comment>This is the header for a control that lets the user select the bright red color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightWhite.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightWhite.Header" xml:space="preserve">
|
||||
<value>Bright white</value>
|
||||
<comment>This is the header for a control that lets the user select the bright white color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_BrightYellow.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_BrightYellow.Header" xml:space="preserve">
|
||||
<value>Bright yellow</value>
|
||||
<comment>This is the header for a control that lets the user select the bright yellow color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
@@ -183,7 +183,7 @@
|
||||
<value>Cursor color</value>
|
||||
<comment>This is the header for a control that lets the user select the text cursor's color displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Cyan.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Cyan.Header" xml:space="preserve">
|
||||
<value>Cyan</value>
|
||||
<comment>This is the header for a control that lets the user select the cyan color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
@@ -191,11 +191,11 @@
|
||||
<value>Foreground</value>
|
||||
<comment>This is the header for a control that lets the user select the foreground color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Green.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Green.Header" xml:space="preserve">
|
||||
<value>Green</value>
|
||||
<comment>This is the header for a control that lets the user select the green color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Purple.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Purple.Header" xml:space="preserve">
|
||||
<value>Purple</value>
|
||||
<comment>This is the header for a control that lets the user select the purple color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
@@ -203,15 +203,15 @@
|
||||
<value>Selection background</value>
|
||||
<comment>This is the header for a control that lets the user select the background color for selected text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Red.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Red.Header" xml:space="preserve">
|
||||
<value>Red</value>
|
||||
<comment>This is the header for a control that lets the user select the red color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_White.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_White.Header" xml:space="preserve">
|
||||
<value>White</value>
|
||||
<comment>This is the header for a control that lets the user select the white color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_Yellow.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_Yellow.Header" xml:space="preserve">
|
||||
<value>Yellow</value>
|
||||
<comment>This is the header for a control that lets the user select the yellow color for text displayed on the screen.</comment>
|
||||
</data>
|
||||
@@ -1194,7 +1194,7 @@
|
||||
<value>Rename</value>
|
||||
<comment>Text label for a button that can be used to begin the renaming process.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_DeleteButtonDisclaimerInBox.Text" xml:space="preserve">
|
||||
<data name="ColorScheme_DeleteButtonDisclaimerInBox" xml:space="preserve">
|
||||
<value>This color scheme cannot be deleted or renamed because it is included by default.</value>
|
||||
<comment>Disclaimer presented next to the delete button when it is disabled.</comment>
|
||||
</data>
|
||||
|
||||
@@ -39,6 +39,10 @@ static constexpr std::string_view ScrollUpKey{ "scrollUp" };
|
||||
static constexpr std::string_view ScrollUpPageKey{ "scrollUpPage" };
|
||||
static constexpr std::string_view ScrollToTopKey{ "scrollToTop" };
|
||||
static constexpr std::string_view ScrollToBottomKey{ "scrollToBottom" };
|
||||
static constexpr std::string_view ScrollToMarkKey{ "scrollToMark" };
|
||||
static constexpr std::string_view AddMarkKey{ "addMark" };
|
||||
static constexpr std::string_view ClearMarkKey{ "clearMark" };
|
||||
static constexpr std::string_view ClearAllMarksKey{ "clearAllMarks" };
|
||||
static constexpr std::string_view SendInputKey{ "sendInput" };
|
||||
static constexpr std::string_view SetColorSchemeKey{ "setColorScheme" };
|
||||
static constexpr std::string_view SetTabColorKey{ "setTabColor" };
|
||||
@@ -76,6 +80,8 @@ static constexpr std::string_view QuitKey{ "quit" };
|
||||
static constexpr std::string_view AdjustOpacityKey{ "adjustOpacity" };
|
||||
static constexpr std::string_view RestoreLastClosedKey{ "restoreLastClosed" };
|
||||
static constexpr std::string_view SelectAllKey{ "selectAll" };
|
||||
static constexpr std::string_view MarkModeKey{ "markMode" };
|
||||
static constexpr std::string_view ToggleBlockSelectionKey{ "toggleBlockSelection" };
|
||||
|
||||
static constexpr std::string_view ActionKey{ "action" };
|
||||
|
||||
@@ -352,6 +358,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::ScrollUpPage, RS_(L"ScrollUpPageCommandKey") },
|
||||
{ ShortcutAction::ScrollToTop, RS_(L"ScrollToTopCommandKey") },
|
||||
{ ShortcutAction::ScrollToBottom, RS_(L"ScrollToBottomCommandKey") },
|
||||
{ ShortcutAction::ScrollToMark, RS_(L"ScrollToPreviousMarkCommandKey") },
|
||||
{ ShortcutAction::AddMark, RS_(L"AddMarkCommandKey") },
|
||||
{ ShortcutAction::ClearMark, RS_(L"ClearMarkCommandKey") },
|
||||
{ ShortcutAction::ClearAllMarks, RS_(L"ClearAllMarksCommandKey") },
|
||||
{ ShortcutAction::SendInput, L"" },
|
||||
{ ShortcutAction::SetColorScheme, L"" },
|
||||
{ ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") },
|
||||
@@ -388,6 +398,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::AdjustOpacity, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||
{ ShortcutAction::RestoreLastClosed, RS_(L"RestoreLastClosedCommandKey") },
|
||||
{ ShortcutAction::SelectAll, RS_(L"SelectAllCommandKey") },
|
||||
{ ShortcutAction::MarkMode, RS_(L"MarkModeCommandKey") },
|
||||
{ ShortcutAction::ToggleBlockSelection, RS_(L"ToggleBlockSelectionCommandKey") },
|
||||
};
|
||||
}();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user