mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-14 10:11:00 +00:00
Compare commits
59 Commits
cinnamon/o
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ca815287b | ||
|
|
24a69689c2 | ||
|
|
a512dddc08 | ||
|
|
c2bc927e50 | ||
|
|
689be38372 | ||
|
|
744631a293 | ||
|
|
89191f8211 | ||
|
|
fce00ff8f6 | ||
|
|
d1b26085e1 | ||
|
|
da26894434 | ||
|
|
5bfbebe3ac | ||
|
|
82534cf8e0 | ||
|
|
6cc7dfaf85 | ||
|
|
72ac061a8e | ||
|
|
2fcf5d7903 | ||
|
|
952f5b11ef | ||
|
|
489329bf41 | ||
|
|
3098fba203 | ||
|
|
1aa3909fea | ||
|
|
f4d6756b68 | ||
|
|
eecf76478b | ||
|
|
4ede37767a | ||
|
|
830c79be93 | ||
|
|
596597bca3 | ||
|
|
136db72b8a | ||
|
|
1607804dfc | ||
|
|
b2c521a372 | ||
|
|
7ca3e35b94 | ||
|
|
fe4f0f38cb | ||
|
|
bb5549a98d | ||
|
|
8a758f7f85 | ||
|
|
a0a70cc801 | ||
|
|
888b6e95b9 | ||
|
|
9f5967527c | ||
|
|
72bedcc159 | ||
|
|
d9c95ca31c | ||
|
|
74678ff2b0 | ||
|
|
67e205746c | ||
|
|
e3edf180a8 | ||
|
|
b78ceacd84 | ||
|
|
fd1afae214 | ||
|
|
ef5198e231 | ||
|
|
62d22c2a57 | ||
|
|
1279c63819 | ||
|
|
cf25fd0e7f | ||
|
|
afe5860ead | ||
|
|
c66f8feffb | ||
|
|
c529789bb3 | ||
|
|
57ca2ec8a4 | ||
|
|
2592cc41fe | ||
|
|
cf81d8c3c5 | ||
|
|
b49fa5ec59 | ||
|
|
ca0dc3d9fd | ||
|
|
825039ea17 | ||
|
|
21ab0a841d | ||
|
|
6ad0bb9232 | ||
|
|
a5b29b6abf | ||
|
|
a7a7d506d3 | ||
|
|
0e4ffd6f58 |
40
.github/linters/.markdown-lint.yml
vendored
40
.github/linters/.markdown-lint.yml
vendored
@@ -1,40 +0,0 @@
|
||||
---
|
||||
###########################
|
||||
###########################
|
||||
## Markdown Linter rules ##
|
||||
###########################
|
||||
###########################
|
||||
|
||||
# Linter rules doc:
|
||||
# - https://github.com/DavidAnson/markdownlint
|
||||
#
|
||||
# Note:
|
||||
# To comment out a single error:
|
||||
# <!-- markdownlint-disable -->
|
||||
# any violations you want
|
||||
# <!-- markdownlint-restore -->
|
||||
#
|
||||
# To run the linter locally:
|
||||
# 1. install the npm package:
|
||||
# `npm install -g markdownlint-cli`
|
||||
# 2. Then run it in the root of the repo with
|
||||
# `markdownlint -c .github\linters\.markdown-lint.yml ./*.md`
|
||||
|
||||
###############
|
||||
# Rules by id #
|
||||
###############
|
||||
MD004: false # Unordered list style
|
||||
MD007:
|
||||
indent: 2 # Unordered list indentation
|
||||
MD013:
|
||||
line_length: 400 # Line length 80 is far to short
|
||||
MD026:
|
||||
punctuation: ".,;:!。,;:" # List of not allowed
|
||||
MD029: false # Ordered list item prefix
|
||||
MD033: false # Allow inline HTML
|
||||
MD036: false # Emphasis used instead of a heading
|
||||
|
||||
#################
|
||||
# Rules by tags #
|
||||
#################
|
||||
blank_lines: false # Error on blank lines
|
||||
54
.github/workflows/linter.yml
vendored
54
.github/workflows/linter.yml
vendored
@@ -1,54 +0,0 @@
|
||||
---
|
||||
###########################
|
||||
###########################
|
||||
## Linter GitHub Actions ##
|
||||
###########################
|
||||
###########################
|
||||
name: Lint Code Base
|
||||
|
||||
#
|
||||
# Documentation:
|
||||
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
|
||||
#
|
||||
|
||||
#############################
|
||||
# Start the job on all push #
|
||||
#############################
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
###############
|
||||
# Set the Job #
|
||||
###############
|
||||
jobs:
|
||||
build:
|
||||
# Name the Job
|
||||
name: Lint Code Base
|
||||
# Set the agent to run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
##################
|
||||
# Load all steps #
|
||||
##################
|
||||
steps:
|
||||
##########################
|
||||
# Checkout the code base #
|
||||
##########################
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
||||
fetch-depth: 0
|
||||
|
||||
################################
|
||||
# Run Linter against code base #
|
||||
################################
|
||||
- name: Lint Code Base
|
||||
uses: github/super-linter@v3
|
||||
env:
|
||||
VALIDATE_ALL_CODEBASE: false
|
||||
DEFAULT_BRANCH: master
|
||||
MARKDOWN_CONFIG_FILE: .markdown-lint.yml
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VALIDATE_EDITORCONFIG: false
|
||||
@@ -140,13 +140,6 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and you
|
||||
1. Create & push a feature branch
|
||||
1. Create a [Draft Pull Request (PR)](https://github.blog/2019-02-14-introducing-draft-pull-requests/)
|
||||
1. Work on your changes
|
||||
1. Build and see if it works. Consult [How to build OpenConsole](./doc/building.md) if you have problems.
|
||||
|
||||
### Testing
|
||||
|
||||
Testing is a key component in the development workflow. Both Windows Terminal and Windows Console use TAEF(the Test Authoring and Execution Framework) as the main framework for testing.
|
||||
|
||||
If your changes affect existing test cases, or you're working on brand new features and also the accompanying test cases, see [TAEF](./doc/TAEF.md) for more information about how to validate your work locally.
|
||||
|
||||
### Code Review
|
||||
|
||||
|
||||
157
OpenConsole.sln
157
OpenConsole.sln
@@ -87,8 +87,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.Tests.Feature", "src\h
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{18D09A24-8240-42D6-8CB6-236EEE820263} = {18D09A24-8240-42D6-8CB6-236EEE820263}
|
||||
{FC802440-AD6A-4919-8F2C-7701F2B38D79} = {FC802440-AD6A-4919-8F2C-7701F2B38D79}
|
||||
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A} = {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}
|
||||
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
|
||||
{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A} = {58A03BB2-DF5A-4B66-91A0-7EF3BA01269A}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalParser.UnitTests", "src\terminal\parser\ut_parser\Parser.UnitTests.vcxproj", "{12144E07-FE63-4D33-9231-748B8D8C3792}"
|
||||
@@ -172,7 +172,6 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\cascadia\WindowsTerminal\WindowsTerminal.vcxproj", "{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
|
||||
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
|
||||
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
|
||||
@@ -181,8 +180,6 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\dll\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
|
||||
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
EndProjectSection
|
||||
@@ -228,22 +225,16 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalApp", "src\cascadia\ut_app\TerminalApp.UnitTests.vcxproj", "{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_TerminalApp", "src\cascadia\LocalTests_TerminalApp\TerminalApp.LocalTests.vcxproj", "{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererUia", "src\renderer\uia\lib\uia.vcxproj", "{48D21369-3D7B-4431-9967-24E81292CF63}"
|
||||
@@ -259,8 +250,6 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHostApp", "src\cascadia\LocalTests_TerminalApp\TestHostApp\TestHostApp.vcxproj", "{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42} = {CA5CAD1A-9B68-456A-B13E-C8218070DC42}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BDB237B6-1D1D-400F-84CC-40A58FA59C8E}"
|
||||
@@ -318,29 +307,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTerminalTestNetCore", "s
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wt", "src\cascadia\wt\wt.vcxproj", "{506FD703-BAA7-4F6E-9361-64F550EC8FCA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings.Editor", "src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj", "{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings.Model.Lib", "src\cascadia\TerminalSettingsModel\Microsoft.Terminal.Settings.ModelLib.vcxproj", "{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings.Model", "src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj", "{CA5CAD1A-082C-4476-9F33-94B339494076}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_SettingsModel", "src\cascadia\LocalTests_SettingsModel\SettingsModel.LocalTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
|
||||
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
AuditMode|Any CPU = AuditMode|Any CPU
|
||||
@@ -2020,123 +1986,6 @@ Global
|
||||
{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x64.Build.0 = Release|x64
|
||||
{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.Build.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|ARM64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|ARM64.Build.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|ARM64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x64Test.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x64Test.Build.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x64Test.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x86Test.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x86Test.Build.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x86Test.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x86.Deploy.0 = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x86.Deploy.0 = Debug|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x86.Deploy.0 = Release|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -2217,10 +2066,6 @@ Global
|
||||
{6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {81C352DB-1818-45B7-A284-18E259F1CC87}
|
||||
{1588FD7C-241E-4E7D-9113-43735F3E6BAD} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{506FD703-BAA7-4F6E-9361-64F550EC8FCA} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-082C-4476-9F33-94B339494076} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-9B68-456A-B13E-C8218070DC42} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
||||
|
||||
222
README.md
222
README.md
@@ -7,25 +7,21 @@ This repository contains the source code for:
|
||||
* The Windows console host (`conhost.exe`)
|
||||
* Components shared between the two projects
|
||||
* [ColorTool](https://github.com/Microsoft/Terminal/tree/master/src/tools/ColorTool)
|
||||
* [Sample projects](https://github.com/Microsoft/Terminal/tree/master/samples)
|
||||
that show how to consume the Windows Console APIs
|
||||
* [Sample projects](https://github.com/Microsoft/Terminal/tree/master/samples) that show how to consume the Windows Console APIs
|
||||
|
||||
Related repositories include:
|
||||
|
||||
* [Windows Terminal Documentation](https://docs.microsoft.com/windows/terminal)
|
||||
([Repo: Contribute to the docs](https://github.com/MicrosoftDocs/terminal))
|
||||
* [Windows Terminal Documentation](https://docs.microsoft.com/windows/terminal) ([Repo: Contribute to the docs](https://github.com/MicrosoftDocs/terminal))
|
||||
* [Console API Documentation](https://github.com/MicrosoftDocs/Console-Docs)
|
||||
* [Cascadia Code Font](https://github.com/Microsoft/Cascadia-Code)
|
||||
|
||||
## Installing and running Windows Terminal
|
||||
|
||||
> 🔴 Note: Windows Terminal requires Windows 10 1903 (build 18362) or later
|
||||
> 👉 Note: Windows Terminal requires Windows 10 1903 (build 18362) or later
|
||||
|
||||
### Microsoft Store [Recommended]
|
||||
|
||||
Install the [Windows Terminal from the Microsoft Store][store-install-link].
|
||||
This allows you to always be on the latest version when we release new builds
|
||||
with automatic upgrades.
|
||||
Install the [Windows Terminal from the Microsoft Store][store-install-link]. This allows you to always be on the latest version when we release new builds with automatic upgrades.
|
||||
|
||||
This is our preferred method.
|
||||
|
||||
@@ -33,21 +29,16 @@ This is our preferred method.
|
||||
|
||||
#### Via GitHub
|
||||
|
||||
For users who are unable to install Terminal from the Microsoft Store, Terminal
|
||||
builds can be manually downloaded from this repository's [Releases
|
||||
page](https://github.com/microsoft/terminal/releases).
|
||||
For users who are unable to install Terminal from the Microsoft Store, Terminal builds can be manually downloaded from this repository's [Releases page](https://github.com/microsoft/terminal/releases).
|
||||
|
||||
> 🔴 Note: If you install Terminal manually:
|
||||
> ⚠ Note: If you install Terminal manually:
|
||||
>
|
||||
> * Terminal will not auto-update when new builds are released so you will need
|
||||
> to regularly install the latest Terminal release to receive all the latest
|
||||
> fixes and improvements!
|
||||
> * Be sure to install the [Desktop Bridge VC++ v14 Redistributable Package](https://www.microsoft.com/en-us/download/details.aspx?id=53175) otherwise Terminal may not install and/or run and may crash at startup
|
||||
> * Terminal will not auto-update when new builds are released so you will need to regularly install the latest Terminal release to receive all the latest fixes and improvements!
|
||||
|
||||
#### Via Windows Package Manager CLI (aka winget)
|
||||
|
||||
[winget](https://github.com/microsoft/winget-cli) users can download and install
|
||||
the latest Terminal release by installing the `Microsoft.WindowsTerminal`
|
||||
package:
|
||||
[winget](https://github.com/microsoft/winget-cli) users can download and install the latest Terminal release by installing the `Microsoft.WindowsTerminal` package:
|
||||
|
||||
```powershell
|
||||
winget install --id=Microsoft.WindowsTerminal -e
|
||||
@@ -55,8 +46,7 @@ winget install --id=Microsoft.WindowsTerminal -e
|
||||
|
||||
#### Via Chocolatey (unofficial)
|
||||
|
||||
[Chocolatey](https://chocolatey.org) users can download and install the latest
|
||||
Terminal release by installing the `microsoft-windows-terminal` package:
|
||||
[Chocolatey](https://chocolatey.org) users can download and install the latest Terminal release by installing the `microsoft-windows-terminal` package:
|
||||
|
||||
```powershell
|
||||
choco install microsoft-windows-terminal
|
||||
@@ -68,18 +58,13 @@ To upgrade Windows Terminal using Chocolatey, run the following:
|
||||
choco upgrade microsoft-windows-terminal
|
||||
```
|
||||
|
||||
If you have any issues when installing/upgrading the package please go to the
|
||||
[Windows Terminal package
|
||||
page](https://chocolatey.org/packages/microsoft-windows-terminal) and follow the
|
||||
[Chocolatey triage process](https://chocolatey.org/docs/package-triage-process)
|
||||
If you have any issues when installing/upgrading the package please go to the [Windows Terminal package page](https://chocolatey.org/packages/microsoft-windows-terminal) and follow the [Chocolatey triage process](https://chocolatey.org/docs/package-triage-process)
|
||||
|
||||
#### Via Scoop (unofficial)
|
||||
|
||||
[Scoop](https://scoop.sh) users can download and install the latest Terminal
|
||||
release by installing the `windows-terminal` package:
|
||||
[Scoop](https://scoop.sh) users can download and install the latest Terminal release by installing the `windows-terminal` package:
|
||||
|
||||
```powershell
|
||||
scoop bucket add extras
|
||||
scoop install windows-terminal
|
||||
```
|
||||
|
||||
@@ -89,123 +74,70 @@ To update Windows Terminal using Scoop, run the following:
|
||||
scoop update windows-terminal
|
||||
```
|
||||
|
||||
If you have any issues when installing/updating the package, please search for
|
||||
or report the same on the [issues
|
||||
page](https://github.com/lukesampson/scoop-extras/issues) of Scoop Extras bucket
|
||||
repository.
|
||||
If you have any issues when installing/updating the package, please search for or report the same on the [issues page](https://github.com/lukesampson/scoop-extras/issues) of Scoop Extras bucket repository.
|
||||
|
||||
---
|
||||
|
||||
## Windows Terminal 2.0 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 delivering Windows Terminal 2.0 [is described here](/doc/terminal-v2-roadmap.md) and will be updated as the project proceeds.
|
||||
|
||||
## Project Build Status
|
||||
|
||||
Project|Build Status
|
||||
---|---
|
||||
Terminal|[](https://dev.azure.com/ms/Terminal/_build?definitionId=136)
|
||||
ColorTool|
|
||||
Terminal|[](https://dev.azure.com/ms/Terminal/_build?definitionId=136)
|
||||
ColorTool|
|
||||
|
||||
---
|
||||
|
||||
## Terminal & Console Overview
|
||||
|
||||
Please take a few minutes to review the overview below before diving into the
|
||||
code:
|
||||
Please take a few minutes to review the overview below before diving into the code:
|
||||
|
||||
### Windows Terminal
|
||||
|
||||
Windows Terminal is a new, modern, feature-rich, productive terminal application
|
||||
for command-line users. It includes many of the features most frequently
|
||||
requested by the Windows command-line community including support for tabs, rich
|
||||
text, globalization, configurability, theming & styling, and more.
|
||||
Windows Terminal is a new, modern, feature-rich, productive terminal application for command-line users. It includes many of the features most frequently requested by the Windows command-line community including support for tabs, rich text, globalization, configurability, theming & styling, and more.
|
||||
|
||||
The Terminal will also need to meet our goals and measures to ensure it remains
|
||||
fast and efficient, and doesn't consume vast amounts of memory or power.
|
||||
The Terminal will also need to meet our goals and measures to ensure it remains fast and efficient, and doesn't consume vast amounts of memory or power.
|
||||
|
||||
### The Windows Console Host
|
||||
|
||||
The Windows Console host, `conhost.exe`, is Windows' original command-line user
|
||||
experience. It also hosts Windows' command-line infrastructure and the Windows
|
||||
Console API server, input engine, rendering engine, user preferences, etc. The
|
||||
console host code in this repository is the actual source from which the
|
||||
`conhost.exe` in Windows itself is built.
|
||||
The Windows Console host, `conhost.exe`, is Windows' original command-line user experience. It also hosts Windows' command-line infrastructure and the Windows Console API server, input engine, rendering engine, user preferences, etc. The console host code in this repository is the actual source from which the `conhost.exe` in Windows itself is built.
|
||||
|
||||
Since taking ownership of the Windows command-line in 2014, the team added
|
||||
several new features to the Console, including background transparency,
|
||||
line-based selection, support for [ANSI / Virtual Terminal
|
||||
sequences](https://en.wikipedia.org/wiki/ANSI_escape_code), [24-bit
|
||||
color](https://devblogs.microsoft.com/commandline/24-bit-color-in-the-windows-console/),
|
||||
a [Pseudoconsole
|
||||
("ConPTY")](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/),
|
||||
and more.
|
||||
Since taking ownership of the Windows command-line in 2014, the team added several new features to the Console, including background transparency, line-based selection, support for [ANSI / Virtual Terminal sequences](https://en.wikipedia.org/wiki/ANSI_escape_code), [24-bit color](https://devblogs.microsoft.com/commandline/24-bit-color-in-the-windows-console/), a [Pseudoconsole ("ConPTY")](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/), and more.
|
||||
|
||||
However, because Windows Console's primary goal is to maintain backward
|
||||
compatibility, we have been unable to add many of the features the community
|
||||
(and the team) have been wanting for the last several years including tabs,
|
||||
unicode text, and emoji.
|
||||
However, because Windows Console's primary goal is to maintain backward compatibility, we have been unable to add many of the features the community (and the team) have been wanting for the last several years including tabs, unicode text, and emoji.
|
||||
|
||||
These limitations led us to create the new Windows Terminal.
|
||||
|
||||
> You can read more about the evolution of the command-line in general, and the
|
||||
> Windows command-line specifically in [this accompanying series of blog
|
||||
> posts](https://devblogs.microsoft.com/commandline/windows-command-line-backgrounder/)
|
||||
> on the Command-Line team's blog.
|
||||
> You can read more about the evolution of the command-line in general, and the Windows command-line specifically in [this accompanying series of blog posts](https://devblogs.microsoft.com/commandline/windows-command-line-backgrounder/) on the Command-Line team's blog.
|
||||
|
||||
### Shared Components
|
||||
|
||||
While overhauling Windows Console, we modernized its codebase considerably,
|
||||
cleanly separating logical entities into modules and classes, introduced some
|
||||
key extensibility points, replaced several old, home-grown collections and
|
||||
containers with safer, more efficient [STL
|
||||
containers](https://docs.microsoft.com/en-us/cpp/standard-library/stl-containers?view=vs-2019),
|
||||
and made the code simpler and safer by using Microsoft's [Windows Implementation
|
||||
Libraries - WIL](https://github.com/Microsoft/wil).
|
||||
While overhauling Windows Console, we modernized its codebase considerably, cleanly separating logical entities into modules and classes, introduced some key extensibility points, replaced several old, home-grown collections and containers with safer, more efficient [STL containers](https://docs.microsoft.com/en-us/cpp/standard-library/stl-containers?view=vs-2019), and made the code simpler and safer by using Microsoft's [Windows Implementation Libraries - WIL](https://github.com/Microsoft/wil).
|
||||
|
||||
This overhaul resulted in several of Console's key components being available
|
||||
for re-use in any terminal implementation on Windows. These components include a
|
||||
new DirectWrite-based text layout and rendering engine, a text buffer capable of
|
||||
storing both UTF-16 and UTF-8, a VT parser/emitter, and more.
|
||||
This overhaul resulted in several of Console's key components being available for re-use in any terminal implementation on Windows. These components include a new DirectWrite-based text layout and rendering engine, a text buffer capable of storing both UTF-16 and UTF-8, a VT parser/emitter, and more.
|
||||
|
||||
### Creating the new Windows Terminal
|
||||
|
||||
When we started planning the new Windows Terminal application, we explored and
|
||||
evaluated several approaches and technology stacks. We ultimately decided that
|
||||
our goals would be best met by continuing our investment in our C++ codebase,
|
||||
which would allow us to reuse several of the aforementioned modernized
|
||||
components in both the existing Console and the new Terminal. Further, we
|
||||
realized that this would allow us to build much of the Terminal's core itself as
|
||||
a reusable UI control that others can incorporate into their own applications.
|
||||
When we started planning the new Windows Terminal application, we explored and evaluated several approaches and technology stacks. We ultimately decided that our goals would be best met by continuing our investment in our C++ codebase, which would allow us to reuse several of the aforementioned modernized components in both the existing Console and the new Terminal. Further, we realized that this would allow us to build much of the Terminal's core itself as a reusable UI control that others can incorporate into their own applications.
|
||||
|
||||
The result of this work is contained within this repo and delivered as the
|
||||
Windows Terminal application you can download from the Microsoft Store, or
|
||||
[directly from this repo's
|
||||
releases](https://github.com/microsoft/terminal/releases).
|
||||
The result of this work is contained within this repo and delivered as the Windows Terminal application you can download from the Microsoft Store, or [directly from this repo's releases](https://github.com/microsoft/terminal/releases).
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
For more information about Windows Terminal, you may find some of these
|
||||
resources useful and interesting:
|
||||
For more information about Windows Terminal, you may find some of these resources useful and interesting:
|
||||
|
||||
* [Command-Line Blog](https://devblogs.microsoft.com/commandline)
|
||||
* [Command-Line Backgrounder Blog
|
||||
Series](https://devblogs.microsoft.com/commandline/windows-command-line-backgrounder/)
|
||||
* Windows Terminal Launch: [Terminal "Sizzle
|
||||
Video"](https://www.youtube.com/watch?v=8gw0rXPMMPE&list=PLEHMQNlPj-Jzh9DkNpqipDGCZZuOwrQwR&index=2&t=0s)
|
||||
* Windows Terminal Launch: [Build 2019
|
||||
Session](https://www.youtube.com/watch?v=KMudkRcwjCw)
|
||||
* Run As Radio: [Show 645 - Windows Terminal with Richard
|
||||
Turner](http://www.runasradio.com/Shows/Show/645)
|
||||
* Azure Devops Podcast: [Episode 54 - Kayla Cinnamon and Rich Turner on DevOps
|
||||
on the Windows
|
||||
Terminal](http://azuredevopspodcast.clear-measure.com/kayla-cinnamon-and-rich-turner-on-devops-on-the-windows-terminal-team-episode-54)
|
||||
* Microsoft Ignite 2019 Session: [The Modern Windows Command Line: Windows
|
||||
Terminal -
|
||||
BRK3321](https://myignite.techcommunity.microsoft.com/sessions/81329?source=sessions)
|
||||
* [Command-Line Backgrounder Blog Series](https://devblogs.microsoft.com/commandline/windows-command-line-backgrounder/)
|
||||
* Windows Terminal Launch: [Terminal "Sizzle Video"](https://www.youtube.com/watch?v=8gw0rXPMMPE&list=PLEHMQNlPj-Jzh9DkNpqipDGCZZuOwrQwR&index=2&t=0s)
|
||||
* Windows Terminal Launch: [Build 2019 Session](https://www.youtube.com/watch?v=KMudkRcwjCw)
|
||||
* Run As Radio: [Show 645 - Windows Terminal with Richard Turner](http://www.runasradio.com/Shows/Show/645)
|
||||
* Azure Devops Podcast: [Episode 54 - Kayla Cinnamon and Rich Turner on DevOps on the Windows Terminal](http://azuredevopspodcast.clear-measure.com/kayla-cinnamon-and-rich-turner-on-devops-on-the-windows-terminal-team-episode-54)
|
||||
* Microsoft Ignite 2019 Session: [The Modern Windows Command Line: Windows Terminal - BRK3321](https://myignite.techcommunity.microsoft.com/sessions/81329?source=sessions)
|
||||
|
||||
---
|
||||
|
||||
@@ -215,50 +147,35 @@ resources useful and interesting:
|
||||
|
||||
Cause: You're launching the incorrect solution in Visual Studio.
|
||||
|
||||
Solution: Make sure you're building & deploying the `CascadiaPackage` project in
|
||||
Visual Studio.
|
||||
Solution: Make sure you're building & deploying the `CascadiaPackage` project in Visual Studio.
|
||||
|
||||
> ⚠ Note: `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
|
||||
> Windows Console that hosts Windows' command-line infrastructure. OpenConsole
|
||||
> is used by Windows Terminal to connect to and communicate with command-line
|
||||
> applications (via
|
||||
> [ConPty](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/)).
|
||||
> ⚠ Note: `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic Windows Console that hosts Windows' command-line infrastructure. OpenConsole is used by Windows Terminal to connect to and communicate with command-line applications (via [ConPty](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/)).
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
All project documentation is located at aka.ms/terminal-docs. If you would like
|
||||
to contribute to the documentation, please submit a pull request on the [Windows
|
||||
Terminal Documentation repo](https://github.com/MicrosoftDocs/terminal).
|
||||
All project documentation is located at aka.ms/terminal-docs. If you would like to contribute to the documentation, please submit a pull request on the [Windows Terminal Documentation repo](https://github.com/MicrosoftDocs/terminal).
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
We are excited to work alongside you, our amazing community, to build and
|
||||
enhance Windows Terminal\!
|
||||
We are excited to work alongside you, our amazing community, to build and enhance Windows Terminal\!
|
||||
|
||||
***BEFORE you start work on a feature/fix***, please read & follow our
|
||||
[Contributor's
|
||||
Guide](https://github.com/microsoft/terminal/blob/master/CONTRIBUTING.md) to
|
||||
help avoid any wasted or duplicate effort.
|
||||
***BEFORE you start work on a feature/fix***, please read & follow our [Contributor's Guide](https://github.com/microsoft/terminal/blob/master/CONTRIBUTING.md) to help avoid any wasted or duplicate effort.
|
||||
|
||||
## Communicating with the Team
|
||||
|
||||
The easiest way to communicate with the team is via GitHub issues.
|
||||
|
||||
Please file new issues, feature requests and suggestions, but **DO search for
|
||||
similar open/closed pre-existing issues before creating a new issue.**
|
||||
Please file new issues, feature requests and suggestions, but **DO search for similar open/closed pre-existing issues before creating a new issue.**
|
||||
|
||||
If you would like to ask a question that you feel doesn't warrant an issue
|
||||
(yet), please reach out to us via Twitter:
|
||||
If you would like to ask a question that you feel doesn't warrant an issue (yet), please reach out to us via Twitter:
|
||||
|
||||
* Kayla Cinnamon, Program Manager:
|
||||
[@cinnamon\_msft](https://twitter.com/cinnamon_msft)
|
||||
* Kayla Cinnamon, Program Manager: [@cinnamon\_msft](https://twitter.com/cinnamon_msft)
|
||||
* Dustin Howett, Engineering Lead: [@dhowett](https://twitter.com/DHowett)
|
||||
* Michael Niksa, Senior Developer:
|
||||
[@michaelniksa](https://twitter.com/MichaelNiksa)
|
||||
* Michael Niksa, Senior Developer: [@michaelniksa](https://twitter.com/MichaelNiksa)
|
||||
* Mike Griese, Developer: [@zadjii](https://twitter.com/zadjii)
|
||||
* Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft)
|
||||
* Leon Liang, Developer: [@leonmsft](https://twitter.com/leonmsft)
|
||||
@@ -268,19 +185,11 @@ If you would like to ask a question that you feel doesn't warrant an issue
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* You must be running Windows 1903 (build >= 10.0.18362.0) or later to run
|
||||
Windows Terminal
|
||||
* You must [enable Developer Mode in the Windows Settings
|
||||
app](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development)
|
||||
to locally install and run Windows Terminal
|
||||
* You must have the [Windows 10 1903
|
||||
SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
installed
|
||||
* You must have at least [VS
|
||||
2019](https://visualstudio.microsoft.com/downloads/) installed
|
||||
* You must install the following Workloads via the VS Installer. Note: Opening
|
||||
the solution in VS 2019 will [prompt you to install missing components
|
||||
automatically](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/):
|
||||
* You must be running Windows 1903 (build >= 10.0.18362.0) or later to run Windows Terminal
|
||||
* You must [enable Developer Mode in the Windows Settings app](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) to locally install and run Windows Terminal
|
||||
* You must have the [Windows 10 1903 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) installed
|
||||
* You must have at least [VS 2019](https://visualstudio.microsoft.com/downloads/) installed
|
||||
* You must install the following Workloads via the VS Installer. Note: Opening the solution in VS 2019 will [prompt you to install missing components automatically](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/):
|
||||
* Desktop Development with C++
|
||||
* Universal Windows Platform Development
|
||||
* **The following Individual Components**
|
||||
@@ -288,17 +197,13 @@ If you would like to ask a question that you feel doesn't warrant an issue
|
||||
|
||||
## Building the Code
|
||||
|
||||
This repository uses [git
|
||||
submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) for some of its
|
||||
dependencies. To make sure submodules are restored or updated, be sure to run
|
||||
the following prior to building:
|
||||
This repository uses [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) for some of its dependencies. To make sure submodules are restored or updated, be sure to run the following prior to building:
|
||||
|
||||
```shell
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
OpenConsole.sln may be built from within Visual Studio or from the command-line
|
||||
using a set of convenience scripts & tools in the **/tools** directory:
|
||||
OpenConsole.sln may be built from within Visual Studio or from the command-line using a set of convenience scripts & tools in the **/tools** directory:
|
||||
|
||||
### Building in PowerShell
|
||||
|
||||
@@ -317,28 +222,19 @@ bcz
|
||||
|
||||
## Running & Debugging
|
||||
|
||||
To debug the Windows Terminal in VS, right click on `CascadiaPackage` (in the
|
||||
Solution Explorer) and go to properties. In the Debug menu, change "Application
|
||||
process" and "Background task process" to "Native Only".
|
||||
To debug the Windows Terminal in VS, right click on `CascadiaPackage` (in the Solution Explorer) and go to properties. In the Debug menu, change "Application process" and "Background task process" to "Native Only".
|
||||
|
||||
You should then be able to build & debug the Terminal project by hitting
|
||||
<kbd>F5</kbd>.
|
||||
You should then be able to build & debug the Terminal project by hitting <kbd>F5</kbd>.
|
||||
|
||||
> 👉 You will _not_ be able to launch the Terminal directly by running the
|
||||
> WindowsTerminal.exe. For more details on why, see
|
||||
> [#926](https://github.com/microsoft/terminal/issues/926),
|
||||
> [#4043](https://github.com/microsoft/terminal/issues/4043)
|
||||
> 👉 You will _not_ be able to launch the Terminal directly by running the WindowsTerminal.exe. For more details on why, see [#926](https://github.com/microsoft/terminal/issues/926), [#4043](https://github.com/microsoft/terminal/issues/4043)
|
||||
|
||||
### Coding Guidance
|
||||
|
||||
Please review these brief docs below about our coding practices.
|
||||
|
||||
> 👉 If you find something missing from these docs, feel free to contribute to
|
||||
> any of our documentation files anywhere in the repository (or write some new
|
||||
> ones!)
|
||||
> 👉 If you find something missing from these docs, feel free to contribute to any of our documentation files anywhere in the repository (or write some new ones!)
|
||||
|
||||
This is a work in progress as we learn what we'll need to provide people in
|
||||
order to be effective contributors to our project.
|
||||
This is a work in progress as we learn what we'll need to provide people in order to be effective contributors to our project.
|
||||
|
||||
* [Coding Style](https://github.com/Microsoft/Terminal/blob/master/doc/STYLE.md)
|
||||
* [Code Organization](https://github.com/Microsoft/Terminal/blob/master/doc/ORGANIZATION.md)
|
||||
@@ -347,12 +243,10 @@ order to be effective contributors to our project.
|
||||
|
||||
---
|
||||
|
||||
## Code of Conduct
|
||||
# Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of
|
||||
Conduct][conduct-code]. For more information see the [Code of Conduct
|
||||
FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any
|
||||
additional questions or comments.
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code].
|
||||
For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments.
|
||||
|
||||
[conduct-code]: https://opensource.microsoft.com/codeofconduct/
|
||||
[conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
|
||||
|
||||
17
SUPPORT.md
17
SUPPORT.md
@@ -1,17 +0,0 @@
|
||||
# Support
|
||||
|
||||
## How to file issues and get help
|
||||
|
||||
This project uses [GitHub issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new topics, file your bug or feature request as a new issue.
|
||||
|
||||
For help and questions about using this project, please look at the [docs site for Windows Terminal][docs] and our [Contributor's Guide][contributor] if you want to work on Windows Terminal.
|
||||
|
||||
## Microsoft Support Policy
|
||||
|
||||
Support for Windows Terminal is limited to the resources listed above.
|
||||
|
||||
[gh-issue]: https://github.com/microsoft/terminal/issues/new/choose
|
||||
[gh-bug]: https://github.com/microsoft/terminal/issues/new?assignees=&labels=Issue-Bug&template=bug_report.md&title=
|
||||
[gh-feature]: https://github.com/microsoft/terminal/issues/new?assignees=&labels=Issue-Feature&template=Feature_Request.md&title=
|
||||
[docs]: https://docs.microsoft.com/windows/terminal
|
||||
[contributor]: https://github.com/microsoft/terminal/blob/master/CONTRIBUTING.md
|
||||
@@ -41,8 +41,6 @@ steps:
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: "${{ parameters.additionalBuildArguments }}"
|
||||
clean: true
|
||||
# The build agents cannot currently support parallel build due to the
|
||||
# memory requirements of our PCH files.
|
||||
maximumCpuCount: false
|
||||
|
||||
- task: PowerShell@2
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Preview'">WT_BRANDING_PREVIEW</_WTBrandingPreprocessorToken>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Release'">WT_BRANDING_RELEASE</_WTBrandingPreprocessorToken>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(_WTBrandingPreprocessorToken)'==''">WT_BRANDING_DEV</_WTBrandingPreprocessorToken>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>$(_WTBrandingPreprocessorToken);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>$(_WTBrandingPreprocessorToken);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -106,10 +106,6 @@ Try {
|
||||
Throw "Failed to find wt.exe/wtd.exe -- check the WAP packaging project"
|
||||
}
|
||||
|
||||
If ($null -eq (Get-Item "$AppxPackageRootPath\OpenConsole.exe" -EA:Ignore)) {
|
||||
Throw "Failed to find OpenConsole.exe -- check the WAP packaging project"
|
||||
}
|
||||
|
||||
} Finally {
|
||||
Remove-Item -Recurse -Force $AppxPackageRootPath
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2020</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>5</VersionMinor>
|
||||
<VersionMinor>4</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
38
doc/TAEF.md
38
doc/TAEF.md
@@ -1,30 +1,9 @@
|
||||
### TAEF Overview ###
|
||||
|
||||
### TAEF ###
|
||||
TAEF, the Test Authoring and Execution Framework, is used extensively within the Windows organization to test the operating system code in a unified manner for system, driver, and application code. As the console is a Windows OS Component, we strive to continue using the same system such that tests can be ran in a unified manner both externally to Microsoft as well as inside the official OS Build/Test system.
|
||||
|
||||
The [official documentation](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/) for TAEF describes the basic architecture, usage, and functionality of the test system. It is similar to Visual Studio test, but a bit more comprehensive and flexible.
|
||||
The [official documentation](https://msdn.microsoft.com/en-us/library/windows/hardware/hh439725\(v=vs.85\).aspx) for TAEF describes the basic architecture, usage, and functionality of the test system. It is similar to Visual Studio test, but a bit more comprehensive and flexible.
|
||||
|
||||
### Writing Tests
|
||||
|
||||
You may want to read the section [Authoring Tests in C++](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/authoring-tests-in-c--) before getting your hands dirty. Note that the quoted header name in `#include "WexTestClass.h"` might be a bit confusing. You are not required to copy TAEF headers into the project folder.
|
||||
|
||||
Use the [TAEF Verify Macros for C++](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/verify) in your test code to perform verifications.
|
||||
|
||||
### Running Tests
|
||||
|
||||
If you have Visual Studio and related C++ components installed, and you have successfully restored NuGets, you should have the TAEF test runner `te.exe` available locally as part of the `Taef.Redist.Wlk` package.
|
||||
|
||||
> Note that you cannot easily run TAEF tests directly through Visual Studio. The `Taef.Redist.Wlk` NuGet package comes with an adapter that will let you browse and execute TAEF tests inside of Visual Studio, but its performance and reliability prevent us from recommending it here.
|
||||
|
||||
In a "normal" CMD environment, `te.exe` may not be directly available. Try the following command to set up the development enviroment first:
|
||||
|
||||
```shell
|
||||
.\tools\razzle.cmd
|
||||
```
|
||||
|
||||
Then you should be able to use `%TAEF%` as an alias of the actual `te.exe`.
|
||||
|
||||
For the purposes of the OpenConsole project, you can run the tests using the `te.exe` that matches the architecture for which the test was built (x86/x64):
|
||||
For the purposes of the console project, you can run the tests using the *TE.exe* that matches the architecture for which the test was build (x86/x64) in the pattern
|
||||
|
||||
te.exe Console.Unit.Tests.dll
|
||||
|
||||
@@ -36,15 +15,6 @@ Limiting the tests to be run is also useful with:
|
||||
|
||||
Any pattern of class/method names can be specified after the */name:* flag with wildcard patterns.
|
||||
|
||||
For any further details on the functionality of the TAEF test runner, please see the [Executing Tests](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/executing-tests) section in the official documentation. Or run the embedded help with
|
||||
For any further details on the functionality of the TAEF test runner, *TE.exe*, please see the documentation above or run the embedded help with
|
||||
|
||||
te.exe /!
|
||||
|
||||
If you use PowerShell, try the following command:
|
||||
|
||||
```powershell
|
||||
Import-Module .\tools\OpenConsole.psm1
|
||||
Invoke-OpenConsoleTests
|
||||
```
|
||||
|
||||
`Invoke-OpenConsoleTests` supports a number of options, which you can enumerate by running `Invoke-OpenConsoleTests -?`.
|
||||
|
||||
@@ -26,25 +26,11 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"BellStyle": {
|
||||
"enum": [
|
||||
"none",
|
||||
"audible"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ProfileGuid": {
|
||||
"default": "{}",
|
||||
"pattern": "^\\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\}$",
|
||||
"type": "string"
|
||||
},
|
||||
"Icon": {
|
||||
"description": "Image file location or an emoji to be used as an icon. Displays within the tab, the dropdown menu, and jumplist.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"ShortcutActionName": {
|
||||
"enum": [
|
||||
"adjustFontSize",
|
||||
@@ -479,14 +465,6 @@
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"icon": { "$ref": "#/definitions/Icon" },
|
||||
"name": {
|
||||
"description": "The name that will appear in the command palette. If one isn't provided, the terminal will attempt to automatically generate a name.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -519,11 +497,6 @@
|
||||
"description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied.",
|
||||
"$ref": "#/definitions/CopyFormat"
|
||||
},
|
||||
"disableAnimations": {
|
||||
"default": false,
|
||||
"description": "When set to `true`, visual animations will be disabled across the application.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"largePasteWarning": {
|
||||
"default": true,
|
||||
"description": "When set to true, trying to paste text with more than 5 KiB of characters will display a warning asking you whether to continue or not with the paste.",
|
||||
@@ -555,18 +528,18 @@
|
||||
},
|
||||
"initialCols": {
|
||||
"default": 120,
|
||||
"description": "The number of columns displayed in the window upon first load. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), this property is ignored.",
|
||||
"description": "The number of columns displayed in the window upon first load.",
|
||||
"maximum": 999,
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"initialPosition": {
|
||||
"$ref": "#/definitions/Coordinates",
|
||||
"description": "The position of the top left corner of the window upon first load. On a system with multiple displays, these coordinates are relative to the top left of the primary display. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), the window will be maximized on the monitor specified by those coordinates."
|
||||
"description": "The position of the top left corner of the window upon first load. On a system with multiple displays, these coordinates are relative to the top left of the primary display. If \"launchMode\" is set to maximized, the window will be maximized on the monitor specified by those coordinates."
|
||||
},
|
||||
"initialRows": {
|
||||
"default": 30,
|
||||
"description": "The number of rows displayed in the window upon first load. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), this property is ignored.",
|
||||
"description": "The number of rows displayed in the window upon first load.",
|
||||
"maximum": 999,
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
@@ -578,13 +551,11 @@
|
||||
},
|
||||
"launchMode": {
|
||||
"default": "default",
|
||||
"description": "Defines whether the terminal will launch as maximized, full screen, or in a window. Setting this to \"focus\" is equivalent to launching the terminal in the \"default\" mode, but with the focus mode enabled. Similar, setting this to \"maximizedFocus\" will result in launching the terminal in a maximized window with the focus mode enabled.",
|
||||
"description": "Defines whether the terminal will launch as maximized, full screen, or in a window.",
|
||||
"enum": [
|
||||
"fullscreen",
|
||||
"maximized",
|
||||
"default",
|
||||
"focus",
|
||||
"maximizedFocus"
|
||||
"default"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -649,7 +620,7 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"useTabSwitcher": {
|
||||
"default": true,
|
||||
"default": false,
|
||||
"description": "When set to \"true\", the \"nextTab\" and \"prevTab\" commands will use the tab switcher UI.",
|
||||
"type": "boolean"
|
||||
}
|
||||
@@ -724,11 +695,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"bellStyle": {
|
||||
"default": "audible",
|
||||
"description": "Controls what happens when the application emits a BEL character. When set to \"audible\", the Terminal will play a sound. When set to \"none\", nothing will happen.",
|
||||
"$ref": "#/definitions/BellStyle"
|
||||
},
|
||||
"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.",
|
||||
@@ -844,7 +810,10 @@
|
||||
"minimum": -1,
|
||||
"type": "integer"
|
||||
},
|
||||
"icon":{ "$ref": "#/definitions/Icon" },
|
||||
"icon": {
|
||||
"description": "Image file location of the icon used in the profile. Displays within the tab and the dropdown menu.",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the profile. Displays in the dropdown menu.",
|
||||
"minLength": 1,
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# Creating a New Project
|
||||
|
||||
## Creating a new WinRT Component DLL and referencing it in another project
|
||||
|
||||
When creating a new DLL, it was really helpful to reference an existing DLL's `.vcxproj` like `TerminalControl.vcxproj`. While you should mostly try to copy what the existing `.vcxproj` has, here's a handful of things to double check for as you go along.
|
||||
|
||||
- [ ] Make sure to `<Import>` our pre props at the _top_ of the vcxproj, and our post props at the _bottom_ of the vcxproj.
|
||||
```
|
||||
<!-- pre props -->
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
|
||||
<!-- everything else -->
|
||||
|
||||
<!-- post props -->
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
```
|
||||
- [ ] Add a `<ProjectReference>` to your new `.vcxproj` in both `WindowsTerminal.vcxproj` and `TerminalApp.vcxproj`
|
||||
- [ ] Add a `<Reference>` to `TerminalAppLib.vcxproj` similar to this:
|
||||
```
|
||||
<Reference Include="Microsoft.Terminal.NewDLL">
|
||||
<HintPath>$(_BinRoot)TerminalNewDLL\Microsoft.Terminal.NewDLL.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
```
|
||||
- [ ] Make sure the project has a `.def` file with the following lines. The `WINRT_GetActivationFactory` part is important to expose the new DLL's activation factory so that other projects can successfully call the DLL's `GetActivationFactory` to get the DLL's classes.
|
||||
```
|
||||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
||||
```
|
||||
- For a bit more context on this whole process, the `AppXManifest.xml` file defines which classes belong to which DLLs. If your project wants class `X.Y.Z`, it can look it up in the manifest's definitions and see that it came from `X.Y.dll`. Then it'll load up the DLL, and call a particular function called `GetActivationFactory(L"X.Y.Z")` to get the class it wants. So, the definitions in `AppXManifest` are _required_ for this activation to work properly, and I found myself double checking the file to see that the definitions I expect are there.
|
||||
- _Note_: If your new library eventually rolls up as a reference to our Centennial Packaging project `CascadiaPackage`, you don't have to worry about manually adding your definitions to the `AppXManifest.xml` because the Centennial Packaging project automatically enumerates the reference tree of WinMDs and stitches that information into the `AppXManifest.xml`. However, if your new project does _not_ ultimately roll up to a packaging project that will automatically put the references into `AppXManifest`, you will have to add them in manually.
|
||||
|
||||
### Troubleshooting
|
||||
- If you hit an error that looks like this:
|
||||
```
|
||||
X found processing metadata file ..\blah1\Microsoft.UI.Xaml.winmd, type already exists in file ..\blah\NewDLLProject\Microsoft.UI.Xaml.winmd.
|
||||
```
|
||||
The `Microsoft.UI.Xaml.winmd` is showing up in the output folder when it shouldn't. Try adding this block at the top of your `.vcxproj`
|
||||
```
|
||||
<ItemDefinitionGroup>
|
||||
<Reference>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemDefinitionGroup>
|
||||
```
|
||||
This will make all references non-private, meaning "don't copy it into my folder" by default.
|
||||
|
||||
- If you hit a `Class not Registered` error, this might be because a class isn't getting registered in the app manifest. You can go check `src/cascadia/CascadiaPackage/bin/x64/Debug/AppX/AppXManifest.xml` to see if there exist entries to the classes of your newly created DLL. If the references aren't there, double check that you've added `<ProjectReference>` blocks to both `WindowsTerminal.vcxproj` and `TerminalApp.vcxproj`.
|
||||
|
||||
- If you hit an extremely vague error along the lines of `Error in the DLL`, and right before that line you notice that your new DLL is loaded and unloaded right after each other, double check that your new DLL's definitions show up in the `AppXManifest.xml` file. If your new DLL is included as a reference to a project that rolls up to `CascadiaPackage`, double check that you've created a `.def` file for the project. Otherwise if your new project _does not_ roll up to a package that populates the `AppXManifest` references for you, you'll have to add those references yourself.
|
||||
@@ -1,251 +0,0 @@
|
||||
---
|
||||
author: Carlos Zamora @carlos-zamora
|
||||
created on: 2020-07-10
|
||||
last updated: 2020-07-10
|
||||
issue id: [#885](https://github.com/microsoft/terminal/issues/885)
|
||||
---
|
||||
|
||||
# Terminal Settings Model
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec proposes a major refactor and repurposing of the TerminalSettings project as the TerminalSettingsModel.
|
||||
TerminalSettingsModel would be responsible for exposing, serializing, and deserializing settings as WinRT objects
|
||||
for Windows Terminal. In doing so, Terminal's settings model is accessible as WinRT objects to existing components
|
||||
like TerminalApp, TerminalControl, and TerminalCore. Additionally, Terminal Settings can be used by the Settings UI or
|
||||
Shell Extensions to modify or reference Terminal's settings respectively.
|
||||
|
||||
## Inspiration
|
||||
|
||||
The main driver for this change is the Settings UI. The Settings UI will need to read and modify Terminal's settings
|
||||
objects. At the time of writing this spec, the Terminal's settings are serialized as objects in the TerminalApp project.
|
||||
To access these objects via XAML, the Settings UI needs them to be WinRT objects. Additional features that need the
|
||||
settings objects to be WinRT objects include future shell extensions, like jumplist.
|
||||
|
||||
## Solution Design
|
||||
|
||||
### Terminal Settings Model: Objects and Projections
|
||||
|
||||
The following TerminalApp objects will become WinRT objects and will be moved to the TerminalSettingsModel project
|
||||
(formerly TerminalSettings):
|
||||
- ColorScheme
|
||||
- Profile
|
||||
- GlobalAppSettings
|
||||
- CascadiaSettings
|
||||
|
||||
The TerminalSettingsModel project will have a root namespace of `Microsoft.Terminal.Settings.Model`.
|
||||
|
||||
Adjacent to the introduction of these settings objects, `IControlSettings` and `ICoreSettings` will be moved
|
||||
to the `Microsoft.Terminal.TerminalControl` namespace. This allows for a better consumption of the
|
||||
settings model that is covered later in the (Consumption section)[#terminal-settings-model:-consumption].
|
||||
|
||||
#### Moving/Splitting the Action Model
|
||||
|
||||
Windows Terminal represents actions via several objects:
|
||||
- `AppKeyBindings`: a map of all the defined keybindings and their corresponding actions
|
||||
- `ActionAndArgs`: a (de)serializable action (this holds more objects inside of it, but we won't focus on that for now)
|
||||
- `ShortcutActionDispatch`: responsible for dispatching events pertinent to a given ActionAndArgs object
|
||||
`TerminalApp`'s `TerminalPage` handles any events dispatched by the `ShortcutActionDispatch`.
|
||||
|
||||
With the introduction of the TerminalSettingsModel, we will split `AppKeyBindings` using a `KeyMapping` class.
|
||||
This separation will look something like the following:
|
||||
```c++
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass AppKeyBindings : Microsoft.Terminal.TerminalControl.IKeyBindings
|
||||
{
|
||||
AppKeyBindings();
|
||||
|
||||
// NOTE: It may be possible to move both of these to the constructor instead
|
||||
void SetDispatch(ShortcutActionDispatch dispatch);
|
||||
void SetKeyMap(KeyMapping keymap);
|
||||
}
|
||||
}
|
||||
|
||||
namespace TerminalSettingsModel
|
||||
{
|
||||
[default_interface] runtimeclass KeyMapping
|
||||
{
|
||||
void SetKeyBinding(ActionAndArgs actionAndArgs, Microsoft.Terminal.TerminalControl.KeyChord chord);
|
||||
void ClearKeyBinding(Microsoft.Terminal.TerminalControl.KeyChord chord);
|
||||
|
||||
Microsoft.Terminal.TerminalControl.KeyChord GetKeyBindingForAction(ShortcutAction action);
|
||||
Microsoft.Terminal.TerminalControl.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs);
|
||||
}
|
||||
}
|
||||
```
|
||||
This separation leaves `AppKeyBindings` with the responsibility of detecting and dispatching actions, whereas
|
||||
`KeyMapping` handles the (de)serialization and navigation of the key bindings.
|
||||
|
||||
|
||||
### Terminal Settings Model: Serialization and Deserialization
|
||||
|
||||
Introducing these `Microsoft.Terminal.Settings.Model` WinRT objects also allow the serialization and deserialization
|
||||
logic from TerminalApp to be moved to TerminalSettings. `JsonUtils` introduces several quick and easy methods
|
||||
for setting serialization. This will be moved into the `Microsoft.Terminal.Settings.Model` namespace too.
|
||||
|
||||
Deserialization will be an extension of the existing `JsonUtils` `ConversionTrait` struct template. `ConversionTrait`
|
||||
already includes `FromJson` and `CanConvert`. Serialization would be handled by a `ToJson` function.
|
||||
|
||||
|
||||
### Terminal Settings Model: Warnings and Serialization Errors
|
||||
|
||||
Today, if the deserialization of `CascadiaSettings` encounters any errors, an exception is thrown and caught/handled
|
||||
by falling back to a simple `CascadiaSettings` object. However, WinRT does not support exceptions.
|
||||
|
||||
To get around this issue, when `CascadiaSettings` encounters a serialization error, it must internally record
|
||||
any pertinent information for that error, and return the simple `CascadiaSettings` as if nothing happened.
|
||||
The consumer must then call `CascadiaSettings::GetErrors()` and `CascadiaSettings::GetWarnings()` to properly
|
||||
understand whether an error ocurred and how to present that to the user.
|
||||
|
||||
|
||||
#### TerminalApp: Loading and Reloading Changes
|
||||
|
||||
TerminalApp will construct and reference a `CascadiaSettings settings` as follows:
|
||||
- TerminalApp will have a global reference to the "settings.json" filepath
|
||||
- construct an `CascadiaSettings` using `CascadiaSettings("settings.json")`. This builds an `CascadiaSettings`
|
||||
from the "defaults.json" file data (which is already compiled as a string literal)
|
||||
and layers the settings.json data on top of it.
|
||||
- check for errors/warnings, and handle them appropriately
|
||||
|
||||
This will be different from the current model which has the settings.json path hardcoded, and is simplified
|
||||
to a `LoadAll()` call wrapped in error handlers.
|
||||
|
||||
**NOTE:** This model allows us to layer even more settings files on top of the existing Terminal Settings
|
||||
Model, if so desired. This could be helpful when importing additional settings files from an external location
|
||||
such as a marketplace.
|
||||
|
||||
When TerminalApp detects a change to settings.json, it'll repeat the steps above. We could cache the result from
|
||||
constructing an `CascadiaSettings` from "defaults.json" data to improve performance.
|
||||
|
||||
|
||||
#### TerminalControl: Acquiring and Applying the Settings
|
||||
|
||||
At the time of writing this spec, TerminalApp constructs `TerminalControl.TerminalSettings` WinRT objects
|
||||
to expose `IControlSettings` and `ICoreSettings` to any hosted terminals. In moving `IControlSettings`
|
||||
and `ICoreSettings` down to the TerminalControl layer, TerminalApp can now have better control over
|
||||
how to expose relevant settings to a TerminalControl instance.
|
||||
|
||||
`TerminalSettings` (which implements `IControlSettings` and `ICoreSettings`) will be moved to
|
||||
TerminalApp and act as a bridge connecting `CascadiaSettings` to the TermControl. It will operate
|
||||
very similarly as it does today. On construction of the TermControl or hot-reload,
|
||||
`TerminalSettings` will be constructed by copying the relevant values of `CascadiaSettings`.
|
||||
Then, it will be passed to TermControl (and TermCore by extension).
|
||||
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
N/A
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
N/A
|
||||
|
||||
### Security
|
||||
|
||||
N/A
|
||||
|
||||
### Reliability
|
||||
|
||||
N/A
|
||||
|
||||
### Compatibility
|
||||
|
||||
N/A
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
## Potential Issues
|
||||
|
||||
N/A
|
||||
|
||||
## Future considerations
|
||||
|
||||
### TerminalSettings: passing by reference
|
||||
|
||||
`TermApp` synthesizes a `TerminalSettings` by copying the relevant values of `CascadiaSettings`,
|
||||
then giving it to a Terminal Control. Some visual keybindings and interactions like ctrl+scroll
|
||||
and ctrl+shift+scroll to change the font size and acrylic opacity operate by directly modifying
|
||||
the value of the instantiated `TerminalSettings`. However, when a settings reload occurs,
|
||||
these instanced changes are lost.
|
||||
|
||||
`TerminalSettings` can be used as a WinRT object that references (instead of copies) the relevant
|
||||
values of `CascadiaSettings`. This would prevent those instanced changes from being lost on a settings
|
||||
reload.
|
||||
|
||||
Since previewing commands like `setColorScheme` would require a clone of the existing `TerminalSettings`,
|
||||
a `Clone` API can be added on `TerminalSettings` to accomplish that. When passing by value,
|
||||
`TerminalSettings` can just overwrite the existing property (i.e.: color scheme). When passing
|
||||
by reference, a slightly more complex mechanism is required to override the value.
|
||||
|
||||
Now, instead of overwriting the value, we need to override the reference to a constant value
|
||||
(i.e.: `snapOnInput=true`) or a referenced value (i.e.: `colorScheme`).
|
||||
|
||||
### Layering Additional Settings
|
||||
As we begin to introduce more sources that affect the settings (via extensions or themes),
|
||||
we can introduce a `LayerSettings(String path)`. This layers the new settings file
|
||||
onto the existing `CascadiaSettings`. This is already done internally, we would just expose
|
||||
it via C++/WinRT.
|
||||
|
||||
```c++
|
||||
runtimeclass CascadiaSettings
|
||||
{
|
||||
// Load a settings file, and layer those changes on top of the existing CascadiaSettings
|
||||
void LayerSettings(String path);
|
||||
}
|
||||
```
|
||||
|
||||
### Settings UI: Modifying and Applying the Settings (DRAFT)
|
||||
|
||||
```c++
|
||||
runtimeclass CascadiaSettings
|
||||
{
|
||||
// Create a copy of the existing CascadiaSettings
|
||||
CascadiaSettings Clone();
|
||||
|
||||
// Compares object to "source" and applies changes to
|
||||
// the settings file at "outPath"
|
||||
void Save(String outPath);
|
||||
}
|
||||
```
|
||||
|
||||
The Settings UI will also have a reference to the `CascadiaSettings settings` from TerminalApp
|
||||
as `settingsSource`. When the Settings UI is opened up, the Settings UI will also have its own `CascadiaSettings settingsClone`
|
||||
that is a clone of TerminalApp's `CascadiaSettings`.
|
||||
```c++
|
||||
settingsClone = settingsSource.Clone()
|
||||
```
|
||||
|
||||
As the user navigates the Settings UI, the relevant contents of `settingsClone` will be retrieved and presented.
|
||||
As the user makes changes to the Settings UI, XAML will update `settingsClone` using XAML data binding.
|
||||
When the user saves/applies the changes in the XAML, `settingsClone.Save("settings.json")` is called;
|
||||
this compares the changes between `settingsClone` and `settingsSource`, then injects the changes (if any) to `settings.json`.
|
||||
|
||||
As mentioned earlier, TerminalApp detects a change to "settings.json" to update its `CascadiaSettings`.
|
||||
Since the above triggers a change to `settings.json`, TerminalApp will also update itself. When
|
||||
something like this occurs, `settingsSource` will automatically be updated too.
|
||||
|
||||
In the case that a user is simultaneously updating the settings file directly and the Settings UI,
|
||||
`settingsSource` and `settingsClone` can be compared to ensure that the Settings UI, the TerminalApp,
|
||||
and the settings files are all in sync.
|
||||
|
||||
**NOTE:** In the event that the user would want to export their current configuration, `Save`
|
||||
can be used to export the changes to a new file.
|
||||
|
||||
### Reserialization (DRAFT)
|
||||
|
||||
After deserializing the settings, injecting the new json into settings.json
|
||||
should not remove the existing comments or formatting.
|
||||
|
||||
The reserialization process takes place right after comparing the `settingsSource` and `settingsClone` objects.
|
||||
For each setting found in the diff, we go to the relevant part of the JSON and see if the key is already there.
|
||||
If it is, we update the value to be the one from `settingsClone`. Otherwise, we append the key/value pair
|
||||
at the end of the section (much like we do with dynamic profiles in `profiles`).
|
||||
|
||||
## Resources
|
||||
|
||||
- [Preview Commands](https://github.com/microsoft/terminal/issues/6689)
|
||||
- [New JSON Utils](https://github.com/microsoft/terminal/pull/6590)
|
||||
- [Spec: Settings UI](https://github.com/microsoft/terminal/pull/6720)
|
||||
@@ -22,14 +22,15 @@ 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 | |
|
||||
| 2020-12-31 | 1.6 in Windows Terminal Preview<br>[1.5] in Windows Terminal | |
|
||||
| 2021-01-31 | 1.7 in Windows Terminal Preview<br>1.6 in Windows Terminal | |
|
||||
| 2021-02-28 | 1.8 in Windows Terminal Preview<br>1.8 in Windows Terminal | |
|
||||
| 2021-03-31 | 1.9 in Windows Terminal Preview<br>1.9 in Windows Terminal | |
|
||||
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | |
|
||||
| 2020-08-31 | 1.3 in Windows Terminal Preview<br>[1.2] in Windows Terminal | |
|
||||
| 2020-09-30 | 1.4 in Windows Terminal Preview<br>1.3 in Windows Terminal | |
|
||||
| 2020-10-31 | 1.5 in Windows Terminal Preview<br>1.4 in Windows Terminal | |
|
||||
| 2020-11-30 | 1.6 in Windows Terminal Preview<br>1.5 in Windows Terminal | |
|
||||
| 2020-12-31 | 1.7 in Windows Terminal Preview<br>1.6 in Windows Terminal | |
|
||||
| 2021-01-31 | 1.8 in Windows Terminal Preview<br>1.7 in Windows Terminal | |
|
||||
| 2021-02-28 | 1.9 in Windows Terminal Preview<br>1.8 in Windows Terminal | |
|
||||
| 2021-03-31 | 1.10 in Windows Terminal Preview<br>1.9 in Windows Terminal | |
|
||||
| 2021-04-30 | 2.0 RC in Windows Terminal Preview<br>2.0 RC in Windows Terminal | |
|
||||
| 2021-05-31 | [2.0] in Windows Terminal Preview<br>[2.0] in Windows Terminal | |
|
||||
|
||||
@@ -49,11 +50,11 @@ The following are a list of the key scenarios we're aiming to deliver for Termin
|
||||
|
||||
| Priority\* | Scenario | Description/Notes |
|
||||
| ---------- | -------- | ----------------- |
|
||||
| 0 | Settings UI | A user interface that connects to settings.json. This provides a way for people to edit their settings without having to edit a JSON file.<br><br>Issue: [#1564]<br>Specs: [#6720], [#6904]<br>Implementation: [#7283], [#7370] |
|
||||
| 0 | Command palette | A popup menu to list possible actions and commands.<br><br>Issues: [#5400], [#2046]<br>Spec: [#2193]<br>Implementation: [#6635] |
|
||||
| 0 | Settings UI | A user interface that connects to settings.json. This provides a way for people to edit their settings without having to edit a JSON file.<br><br>Issue: [#1564] |
|
||||
| 0 | Command palette | A popup menu to list possible actions and commands.<br><br>Issues: [#5400], [#2046]<br>Spec: [#2193] |
|
||||
| 1 | Tab tear-off | The ability to tear a tab out of the current window and spawn a new window or attach it to a separate window.<br><br>Issue: [#1256]<br>Spec: [#2080] |
|
||||
| 1 | Clickable links | Hyperlinking any links that appear in the text buffer. When clicking on the link, the link will open in your default browser.<br><br>Issue: [#574]<br>Implementation: [#7251] |
|
||||
| 1 | Default terminal | If a command-line application is spawned, it should open in Windows Terminal (if installed) or your preferred terminal<br><br>Issue: [#492]<br>Spec: [#2080], [#7414] |
|
||||
| 1 | Clickable links | Hyperlinking any links that appear in the text buffer. When clicking on the link, the link will open in your default browser.<br><br>Issue: [#574] |
|
||||
| 1 | Default terminal | If a command-line application is spawned, it should open in Windows Terminal (if installed) or your preferred terminal<br><br>Issue: [#492]<br>Spec: [#2080] |
|
||||
| 1 | Overall theme support | Tab coloring, title bar coloring, pane border coloring, pane border width, definition of what makes a theme<br><br>Issue: [#3327]<br>Spec: [#5772] |
|
||||
| 1 | Open tab as admin/other user | Open tab in existing Windows Terminal instance as admin (if Terminal was run unelevated) or as another user.<br><br>Issue: [#5000] |
|
||||
| 1 | Traditional opacity | Have a transparent background without the acrylic blur.<br><br>Issue: [#603] |
|
||||
@@ -61,7 +62,7 @@ The following are a list of the key scenarios we're aiming to deliver for Termin
|
||||
| 2 | Infinite scrollback | Have an infinite history for the text buffer.<br><br>Issue: [#1410] |
|
||||
| 2 | Pane management | All issues listed out in the original issue. Some features include pane resizing with mouse, pane zooming, and opening a pane by prompting which profile to use.<br><br>Issue: [#1000] |
|
||||
| 2 | Theme marketplace | Marketplace for creation and distribution of themes.<br>Dependent on overall theming |
|
||||
| 2 | Jump list | Show profiles from task bar (on right click)/start menu.<br><br>Issue: [#576]<br>Implementation: [#7515] |
|
||||
| 2 | Jump list | Show profiles from task bar (on right click)/start menu.<br><br>Issue: [#576] |
|
||||
| 2 | Open with multiple tabs | A setting that allows Windows Terminal to launch with a specific tab configuration (not using only command line arguments).<br><br>Issue: [#756] |
|
||||
| 3 | Open in Windows Terminal | Functionality to right click on a file or folder and select Open in Windows Terminal.<br><br>Issue: [#1060]<br>Implementation: [#6100] |
|
||||
| 3 | Session restoration | Launch Windows Terminal and the previous session is restored with the proper tab and pane configuration and starting directories.<br><br>Issues: [#961], [#960], [#766] |
|
||||
@@ -79,26 +80,16 @@ Feature Notes:
|
||||
|
||||
[1.1]: https://github.com/microsoft/terminal/milestone/24
|
||||
[1.2]: https://github.com/microsoft/terminal/milestone/25
|
||||
[1.3]: https://github.com/microsoft/terminal/milestone/26
|
||||
[1.4]: https://github.com/microsoft/terminal/milestone/28
|
||||
[1.5]: https://github.com/microsoft/terminal/milestone/30
|
||||
[2.0]: https://github.com/microsoft/terminal/milestone/22
|
||||
[#1564]: https://github.com/microsoft/terminal/issues/1564
|
||||
[#6720]: https://github.com/microsoft/terminal/pull/6720
|
||||
[#6904]: https://github.com/microsoft/terminal/pull/6904
|
||||
[#7283]: https://github.com/microsoft/terminal/pull/7283
|
||||
[#7370]: https://github.com/microsoft/terminal/pull/7370
|
||||
[#5400]: https://github.com/microsoft/terminal/issues/5400
|
||||
[#2046]: https://github.com/microsoft/terminal/issues/2046
|
||||
[#2193]: https://github.com/microsoft/terminal/pull/2193
|
||||
[#6635]: https://github.com/microsoft/terminal/pull/6635
|
||||
[#1256]: https://github.com/microsoft/terminal/issues/1256
|
||||
[#2080]: https://github.com/microsoft/terminal/pull/2080
|
||||
[#574]: https://github.com/microsoft/terminal/issues/574
|
||||
[#7251]: https://github.com/microsoft/terminal/pull/7251
|
||||
[#492]: https://github.com/microsoft/terminal/issues/492
|
||||
[#2080]: https://github.com/microsoft/terminal/pull/2080
|
||||
[#7414]: https://github.com/microsoft/terminal/pull/7414
|
||||
[#3327]: https://github.com/microsoft/terminal/issues/3327
|
||||
[#5772]: https://github.com/microsoft/terminal/pull/5772
|
||||
[#5000]: https://github.com/microsoft/terminal/issues/5000
|
||||
@@ -109,7 +100,6 @@ Feature Notes:
|
||||
[#1410]: https://github.com/microsoft/terminal/issues/1410
|
||||
[#1000]: https://github.com/microsoft/terminal/issues/1000
|
||||
[#576]: https://github.com/microsoft/terminal/issues/576
|
||||
[#7515]: https://github.com/microsoft/terminal/pull/7515
|
||||
[#756]: https://github.com/microsoft/terminal/issues/756
|
||||
[#1060]: https://github.com/microsoft/terminal/issues/1060
|
||||
[#6100]: https://github.com/microsoft/terminal/pull/6100
|
||||
|
||||
@@ -2350,11 +2350,13 @@ std::wstring TextBuffer::GetCustomIdFromId(uint16_t id) const
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Copies the hyperlink/customID maps of the old buffer into this one
|
||||
// - Copies the hyperlink/customID maps of the old buffer into this one,
|
||||
// also copies currentHyperlinkId
|
||||
// Arguments:
|
||||
// - The other buffer
|
||||
void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
|
||||
{
|
||||
_hyperlinkMap = other._hyperlinkMap;
|
||||
_hyperlinkCustomIdMap = other._hyperlinkCustomIdMap;
|
||||
_currentHyperlinkId = other._currentHyperlinkId;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<Link>ProfileIcons\%(RecursiveDir)%(FileName)%(Extension)</Link>
|
||||
</Content>
|
||||
<!-- Default Settings -->
|
||||
<Content Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\defaults.json">
|
||||
<Content Include="$(OpenConsoleDir)src\cascadia\TerminalApp\defaults.json">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
|
||||
</Content>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
||||
@@ -1,112 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!-- A note about this project: We're building the test code dll from this
|
||||
project, but it _MUST_ be run in conjunction with the TestHostApp project.
|
||||
TestHostApp actually will build a TestHost executable and packaging bits
|
||||
that we can use to run our tests. We need TestHostApp so that our
|
||||
dependencies, like MUX, can be aggregated correctly, and resources properly
|
||||
combined into a resources.pri file.
|
||||
|
||||
TestHostApp will manually copy the output of this project into it's own
|
||||
OutDir, so we can run the tests from there. -->
|
||||
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{CA5CAD1A-9B68-456A-B13E-C8218070DC42}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>SettingsModelLocalTests</RootNamespace>
|
||||
<ProjectName>LocalTests_SettingsModel</ProjectName>
|
||||
<TargetName>SettingsModel.LocalTests</TargetName>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<!-- We'll manage our own OutDir/IntDir -->
|
||||
<NoOutputRedirection>true</NoOutputRedirection>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Manually change our outdir to be in a subdirectory. We don't really want
|
||||
to put our output in the bin root, because if we do, we'll copy
|
||||
TerminalApp.winmd to the bin root, and then every subsequent mdmerge step
|
||||
(in _any_ cppwinrt project) will automatically try to pick up
|
||||
TerminalApp.winmd as a dependency (which is just wrong). This MUST be done
|
||||
before importing common.build.pre.props -->
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(SolutionDir)\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)\src\cppwinrt.build.pre.props" />
|
||||
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="JsonTestClass.h" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ProfileTests.cpp" />
|
||||
<ClCompile Include="ColorSchemeTests.cpp" />
|
||||
<ClCompile Include="KeyBindingsTests.cpp" />
|
||||
<ClCompile Include="CommandTests.cpp" />
|
||||
<ClCompile Include="DeserializationTests.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
|
||||
you want to use jsoncpp -->
|
||||
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Project References ======================== -->
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\Microsoft.Terminal.Settings.ModelLib.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)\src\types\lib\types.vcxproj" />
|
||||
|
||||
<!-- If you don't reference these projects here, the
|
||||
_ConsoleGenerateAdditionalWinmdManifests step won't gather the winmd's -->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Globals ======================== -->
|
||||
|
||||
<!-- ====================== Compiler & Linker Flags ===================== -->
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\Generated Files";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
|
||||
<!-- Manually disable unreachable code warning, because jconcpp has a ton of that. -->
|
||||
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.tests.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_CppWinrtBinRoot>"$(OpenConsoleDir)$(Platform)\$(Configuration)\"</_CppWinrtBinRoot>
|
||||
<!-- From Microsoft.UI.Xaml.targets -->
|
||||
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
|
||||
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
|
||||
<_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\"</_MUXBinRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- We actually can just straight up reference MUX here, it's fine -->
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
@@ -1,65 +0,0 @@
|
||||
/*++
|
||||
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).
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora (cazamor) April 2019
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
||||
#define BLOCK_TIL
|
||||
// This includes support libraries from the CRT, STL, WIL, and GSL
|
||||
#include "LibraryIncludes.h"
|
||||
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
|
||||
// SDK definition of this function, so the only fix is to undef it.
|
||||
// from WinBase.h
|
||||
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
#include <wil/cppwinrt.h>
|
||||
#include <unknwn.h>
|
||||
#include <hstring.h>
|
||||
|
||||
#include <WexTestClass.h>
|
||||
#include <json.h>
|
||||
#include "consoletaeftemplates.hpp"
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
|
||||
#include "winrt/Windows.UI.Xaml.Markup.h"
|
||||
#include <winrt/Windows.system.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/windows.ui.core.h>
|
||||
#include <winrt/Windows.ui.input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.ui.xaml.media.h>
|
||||
#include <winrt/Windows.ui.xaml.input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||
#include <winrt/Windows.UI.Xaml.Documents.h>
|
||||
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
#include <winrt/windows.applicationmodel.core.h>
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
|
||||
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
||||
#include "til.h"
|
||||
|
||||
// Common includes for most tests:
|
||||
#include "../../inc/argb.h"
|
||||
#include "../../inc/conattrs.hpp"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
@@ -3,17 +3,18 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../TerminalSettingsModel/ColorScheme.h"
|
||||
#include "../TerminalSettingsModel/CascadiaSettings.h"
|
||||
#include "../TerminalApp/ColorScheme.h"
|
||||
#include "../TerminalApp/CascadiaSettings.h"
|
||||
#include "JsonTestClass.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp::implementation;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
// TODO:microsoft/terminal#3838:
|
||||
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
|
||||
@@ -130,11 +131,11 @@ namespace SettingsModelLocalTests
|
||||
const auto scheme2Json = VerifyParseSucceeded(scheme2String);
|
||||
|
||||
auto scheme0 = ColorScheme::FromJson(scheme0Json);
|
||||
VERIFY_ARE_EQUAL(L"scheme0", scheme0->_Name);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 0), scheme0->_SelectionBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 1), scheme0->_CursorColor);
|
||||
VERIFY_ARE_EQUAL(L"scheme0", scheme0->_schemeName);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 0), scheme0->_selectionBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 1), scheme0->_cursorColor);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 0), scheme0->_table[XTERM_RED_ATTR]);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0->_table[XTERM_GREEN_ATTR]);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 1), scheme0->_table[XTERM_BLUE_ATTR]);
|
||||
@@ -143,10 +144,10 @@ namespace SettingsModelLocalTests
|
||||
L"Layering scheme1 on top of scheme0"));
|
||||
scheme0->LayerJson(scheme1Json);
|
||||
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 0), scheme0->_SelectionBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 0, 4), scheme0->_CursorColor);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme0->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 0), scheme0->_selectionBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 0, 4), scheme0->_cursorColor);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 0, 0), scheme0->_table[XTERM_RED_ATTR]);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0->_table[XTERM_GREEN_ATTR]);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0->_table[XTERM_BLUE_ATTR]);
|
||||
@@ -155,10 +156,10 @@ namespace SettingsModelLocalTests
|
||||
L"Layering scheme2Json on top of (scheme0+scheme1)"));
|
||||
scheme0->LayerJson(scheme2Json);
|
||||
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 0), scheme0->_SelectionBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 6, 0, 6), scheme0->_CursorColor);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 0), scheme0->_selectionBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 6, 0, 6), scheme0->_cursorColor);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 0, 0), scheme0->_table[XTERM_RED_ATTR]);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 3, 0), scheme0->_table[XTERM_GREEN_ATTR]);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0->_table[XTERM_BLUE_ATTR]);
|
||||
@@ -192,7 +193,7 @@ namespace SettingsModelLocalTests
|
||||
const auto scheme2Json = VerifyParseSucceeded(scheme2String);
|
||||
const auto scheme3Json = VerifyParseSucceeded(scheme3String);
|
||||
|
||||
auto settings = winrt::make_self<CascadiaSettings>();
|
||||
auto settings = winrt::make_self<winrt::TerminalApp::implementation::CascadiaSettings>();
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, settings->_globals->ColorSchemes().Size());
|
||||
VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme0Json));
|
||||
@@ -217,8 +218,8 @@ namespace SettingsModelLocalTests
|
||||
VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme1Json));
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json));
|
||||
VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json));
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground);
|
||||
}
|
||||
|
||||
settings->_LayerOrCreateColorScheme(scheme1Json);
|
||||
@@ -237,10 +238,10 @@ namespace SettingsModelLocalTests
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme1Json));
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json));
|
||||
VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json));
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground);
|
||||
}
|
||||
settings->_LayerOrCreateColorScheme(scheme2Json);
|
||||
|
||||
@@ -258,10 +259,10 @@ namespace SettingsModelLocalTests
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme1Json));
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json));
|
||||
VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json));
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground);
|
||||
}
|
||||
settings->_LayerOrCreateColorScheme(scheme3Json);
|
||||
|
||||
@@ -282,12 +283,12 @@ namespace SettingsModelLocalTests
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme1Json));
|
||||
VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json));
|
||||
VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json));
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 6, 6, 6), scheme2->_Foreground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 7, 7, 7), scheme2->_Background);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 6, 6, 6), scheme2->_defaultForeground);
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 7, 7, 7), scheme2->_defaultBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,20 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../TerminalSettingsModel/CascadiaSettings.h"
|
||||
#include "../TerminalApp/CascadiaSettings.h"
|
||||
#include "JsonTestClass.h"
|
||||
#include "TestUtils.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
// TODO:microsoft/terminal#3838:
|
||||
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
|
||||
@@ -61,7 +62,7 @@ namespace SettingsModelLocalTests
|
||||
const auto commands1Json = VerifyParseSucceeded(commands1String);
|
||||
const auto commands2Json = VerifyParseSucceeded(commands2String);
|
||||
|
||||
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
|
||||
IMap<winrt::hstring, winrt::TerminalApp::Command> commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
VERIFY_ARE_EQUAL(0u, commands.Size());
|
||||
{
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
@@ -95,7 +96,7 @@ namespace SettingsModelLocalTests
|
||||
const auto commands2Json = VerifyParseSucceeded(commands2String);
|
||||
const auto commands3Json = VerifyParseSucceeded(commands3String);
|
||||
|
||||
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
|
||||
IMap<winrt::hstring, winrt::TerminalApp::Command> commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
VERIFY_ARE_EQUAL(0u, commands.Size());
|
||||
{
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
@@ -153,7 +154,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
|
||||
IMap<winrt::hstring, winrt::TerminalApp::Command> commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
VERIFY_ARE_EQUAL(0u, commands.Size());
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
VERIFY_ARE_EQUAL(0u, warnings.size());
|
||||
@@ -167,7 +168,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.Lookup(L"command1");
|
||||
@@ -177,7 +178,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Vertical, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.Lookup(L"command2");
|
||||
@@ -187,7 +188,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Horizontal, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.Lookup(L"command4");
|
||||
@@ -197,7 +198,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.Lookup(L"command5");
|
||||
@@ -207,7 +208,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
}
|
||||
void CommandTests::TestResourceKeyName()
|
||||
@@ -217,7 +218,7 @@ namespace SettingsModelLocalTests
|
||||
const std::string commands0String{ R"([ { "name": { "key": "DuplicateTabCommandKey"}, "command": "copy" } ])" };
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
|
||||
IMap<winrt::hstring, winrt::TerminalApp::Command> commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
VERIFY_ARE_EQUAL(0u, commands.Size());
|
||||
{
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
@@ -265,7 +266,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
|
||||
IMap<winrt::hstring, winrt::TerminalApp::Command> commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
VERIFY_ARE_EQUAL(0u, commands.Size());
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
VERIFY_ARE_EQUAL(0u, warnings.size());
|
||||
@@ -283,7 +284,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.Lookup(L"Split pane, split: vertical");
|
||||
@@ -293,7 +294,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Vertical, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
auto command = commands.Lookup(L"Split pane, split: horizontal");
|
||||
@@ -303,7 +304,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Horizontal, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle());
|
||||
}
|
||||
}
|
||||
void CommandTests::TestLayerOnAutogeneratedName()
|
||||
@@ -315,7 +316,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto commands0Json = VerifyParseSucceeded(commands0String);
|
||||
|
||||
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
|
||||
IMap<winrt::hstring, winrt::TerminalApp::Command> commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
VERIFY_ARE_EQUAL(0u, commands.Size());
|
||||
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
|
||||
VERIFY_ARE_EQUAL(0u, warnings.size());
|
||||
@@ -329,7 +330,7 @@ namespace SettingsModelLocalTests
|
||||
const auto& realArgs = command.Action().Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Vertical, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
#include "../TerminalApp/TerminalPage.h"
|
||||
#include "../TerminalApp/AppCommandlineArgs.h"
|
||||
#include "../TerminalApp/ActionArgs.h"
|
||||
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::Common;
|
||||
using namespace WEX::TestExecution;
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace ::TerminalApp;
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace TerminalAppLocalTests
|
||||
TEST_METHOD(TestSimpleExecuteCommandlineAction);
|
||||
TEST_METHOD(TestMultipleCommandExecuteCommandlineAction);
|
||||
TEST_METHOD(TestInvalidExecuteCommandlineAction);
|
||||
TEST_METHOD(TestLaunchMode);
|
||||
|
||||
private:
|
||||
void _buildCommandlinesHelper(AppCommandlineArgs& appArgs,
|
||||
@@ -1077,8 +1076,9 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void CommandlineTest::TestSimpleExecuteCommandlineAction()
|
||||
{
|
||||
ExecuteCommandlineArgs args{ L"new-tab" };
|
||||
auto actions = implementation::TerminalPage::ConvertExecuteCommandlineToActions(args);
|
||||
auto args = winrt::make_self<implementation::ExecuteCommandlineArgs>();
|
||||
args->Commandline(L"new-tab");
|
||||
auto actions = implementation::TerminalPage::ConvertExecuteCommandlineToActions(*args);
|
||||
VERIFY_ARE_EQUAL(1u, actions.size());
|
||||
auto actionAndArgs = actions.at(0);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
|
||||
@@ -1095,8 +1095,9 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void CommandlineTest::TestMultipleCommandExecuteCommandlineAction()
|
||||
{
|
||||
ExecuteCommandlineArgs args{ L"new-tab ; split-pane" };
|
||||
auto actions = implementation::TerminalPage::ConvertExecuteCommandlineToActions(args);
|
||||
auto args = winrt::make_self<implementation::ExecuteCommandlineArgs>();
|
||||
args->Commandline(L"new-tab ; split-pane");
|
||||
auto actions = implementation::TerminalPage::ConvertExecuteCommandlineToActions(*args);
|
||||
VERIFY_ARE_EQUAL(2u, actions.size());
|
||||
{
|
||||
auto actionAndArgs = actions.at(0);
|
||||
@@ -1128,100 +1129,10 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void CommandlineTest::TestInvalidExecuteCommandlineAction()
|
||||
{
|
||||
auto args = winrt::make_self<implementation::ExecuteCommandlineArgs>();
|
||||
// -H and -V cannot be combined.
|
||||
ExecuteCommandlineArgs args{ L"split-pane -H -V" };
|
||||
auto actions = implementation::TerminalPage::ConvertExecuteCommandlineToActions(args);
|
||||
args->Commandline(L"split-pane -H -V");
|
||||
auto actions = implementation::TerminalPage::ConvertExecuteCommandlineToActions(*args);
|
||||
VERIFY_ARE_EQUAL(0u, actions.size());
|
||||
}
|
||||
|
||||
void CommandlineTest::TestLaunchMode()
|
||||
{
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_FALSE(appArgs.GetLaunchMode().has_value());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"-F" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::FullscreenMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"--fullscreen" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::FullscreenMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"-M" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"--maximized" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"-f" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::FocusMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"--focus" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::FocusMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"-fM" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedFocusMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"--maximized", L"--focus" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedFocusMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"--maximized", L"--focus", L"--focus" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedFocusMode);
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", L"--maximized", L"--focus", L"--maximized" };
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_IS_TRUE(appArgs.GetLaunchMode().has_value());
|
||||
VERIFY_ARE_EQUAL(appArgs.GetLaunchMode().value(), LaunchMode::MaximizedFocusMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,21 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../TerminalSettingsModel/ColorScheme.h"
|
||||
#include "../TerminalSettingsModel/CascadiaSettings.h"
|
||||
#include "../TerminalSettingsModel/KeyMapping.h"
|
||||
#include "../TerminalApp/ColorScheme.h"
|
||||
#include "../TerminalApp/CascadiaSettings.h"
|
||||
#include "../KeyMapping.h"
|
||||
#include "JsonTestClass.h"
|
||||
#include "TestUtils.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
// TODO:microsoft/terminal#3838:
|
||||
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
|
||||
@@ -66,7 +67,7 @@ namespace SettingsModelLocalTests
|
||||
const auto bindings1Json = VerifyParseSucceeded(bindings1String);
|
||||
const auto bindings2Json = VerifyParseSucceeded(bindings2String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
|
||||
@@ -90,7 +91,7 @@ namespace SettingsModelLocalTests
|
||||
const auto bindings1Json = VerifyParseSucceeded(bindings1String);
|
||||
const auto bindings2Json = VerifyParseSucceeded(bindings2String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
|
||||
@@ -120,7 +121,7 @@ namespace SettingsModelLocalTests
|
||||
const auto bindings4Json = VerifyParseSucceeded(bindings4String);
|
||||
const auto bindings5Json = VerifyParseSucceeded(bindings5String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
|
||||
@@ -189,7 +190,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto bindings0Json = VerifyParseSucceeded(bindings0String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
keymap->LayerJson(bindings0Json);
|
||||
@@ -199,7 +200,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `copy` without args parses as Copy(SingleLine=false)"));
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('C') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
@@ -210,7 +211,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `copy` with args parses them correctly"));
|
||||
KeyChord kc{ true, false, true, static_cast<int32_t>('C') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
@@ -221,7 +222,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `copy` with args parses them correctly"));
|
||||
KeyChord kc{ false, true, true, static_cast<int32_t>('C') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
@@ -232,7 +233,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `newTab` without args parses as NewTab(Index=null)"));
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('T') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -244,7 +245,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `newTab` parses args correctly"));
|
||||
KeyChord kc{ true, false, true, static_cast<int32_t>('T') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -258,7 +259,7 @@ namespace SettingsModelLocalTests
|
||||
L"Verify that `newTab` with an index greater than the legacy "
|
||||
L"args afforded parses correctly"));
|
||||
KeyChord kc{ true, false, true, static_cast<int32_t>('Y') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -272,7 +273,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `copy` ignores args it doesn't understand"));
|
||||
KeyChord kc{ true, false, true, static_cast<int32_t>('B') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::CopyText, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -284,7 +285,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `copy` null as it's `args` parses as the default option"));
|
||||
KeyChord kc{ true, false, true, static_cast<int32_t>('B') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::CopyText, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -296,7 +297,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `adjustFontSize` with a positive delta parses args correctly"));
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('F') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::AdjustFontSize, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<AdjustFontSizeArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -308,7 +309,7 @@ namespace SettingsModelLocalTests
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that `adjustFontSize` with a negative delta parses args correctly"));
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('G') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::AdjustFontSize, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<AdjustFontSizeArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -329,7 +330,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto bindings0Json = VerifyParseSucceeded(bindings0String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
keymap->LayerJson(bindings0Json);
|
||||
@@ -337,48 +338,48 @@ namespace SettingsModelLocalTests
|
||||
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('C') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('D') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Vertical, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('E') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Horizontal, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('G') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('H') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, realArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +393,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto bindings0Json = VerifyParseSucceeded(bindings0String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
keymap->LayerJson(bindings0Json);
|
||||
@@ -400,7 +401,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('C') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SetTabColor, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SetTabColorArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -409,7 +410,7 @@ namespace SettingsModelLocalTests
|
||||
}
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('D') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SetTabColor, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SetTabColorArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -420,7 +421,7 @@ namespace SettingsModelLocalTests
|
||||
}
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('F') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SetTabColor, actionAndArgs.Action());
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<SetTabColorArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
@@ -437,7 +438,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
const auto bindings0Json = VerifyParseSucceeded(bindings0String);
|
||||
|
||||
auto keymap = winrt::make_self<implementation::KeyMapping>();
|
||||
auto keymap = winrt::make_self<winrt::TerminalApp::implementation::KeyMapping>();
|
||||
VERIFY_IS_NOT_NULL(keymap);
|
||||
VERIFY_ARE_EQUAL(0u, keymap->_keyShortcuts.size());
|
||||
keymap->LayerJson(bindings0Json);
|
||||
@@ -445,7 +446,7 @@ namespace SettingsModelLocalTests
|
||||
|
||||
{
|
||||
KeyChord kc{ true, false, false, static_cast<int32_t>('C') };
|
||||
auto actionAndArgs = ::TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
auto actionAndArgs = TestUtils::GetActionAndArgs(*keymap, kc);
|
||||
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
|
||||
VERIFY_IS_NOT_NULL(realArgs);
|
||||
// Verify the args have the expected value
|
||||
@@ -3,17 +3,18 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../TerminalSettingsModel/ColorScheme.h"
|
||||
#include "../TerminalSettingsModel/CascadiaSettings.h"
|
||||
#include "../TerminalApp/ColorScheme.h"
|
||||
#include "../TerminalApp/CascadiaSettings.h"
|
||||
#include "JsonTestClass.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
// TODO:microsoft/terminal#3838:
|
||||
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
|
||||
@@ -195,32 +196,32 @@ namespace SettingsModelLocalTests
|
||||
const auto profile3Json = VerifyParseSucceeded(profile3String);
|
||||
|
||||
auto profile0 = implementation::Profile::FromJson(profile0Json);
|
||||
VERIFY_IS_FALSE(profile0->Icon().empty());
|
||||
VERIFY_ARE_EQUAL(L"not-null.png", profile0->Icon());
|
||||
VERIFY_IS_FALSE(profile0->IconPath().empty());
|
||||
VERIFY_ARE_EQUAL(L"not-null.png", profile0->IconPath());
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that layering an object the key set to null will clear the key"));
|
||||
profile0->LayerJson(profile1Json);
|
||||
VERIFY_IS_TRUE(profile0->Icon().empty());
|
||||
VERIFY_IS_TRUE(profile0->IconPath().empty());
|
||||
|
||||
profile0->LayerJson(profile2Json);
|
||||
VERIFY_IS_TRUE(profile0->Icon().empty());
|
||||
VERIFY_IS_TRUE(profile0->IconPath().empty());
|
||||
|
||||
profile0->LayerJson(profile3Json);
|
||||
VERIFY_IS_FALSE(profile0->Icon().empty());
|
||||
VERIFY_ARE_EQUAL(L"another-real.png", profile0->Icon());
|
||||
VERIFY_IS_FALSE(profile0->IconPath().empty());
|
||||
VERIFY_ARE_EQUAL(L"another-real.png", profile0->IconPath());
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Verify that layering an object _without_ the key will not clear the key"));
|
||||
profile0->LayerJson(profile2Json);
|
||||
VERIFY_IS_FALSE(profile0->Icon().empty());
|
||||
VERIFY_ARE_EQUAL(L"another-real.png", profile0->Icon());
|
||||
VERIFY_IS_FALSE(profile0->IconPath().empty());
|
||||
VERIFY_ARE_EQUAL(L"another-real.png", profile0->IconPath());
|
||||
|
||||
auto profile1 = implementation::Profile::FromJson(profile1Json);
|
||||
VERIFY_IS_TRUE(profile1->Icon().empty());
|
||||
VERIFY_IS_TRUE(profile1->IconPath().empty());
|
||||
profile1->LayerJson(profile3Json);
|
||||
VERIFY_IS_FALSE(profile1->Icon().empty());
|
||||
VERIFY_ARE_EQUAL(L"another-real.png", profile1->Icon());
|
||||
VERIFY_IS_FALSE(profile1->IconPath().empty());
|
||||
VERIFY_ARE_EQUAL(L"another-real.png", profile1->IconPath());
|
||||
}
|
||||
|
||||
void ProfileTests::LayerProfilesOnArray()
|
||||
@@ -252,7 +253,7 @@ namespace SettingsModelLocalTests
|
||||
const auto profile3Json = VerifyParseSucceeded(profile3String);
|
||||
const auto profile4Json = VerifyParseSucceeded(profile4String);
|
||||
|
||||
auto settings = winrt::make_self<implementation::CascadiaSettings>();
|
||||
auto settings = winrt::make_self<winrt::TerminalApp::implementation::CascadiaSettings>();
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, settings->_profiles.Size());
|
||||
VERIFY_IS_NULL(settings->_FindMatchingProfile(profile0Json));
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,13 +7,13 @@
|
||||
#include "../TerminalApp/MinMaxCloseControl.h"
|
||||
#include "../TerminalApp/TabRowControl.h"
|
||||
#include "../TerminalApp/ShortcutActionDispatch.h"
|
||||
#include "../TerminalApp/TerminalTab.h"
|
||||
#include "../TerminalApp/Tab.h"
|
||||
#include "../CppWinrtTailored.h"
|
||||
#include "JsonTestClass.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
@@ -26,7 +26,7 @@ namespace TerminalAppLocalTests
|
||||
// an updated TAEF that will let us install framework packages when the test
|
||||
// package is deployed. Until then, these tests won't deploy in CI.
|
||||
|
||||
class TabTests
|
||||
class TabTests : public JsonTestClass
|
||||
{
|
||||
// For this set of tests, we need to activate some XAML content. For
|
||||
// release builds, the application runs as a centennial application,
|
||||
@@ -68,6 +68,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
InitializeJsonReader();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,7 +79,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
private:
|
||||
void _initializeTerminalPage(winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage>& page,
|
||||
CascadiaSettings initialSettings);
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::CascadiaSettings>& initialSettings);
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage> _commonSetup();
|
||||
};
|
||||
|
||||
@@ -194,7 +195,7 @@ namespace TerminalAppLocalTests
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabTests::_initializeTerminalPage(winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage>& page,
|
||||
CascadiaSettings initialSettings)
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::CascadiaSettings>& initialSettings)
|
||||
{
|
||||
// This is super wacky, but we can't just initialize the
|
||||
// com_ptr<impl::TerminalPage> in the lambda and assign it back out of
|
||||
@@ -210,7 +211,7 @@ namespace TerminalAppLocalTests
|
||||
auto result = RunOnUIThread([&projectedPage, &page, initialSettings]() {
|
||||
projectedPage = winrt::TerminalApp::TerminalPage();
|
||||
page.copy_from(winrt::get_self<winrt::TerminalApp::implementation::TerminalPage>(projectedPage));
|
||||
page->_settings = initialSettings;
|
||||
page->_settings = *initialSettings;
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
|
||||
@@ -250,8 +251,8 @@ namespace TerminalAppLocalTests
|
||||
// In the real app, this isn't a problem, but doesn't happen
|
||||
// reliably in the unit tests.
|
||||
Log::Comment(L"Ensure we set the first tab as the selected one.");
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
page->_tabView.SelectedItem(tab->TabViewItem());
|
||||
auto tab{ page->_GetStrongTabImpl(0) };
|
||||
page->_tabView.SelectedItem(tab->GetTabViewItem());
|
||||
page->_UpdatedSelectedTab(0);
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -280,8 +281,12 @@ namespace TerminalAppLocalTests
|
||||
]
|
||||
})" };
|
||||
|
||||
CascadiaSettings settings0{ til::u8u16(settingsJson0) };
|
||||
VerifyParseSucceeded(settingsJson0);
|
||||
auto settings0 = winrt::make_self<implementation::CascadiaSettings>(false);
|
||||
VERIFY_IS_NOT_NULL(settings0);
|
||||
settings0->_ParseJsonString(settingsJson0, false);
|
||||
settings0->LayerJson(settings0->_userSettings);
|
||||
settings0->_ValidateSettings();
|
||||
|
||||
// This is super wacky, but we can't just initialize the
|
||||
// com_ptr<impl::TerminalPage> in the lambda and assign it back out of
|
||||
@@ -338,11 +343,19 @@ namespace TerminalAppLocalTests
|
||||
]
|
||||
})" };
|
||||
|
||||
CascadiaSettings settings0{ til::u8u16(settingsJson0) };
|
||||
VerifyParseSucceeded(settingsJson0);
|
||||
auto settings0 = winrt::make_self<implementation::CascadiaSettings>(false);
|
||||
VERIFY_IS_NOT_NULL(settings0);
|
||||
settings0->_ParseJsonString(settingsJson0, false);
|
||||
settings0->LayerJson(settings0->_userSettings);
|
||||
settings0->_ValidateSettings();
|
||||
|
||||
CascadiaSettings settings1{ til::u8u16(settingsJson1) };
|
||||
VerifyParseSucceeded(settingsJson1);
|
||||
auto settings1 = winrt::make_self<implementation::CascadiaSettings>(false);
|
||||
VERIFY_IS_NOT_NULL(settings1);
|
||||
settings1->_ParseJsonString(settingsJson1, false);
|
||||
settings1->LayerJson(settings1->_userSettings);
|
||||
settings1->_ValidateSettings();
|
||||
|
||||
const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}");
|
||||
const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}");
|
||||
@@ -375,7 +388,7 @@ namespace TerminalAppLocalTests
|
||||
L"Change the settings of the TerminalPage so the first profile is "
|
||||
L"no longer in the list of profiles"));
|
||||
result = RunOnUIThread([&page, settings1]() {
|
||||
page->_settings = settings1;
|
||||
page->_settings = *settings1;
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
|
||||
@@ -425,11 +438,19 @@ namespace TerminalAppLocalTests
|
||||
]
|
||||
})" };
|
||||
|
||||
CascadiaSettings settings0{ til::u8u16(settingsJson0) };
|
||||
VerifyParseSucceeded(settingsJson0);
|
||||
auto settings0 = winrt::make_self<implementation::CascadiaSettings>(false);
|
||||
VERIFY_IS_NOT_NULL(settings0);
|
||||
settings0->_ParseJsonString(settingsJson0, false);
|
||||
settings0->LayerJson(settings0->_userSettings);
|
||||
settings0->_ValidateSettings();
|
||||
|
||||
CascadiaSettings settings1{ til::u8u16(settingsJson1) };
|
||||
VerifyParseSucceeded(settingsJson1);
|
||||
auto settings1 = winrt::make_self<implementation::CascadiaSettings>(false);
|
||||
VERIFY_IS_NOT_NULL(settings1);
|
||||
settings1->_ParseJsonString(settingsJson1, false);
|
||||
settings1->LayerJson(settings1->_userSettings);
|
||||
settings1->_ValidateSettings();
|
||||
|
||||
const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}");
|
||||
const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}");
|
||||
@@ -453,7 +474,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
result = RunOnUIThread([&page]() {
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetStrongTabImpl(0);
|
||||
VERIFY_ARE_EQUAL(1, tab->GetLeafPaneCount());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -463,7 +484,7 @@ namespace TerminalAppLocalTests
|
||||
page->_SplitPane(SplitState::Automatic, SplitType::Duplicate, nullptr);
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetStrongTabImpl(0);
|
||||
VERIFY_ARE_EQUAL(2, tab->GetLeafPaneCount());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -472,7 +493,7 @@ namespace TerminalAppLocalTests
|
||||
L"Change the settings of the TerminalPage so the first profile is "
|
||||
L"no longer in the list of profiles"));
|
||||
result = RunOnUIThread([&page, settings1]() {
|
||||
page->_settings = settings1;
|
||||
page->_settings = *settings1;
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
|
||||
@@ -481,7 +502,7 @@ namespace TerminalAppLocalTests
|
||||
page->_SplitPane(SplitState::Automatic, SplitType::Duplicate, nullptr);
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetStrongTabImpl(0);
|
||||
VERIFY_ARE_EQUAL(2,
|
||||
tab->GetLeafPaneCount(),
|
||||
L"We should gracefully do nothing here - the profile no longer exists.");
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="JsonTestClass.h" />
|
||||
<ClInclude Include="CppWinrtTailored.h" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -56,10 +57,19 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CommandlineTest.cpp" />
|
||||
<ClCompile Include="SettingsTests.cpp" />
|
||||
<ClCompile Include="ProfileTests.cpp" />
|
||||
<ClCompile Include="ColorSchemeTests.cpp" />
|
||||
<ClCompile Include="KeyBindingsTests.cpp" />
|
||||
<ClCompile Include="CommandTests.cpp" />
|
||||
<ClCompile Include="TabTests.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
|
||||
you want to use jsoncpp -->
|
||||
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Project References ======================== -->
|
||||
@@ -69,11 +79,9 @@
|
||||
|
||||
<!-- If you don't reference these projects here, the
|
||||
_ConsoleGenerateAdditionalWinmdManifests step won't gather the winmd's -->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalApp\dll\TerminalApp.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\dll\TerminalApp.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Globals ======================== -->
|
||||
|
||||
@@ -94,18 +94,12 @@
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj">
|
||||
<Project>{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\dll\TerminalApp.vcxproj">
|
||||
<Project>{ca5cad1a-44bd-4ac7-ac72-f16e576fdd12}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj">
|
||||
<Project>{CA5CAD1A-082C-4476-9F33-94B339494076}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -159,10 +153,6 @@
|
||||
<Copy SourceFiles="$(_TestBinRoot)\LocalTests_TerminalApp\TerminalApp.LocalTests.dll"
|
||||
DestinationFiles="$(TargetDir)\TerminalApp.LocalTests.dll" />
|
||||
|
||||
<!-- Copy our test code from LocalTests_TerminalApp into this directory -->
|
||||
<Copy SourceFiles="$(_TestBinRoot)\LocalTests_SettingsModel\SettingsModel.LocalTests.dll"
|
||||
DestinationFiles="$(TargetDir)\SettingsModel.LocalTests.dll" />
|
||||
|
||||
<!-- Copy some dlls which TerminalConnection is dependent upon that didn't
|
||||
get rolled up into this directory -->
|
||||
<Copy SourceFiles="@(TerminalConnectionDlls)"
|
||||
|
||||
@@ -12,7 +12,7 @@ Author(s):
|
||||
Mike Griese (migrie) December-2019
|
||||
--*/
|
||||
|
||||
class TestUtils
|
||||
class TerminalAppLocalTests::TestUtils
|
||||
{
|
||||
public:
|
||||
// Function Description:
|
||||
@@ -23,8 +23,8 @@ public:
|
||||
// - kc: The key chord to look up the bound ActionAndArgs for.
|
||||
// Return Value:
|
||||
// - The ActionAndArgs bound to the given key, or nullptr if nothing is bound to it.
|
||||
static const winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs GetActionAndArgs(const winrt::Microsoft::Terminal::Settings::Model::KeyMapping& keymap,
|
||||
const winrt::Microsoft::Terminal::TerminalControl::KeyChord& kc)
|
||||
static const winrt::TerminalApp::ActionAndArgs GetActionAndArgs(const winrt::TerminalApp::implementation::KeyMapping& keymap,
|
||||
const winrt::Microsoft::Terminal::TerminalControl::KeyChord& kc)
|
||||
{
|
||||
std::wstring buffer{ L"" };
|
||||
if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::TerminalControl::KeyModifiers::Ctrl))
|
||||
@@ -54,7 +54,6 @@ Author(s):
|
||||
#include <winrt/windows.applicationmodel.core.h>
|
||||
|
||||
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
|
||||
#include <winrt/Microsoft.Terminal.Settings.Model.h>
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
|
||||
|
||||
@@ -185,12 +185,17 @@ HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/,
|
||||
|
||||
HRESULT OpenTerminalHere::GetIcon(IShellItemArray* /*psiItemArray*/,
|
||||
LPWSTR* ppszIcon)
|
||||
try
|
||||
{
|
||||
// the icon ref ("dll,-<resid>") is provided here, in this case none is provided
|
||||
*ppszIcon = nullptr;
|
||||
// TODO GH#6111: Return the Terminal icon here
|
||||
return E_NOTIMPL;
|
||||
std::filesystem::path modulePath{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
|
||||
modulePath.replace_filename(WindowsTerminalExe);
|
||||
// WindowsTerminal.exe,-101 will be the first icon group in WT
|
||||
// We're using WindowsTerminal here explicitly, and not wt (from _getExePath), because
|
||||
// WindowsTerminal is the only one built with the right icons.
|
||||
const auto resource{ modulePath.wstring() + L",-101" };
|
||||
return SHStrDupW(resource.c_str(), ppszIcon);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
HRESULT OpenTerminalHere::GetFlags(EXPCMDFLAGS* pFlags)
|
||||
{
|
||||
|
||||
@@ -51,9 +51,9 @@ static constexpr std::string_view ActionKey{ "action" };
|
||||
// This key is reserved to remove a keybinding, instead of mapping it to an action.
|
||||
static constexpr std::string_view UnboundKey{ "unbound" };
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::TerminalApp;
|
||||
|
||||
// Specifically use a map here over an unordered_map. We want to be able to
|
||||
// iterate over these entries in-order when we're serializing the keybindings.
|
||||
@@ -105,7 +105,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ UnboundKey, ShortcutAction::Invalid },
|
||||
};
|
||||
|
||||
using ParseResult = std::tuple<IActionArgs, std::vector<SettingsLoadWarnings>>;
|
||||
using ParseResult = std::tuple<IActionArgs, std::vector<TerminalApp::SettingsLoadWarnings>>;
|
||||
using ParseActionFunction = std::function<ParseResult(const Json::Value&)>;
|
||||
|
||||
// This is a map of ShortcutAction->function<IActionArgs(Json::Value)>. It holds
|
||||
@@ -169,7 +169,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// - a deserialized ActionAndArgs corresponding to the values in json, or
|
||||
// null if we failed to deserialize an action.
|
||||
winrt::com_ptr<ActionAndArgs> ActionAndArgs::FromJson(const Json::Value& json,
|
||||
std::vector<SettingsLoadWarnings>& warnings)
|
||||
std::vector<TerminalApp::SettingsLoadWarnings>& warnings)
|
||||
{
|
||||
// Invalid is our placeholder that the action was not parsed.
|
||||
ShortcutAction action = ShortcutAction::Invalid;
|
||||
@@ -208,7 +208,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// does, we'll try to deserialize any "args" that were provided with
|
||||
// the binding.
|
||||
IActionArgs args{ nullptr };
|
||||
std::vector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> parseWarnings;
|
||||
std::vector<TerminalApp::SettingsLoadWarnings> parseWarnings;
|
||||
const auto deserializersIter = argParsers.find(action);
|
||||
if (deserializersIter != argParsers.end())
|
||||
{
|
||||
@@ -240,14 +240,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
}
|
||||
}
|
||||
|
||||
com_ptr<ActionAndArgs> ActionAndArgs::Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<ActionAndArgs>() };
|
||||
copy->_Action = _Action;
|
||||
copy->_Args = _Args.Copy();
|
||||
return copy;
|
||||
}
|
||||
|
||||
winrt::hstring ActionAndArgs::GenerateName() const
|
||||
{
|
||||
// Use a magic static to initialize this map, because we won't be able
|
||||
@@ -1,34 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ActionAndArgs.g.h"
|
||||
#include "TerminalWarnings.h"
|
||||
#include "..\inc\cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct ActionAndArgs : public ActionAndArgsT<ActionAndArgs>
|
||||
{
|
||||
static const std::map<std::string_view, ShortcutAction, std::less<>> ActionKeyNamesMap;
|
||||
static winrt::com_ptr<ActionAndArgs> FromJson(const Json::Value& json,
|
||||
std::vector<SettingsLoadWarnings>& warnings);
|
||||
std::vector<TerminalApp::SettingsLoadWarnings>& warnings);
|
||||
|
||||
ActionAndArgs() = default;
|
||||
ActionAndArgs(ShortcutAction action, IActionArgs args) :
|
||||
_Action{ action },
|
||||
_Args{ args } {};
|
||||
com_ptr<ActionAndArgs> Copy() const;
|
||||
|
||||
hstring GenerateName() const;
|
||||
|
||||
GETSET_PROPERTY(ShortcutAction, Action, ShortcutAction::Invalid);
|
||||
GETSET_PROPERTY(TerminalApp::ShortcutAction, Action, TerminalApp::ShortcutAction::Invalid);
|
||||
GETSET_PROPERTY(IActionArgs, Args, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ActionAndArgs);
|
||||
}
|
||||
@@ -20,14 +20,14 @@
|
||||
#include "SetTabColorArgs.g.cpp"
|
||||
#include "RenameTabArgs.g.cpp"
|
||||
#include "ExecuteCommandlineArgs.g.cpp"
|
||||
#include "CloseOtherTabsArgs.g.cpp"
|
||||
#include "CloseTabsAfterArgs.g.cpp"
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
winrt::hstring NewTerminalArgs::GenerateName() const
|
||||
{
|
||||
@@ -212,7 +212,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// The string will be similar to the following:
|
||||
// * "Send Input: ...input..."
|
||||
|
||||
auto escapedInput = til::visualize_control_codes(_Input);
|
||||
auto escapedInput = VisualizeControlCodes(_Input);
|
||||
auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput);
|
||||
return winrt::hstring{ name };
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "CloseTabsAfterArgs.g.h"
|
||||
|
||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||
#include "Utils.h"
|
||||
#include "JsonUtils.h"
|
||||
#include "TerminalWarnings.h"
|
||||
|
||||
@@ -35,16 +36,16 @@
|
||||
// * ActionEventArgs holds a single IActionArgs. For events that don't need
|
||||
// additional args, this can be nullptr.
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
using FromJsonResult = std::tuple<Model::IActionArgs, std::vector<SettingsLoadWarnings>>;
|
||||
using namespace ::TerminalApp;
|
||||
using FromJsonResult = std::tuple<winrt::TerminalApp::IActionArgs, std::vector<TerminalApp::SettingsLoadWarnings>>;
|
||||
|
||||
struct ActionEventArgs : public ActionEventArgsT<ActionEventArgs>
|
||||
{
|
||||
ActionEventArgs() = default;
|
||||
|
||||
explicit ActionEventArgs(const Model::IActionArgs& args) :
|
||||
explicit ActionEventArgs(const TerminalApp::IActionArgs& args) :
|
||||
_ActionArgs{ args } {};
|
||||
GETSET_PROPERTY(IActionArgs, ActionArgs, nullptr);
|
||||
GETSET_PROPERTY(bool, Handled, false);
|
||||
@@ -53,8 +54,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
struct NewTerminalArgs : public NewTerminalArgsT<NewTerminalArgs>
|
||||
{
|
||||
NewTerminalArgs() = default;
|
||||
NewTerminalArgs(int32_t& profileIndex) :
|
||||
_ProfileIndex{ profileIndex } {};
|
||||
GETSET_PROPERTY(winrt::hstring, Commandline, L"");
|
||||
GETSET_PROPERTY(winrt::hstring, StartingDirectory, L"");
|
||||
GETSET_PROPERTY(winrt::hstring, TabTitle, L"");
|
||||
@@ -70,7 +69,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
public:
|
||||
hstring GenerateName() const;
|
||||
|
||||
bool Equals(const Model::NewTerminalArgs& other)
|
||||
bool Equals(const winrt::TerminalApp::NewTerminalArgs& other)
|
||||
{
|
||||
return other.Commandline() == _Commandline &&
|
||||
other.StartingDirectory() == _StartingDirectory &&
|
||||
@@ -78,7 +77,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
other.ProfileIndex() == _ProfileIndex &&
|
||||
other.Profile() == _Profile;
|
||||
};
|
||||
static Model::NewTerminalArgs FromJson(const Json::Value& json)
|
||||
static winrt::TerminalApp::NewTerminalArgs FromJson(const Json::Value& json)
|
||||
{
|
||||
// LOAD BEARING: Not using make_self here _will_ break you in the future!
|
||||
auto args = winrt::make_self<NewTerminalArgs>();
|
||||
@@ -89,23 +88,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, ProfileKey, args->_Profile);
|
||||
return *args;
|
||||
}
|
||||
Model::NewTerminalArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<NewTerminalArgs>() };
|
||||
copy->_Commandline = _Commandline;
|
||||
copy->_StartingDirectory = _StartingDirectory;
|
||||
copy->_TabTitle = _TabTitle;
|
||||
copy->_ProfileIndex = _ProfileIndex;
|
||||
copy->_Profile = _Profile;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct CopyTextArgs : public CopyTextArgsT<CopyTextArgs>
|
||||
{
|
||||
CopyTextArgs() = default;
|
||||
GETSET_PROPERTY(bool, SingleLine, false);
|
||||
GETSET_PROPERTY(Windows::Foundation::IReference<TerminalControl::CopyFormat>, CopyFormatting, nullptr);
|
||||
GETSET_PROPERTY(Windows::Foundation::IReference<Microsoft::Terminal::TerminalControl::CopyFormat>, CopyFormatting, nullptr);
|
||||
|
||||
static constexpr std::string_view SingleLineKey{ "singleLine" };
|
||||
static constexpr std::string_view CopyFormattingKey{ "copyFormatting" };
|
||||
@@ -131,22 +120,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, CopyFormattingKey, args->_CopyFormatting);
|
||||
return { *args, {} };
|
||||
}
|
||||
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<CopyTextArgs>() };
|
||||
copy->_SingleLine = _SingleLine;
|
||||
copy->_CopyFormatting = _CopyFormatting;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct NewTabArgs : public NewTabArgsT<NewTabArgs>
|
||||
{
|
||||
NewTabArgs() = default;
|
||||
NewTabArgs(const Model::NewTerminalArgs& terminalArgs) :
|
||||
_TerminalArgs{ terminalArgs } {};
|
||||
GETSET_PROPERTY(Model::NewTerminalArgs, TerminalArgs, nullptr);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::NewTerminalArgs, TerminalArgs, nullptr);
|
||||
|
||||
public:
|
||||
hstring GenerateName() const;
|
||||
@@ -167,19 +146,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
args->_TerminalArgs = NewTerminalArgs::FromJson(json);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<NewTabArgs>() };
|
||||
copy->_TerminalArgs = _TerminalArgs.Copy();
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct SwitchToTabArgs : public SwitchToTabArgsT<SwitchToTabArgs>
|
||||
{
|
||||
SwitchToTabArgs() = default;
|
||||
SwitchToTabArgs(uint32_t& tabIndex) :
|
||||
_TabIndex{ tabIndex } {};
|
||||
GETSET_PROPERTY(uint32_t, TabIndex, 0);
|
||||
|
||||
static constexpr std::string_view TabIndexKey{ "index" };
|
||||
@@ -203,18 +174,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, TabIndexKey, args->_TabIndex);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<SwitchToTabArgs>() };
|
||||
copy->_TabIndex = _TabIndex;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct ResizePaneArgs : public ResizePaneArgsT<ResizePaneArgs>
|
||||
{
|
||||
ResizePaneArgs() = default;
|
||||
GETSET_PROPERTY(Model::Direction, Direction, Direction::None);
|
||||
GETSET_PROPERTY(TerminalApp::Direction, Direction, TerminalApp::Direction::None);
|
||||
|
||||
static constexpr std::string_view DirectionKey{ "direction" };
|
||||
|
||||
@@ -235,30 +200,24 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// LOAD BEARING: Not using make_self here _will_ break you in the future!
|
||||
auto args = winrt::make_self<ResizePaneArgs>();
|
||||
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
|
||||
if (args->_Direction == Direction::None)
|
||||
if (args->_Direction == TerminalApp::Direction::None)
|
||||
{
|
||||
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
return { nullptr, { TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
}
|
||||
else
|
||||
{
|
||||
return { *args, {} };
|
||||
}
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<ResizePaneArgs>() };
|
||||
copy->_Direction = _Direction;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct MoveFocusArgs : public MoveFocusArgsT<MoveFocusArgs>
|
||||
{
|
||||
MoveFocusArgs() = default;
|
||||
MoveFocusArgs(Model::Direction direction) :
|
||||
MoveFocusArgs(TerminalApp::Direction direction) :
|
||||
_Direction{ direction } {};
|
||||
|
||||
GETSET_PROPERTY(Model::Direction, Direction, Direction::None);
|
||||
GETSET_PROPERTY(TerminalApp::Direction, Direction, TerminalApp::Direction::None);
|
||||
|
||||
static constexpr std::string_view DirectionKey{ "direction" };
|
||||
|
||||
@@ -279,21 +238,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// LOAD BEARING: Not using make_self here _will_ break you in the future!
|
||||
auto args = winrt::make_self<MoveFocusArgs>();
|
||||
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
|
||||
if (args->_Direction == Direction::None)
|
||||
if (args->_Direction == TerminalApp::Direction::None)
|
||||
{
|
||||
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
return { nullptr, { TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
}
|
||||
else
|
||||
{
|
||||
return { *args, {} };
|
||||
}
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<MoveFocusArgs>() };
|
||||
copy->_Direction = _Direction;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct AdjustFontSizeArgs : public AdjustFontSizeArgsT<AdjustFontSizeArgs>
|
||||
@@ -322,12 +275,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, AdjustFontSizeDelta, args->_Delta);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<AdjustFontSizeArgs>() };
|
||||
copy->_Delta = _Delta;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct SendInputArgs : public SendInputArgsT<SendInputArgs>
|
||||
@@ -355,29 +302,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, InputKey, args->_Input);
|
||||
if (args->_Input.empty())
|
||||
{
|
||||
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
return { nullptr, { TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
}
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<SendInputArgs>() };
|
||||
copy->_Input = _Input;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct SplitPaneArgs : public SplitPaneArgsT<SplitPaneArgs>
|
||||
{
|
||||
SplitPaneArgs() = default;
|
||||
SplitPaneArgs(SplitState style, const Model::NewTerminalArgs& terminalArgs) :
|
||||
SplitPaneArgs(winrt::TerminalApp::SplitState style, const winrt::TerminalApp::NewTerminalArgs& terminalArgs) :
|
||||
_SplitStyle{ style },
|
||||
_TerminalArgs{ terminalArgs } {};
|
||||
SplitPaneArgs(SplitType splitMode) :
|
||||
_SplitMode{ splitMode } {};
|
||||
GETSET_PROPERTY(SplitState, SplitStyle, SplitState::Automatic);
|
||||
GETSET_PROPERTY(Model::NewTerminalArgs, TerminalArgs, nullptr);
|
||||
GETSET_PROPERTY(SplitType, SplitMode, SplitType::Manual);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::SplitState, SplitStyle, winrt::TerminalApp::SplitState::Automatic);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::NewTerminalArgs, TerminalArgs, nullptr);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::SplitType, SplitMode, winrt::TerminalApp::SplitType::Manual);
|
||||
|
||||
static constexpr std::string_view SplitKey{ "split" };
|
||||
static constexpr std::string_view SplitModeKey{ "splitMode" };
|
||||
@@ -406,20 +347,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, SplitModeKey, args->_SplitMode);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<SplitPaneArgs>() };
|
||||
copy->_SplitStyle = _SplitStyle;
|
||||
copy->_TerminalArgs = _TerminalArgs.Copy();
|
||||
copy->_SplitMode = _SplitMode;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct OpenSettingsArgs : public OpenSettingsArgsT<OpenSettingsArgs>
|
||||
{
|
||||
OpenSettingsArgs() = default;
|
||||
GETSET_PROPERTY(SettingsTarget, Target, SettingsTarget::SettingsFile);
|
||||
GETSET_PROPERTY(TerminalApp::SettingsTarget, Target, TerminalApp::SettingsTarget::SettingsFile);
|
||||
|
||||
static constexpr std::string_view TargetKey{ "target" };
|
||||
|
||||
@@ -442,12 +375,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, TargetKey, args->_Target);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<OpenSettingsArgs>() };
|
||||
copy->_Target = _Target;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetColorSchemeArgs : public SetColorSchemeArgsT<SetColorSchemeArgs>
|
||||
@@ -476,16 +403,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, NameKey, args->_SchemeName);
|
||||
if (args->_SchemeName.empty())
|
||||
{
|
||||
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
return { nullptr, { TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
}
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<SetColorSchemeArgs>() };
|
||||
copy->_SchemeName = _SchemeName;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetTabColorArgs : public SetTabColorArgsT<SetTabColorArgs>
|
||||
@@ -517,12 +438,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
}
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<SetTabColorArgs>() };
|
||||
copy->_TabColor = _TabColor;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct RenameTabArgs : public RenameTabArgsT<RenameTabArgs>
|
||||
@@ -551,19 +466,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, TitleKey, args->_Title);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<RenameTabArgs>() };
|
||||
copy->_Title = _Title;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExecuteCommandlineArgs : public ExecuteCommandlineArgsT<ExecuteCommandlineArgs>
|
||||
{
|
||||
ExecuteCommandlineArgs() = default;
|
||||
ExecuteCommandlineArgs(winrt::hstring commandline) :
|
||||
_Commandline{ commandline } {};
|
||||
GETSET_PROPERTY(winrt::hstring, Commandline, L"");
|
||||
|
||||
static constexpr std::string_view CommandlineKey{ "commandline" };
|
||||
@@ -587,24 +494,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, CommandlineKey, args->_Commandline);
|
||||
if (args->_Commandline.empty())
|
||||
{
|
||||
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
return { nullptr, { TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
|
||||
}
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<ExecuteCommandlineArgs>() };
|
||||
copy->_Commandline = _Commandline;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct CloseOtherTabsArgs : public CloseOtherTabsArgsT<CloseOtherTabsArgs>
|
||||
{
|
||||
CloseOtherTabsArgs() = default;
|
||||
CloseOtherTabsArgs(uint32_t& tabIndex) :
|
||||
_Index{ tabIndex } {};
|
||||
GETSET_PROPERTY(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
|
||||
GETSET_PROPERTY(winrt::Windows::Foundation::IReference<uint32_t>, Index, nullptr);
|
||||
|
||||
static constexpr std::string_view IndexKey{ "index" };
|
||||
|
||||
@@ -627,20 +526,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, IndexKey, args->_Index);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<CloseOtherTabsArgs>() };
|
||||
copy->_Index = _Index;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
|
||||
struct CloseTabsAfterArgs : public CloseTabsAfterArgsT<CloseTabsAfterArgs>
|
||||
{
|
||||
CloseTabsAfterArgs() = default;
|
||||
CloseTabsAfterArgs(uint32_t& tabIndex) :
|
||||
_Index{ tabIndex } {};
|
||||
GETSET_PROPERTY(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
|
||||
GETSET_PROPERTY(winrt::Windows::Foundation::IReference<uint32_t>, Index, nullptr);
|
||||
|
||||
static constexpr std::string_view IndexKey{ "index" };
|
||||
|
||||
@@ -663,24 +554,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
JsonUtils::GetValueForKey(json, IndexKey, args->_Index);
|
||||
return { *args, {} };
|
||||
}
|
||||
IActionArgs Copy() const
|
||||
{
|
||||
auto copy{ winrt::make_self<CloseTabsAfterArgs>() };
|
||||
copy->_Index = _Index;
|
||||
return *copy;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ActionEventArgs);
|
||||
BASIC_FACTORY(SwitchToTabArgs);
|
||||
BASIC_FACTORY(NewTerminalArgs);
|
||||
BASIC_FACTORY(NewTabArgs);
|
||||
BASIC_FACTORY(MoveFocusArgs);
|
||||
BASIC_FACTORY(SplitPaneArgs);
|
||||
BASIC_FACTORY(ExecuteCommandlineArgs);
|
||||
BASIC_FACTORY(CloseOtherTabsArgs);
|
||||
BASIC_FACTORY(CloseTabsAfterArgs);
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
interface IActionArgs
|
||||
{
|
||||
Boolean Equals(IActionArgs other);
|
||||
String GenerateName();
|
||||
IActionArgs Copy();
|
||||
};
|
||||
|
||||
interface IActionEventArgs
|
||||
@@ -43,15 +42,11 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
{
|
||||
SettingsFile = 0,
|
||||
DefaultsFile,
|
||||
AllFiles,
|
||||
SettingsUI
|
||||
AllFiles
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass NewTerminalArgs {
|
||||
NewTerminalArgs();
|
||||
NewTerminalArgs(Int32 profileIndex);
|
||||
NewTerminalArgs Copy();
|
||||
|
||||
String Commandline;
|
||||
String StartingDirectory;
|
||||
String TabTitle;
|
||||
@@ -66,7 +61,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
[default_interface] runtimeclass ActionEventArgs : IActionEventArgs
|
||||
{
|
||||
ActionEventArgs();
|
||||
ActionEventArgs(IActionArgs args);
|
||||
};
|
||||
|
||||
@@ -78,14 +72,12 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
[default_interface] runtimeclass NewTabArgs : IActionArgs
|
||||
{
|
||||
NewTabArgs(NewTerminalArgs terminalArgs);
|
||||
NewTerminalArgs TerminalArgs { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SwitchToTabArgs : IActionArgs
|
||||
{
|
||||
SwitchToTabArgs(UInt32 tabIndex);
|
||||
UInt32 TabIndex;
|
||||
UInt32 TabIndex { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass ResizePaneArgs : IActionArgs
|
||||
@@ -141,19 +133,16 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
[default_interface] runtimeclass ExecuteCommandlineArgs : IActionArgs
|
||||
{
|
||||
ExecuteCommandlineArgs(String commandline);
|
||||
String Commandline;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass CloseOtherTabsArgs : IActionArgs
|
||||
{
|
||||
CloseOtherTabsArgs(UInt32 tabIndex);
|
||||
Windows.Foundation.IReference<UInt32> Index { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass CloseTabsAfterArgs : IActionArgs
|
||||
{
|
||||
CloseTabsAfterArgs(UInt32 tabIndex);
|
||||
Windows.Foundation.IReference<UInt32> Index { get; };
|
||||
};
|
||||
}
|
||||
@@ -14,7 +14,6 @@ using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace ::TerminalApp;
|
||||
@@ -28,76 +27,76 @@ namespace winrt
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
void TerminalPage::_HandleOpenNewTabDropdown(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_OpenNewTabDropdown();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleDuplicateTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_DuplicateTabViewItem();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleCloseTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_CloseFocusedTab();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleClosePane(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_CloseFocusedPane();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleCloseWindow(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
CloseWindow();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleScrollUp(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_Scroll(-1);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleScrollDown(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_Scroll(1);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleNextTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_SelectNextTab(true);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandlePrevTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_SelectNextTab(false);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSendInput(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (args == nullptr)
|
||||
{
|
||||
args.Handled(false);
|
||||
}
|
||||
else if (const auto& realArgs = args.ActionArgs().try_as<SendInputArgs>())
|
||||
else if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SendInputArgs>())
|
||||
{
|
||||
const auto termControl = _GetActiveControl();
|
||||
termControl.SendInput(realArgs.Input());
|
||||
@@ -106,13 +105,13 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSplitPane(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (args == nullptr)
|
||||
{
|
||||
args.Handled(false);
|
||||
}
|
||||
else if (const auto& realArgs = args.ActionArgs().try_as<SplitPaneArgs>())
|
||||
else if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SplitPaneArgs>())
|
||||
{
|
||||
_SplitPane(realArgs.SplitStyle(), realArgs.SplitMode(), realArgs.TerminalArgs());
|
||||
args.Handled(true);
|
||||
@@ -120,49 +119,44 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleTogglePaneZoom(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (auto focusedTab = _GetFocusedTab())
|
||||
auto activeTab = _GetFocusedTab();
|
||||
|
||||
// Don't do anything if there's only one pane. It's already zoomed.
|
||||
if (activeTab && activeTab->GetLeafPaneCount() > 1)
|
||||
{
|
||||
if (auto activeTab = _GetTerminalTabImpl(focusedTab))
|
||||
{
|
||||
// Don't do anything if there's only one pane. It's already zoomed.
|
||||
if (activeTab && activeTab->GetLeafPaneCount() > 1)
|
||||
{
|
||||
// First thing's first, remove the current content from the UI
|
||||
// tree. This is important, because we might be leaving zoom, and if
|
||||
// a pane is zoomed, then it's currently in the UI tree, and should
|
||||
// be removed before it's re-added in Pane::Restore
|
||||
_tabContent.Children().Clear();
|
||||
// First thing's first, remove the current content from the UI
|
||||
// tree. This is important, because we might be leaving zoom, and if
|
||||
// a pane is zoomed, then it's currently in the UI tree, and should
|
||||
// be removed before it's re-added in Pane::Restore
|
||||
_tabContent.Children().Clear();
|
||||
|
||||
// Togging the zoom on the tab will cause the tab to inform us of
|
||||
// the new root Content for this tab.
|
||||
activeTab->ToggleZoom();
|
||||
}
|
||||
}
|
||||
// Togging the zoom on the tab will cause the tab to inform us of
|
||||
// the new root Content for this tab.
|
||||
activeTab->ToggleZoom();
|
||||
}
|
||||
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleScrollUpPage(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_ScrollPage(-1);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleScrollDownPage(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_ScrollPage(1);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenSettings(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<OpenSettingsArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::OpenSettingsArgs>())
|
||||
{
|
||||
_LaunchSettings(realArgs.Target());
|
||||
args.Handled(true);
|
||||
@@ -170,21 +164,21 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandlePasteText(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_PasteText();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleNewTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (args == nullptr)
|
||||
{
|
||||
_OpenNewTab(nullptr);
|
||||
args.Handled(true);
|
||||
}
|
||||
else if (const auto& realArgs = args.ActionArgs().try_as<NewTabArgs>())
|
||||
else if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::NewTabArgs>())
|
||||
{
|
||||
_OpenNewTab(realArgs.TerminalArgs());
|
||||
args.Handled(true);
|
||||
@@ -192,9 +186,9 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSwitchToTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SwitchToTabArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SwitchToTabArgs>())
|
||||
{
|
||||
const auto handled = _SelectTab({ realArgs.TabIndex() });
|
||||
args.Handled(handled);
|
||||
@@ -202,11 +196,11 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleResizePane(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<ResizePaneArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::ResizePaneArgs>())
|
||||
{
|
||||
if (realArgs.Direction() == Direction::None)
|
||||
if (realArgs.Direction() == TerminalApp::Direction::None)
|
||||
{
|
||||
// Do nothing
|
||||
args.Handled(false);
|
||||
@@ -220,11 +214,11 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleMoveFocus(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<MoveFocusArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::MoveFocusArgs>())
|
||||
{
|
||||
if (realArgs.Direction() == Direction::None)
|
||||
if (realArgs.Direction() == TerminalApp::Direction::None)
|
||||
{
|
||||
// Do nothing
|
||||
args.Handled(false);
|
||||
@@ -238,9 +232,9 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleCopyText(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::CopyTextArgs>())
|
||||
{
|
||||
const auto handled = _CopyText(realArgs.SingleLine(), realArgs.CopyFormatting());
|
||||
args.Handled(handled);
|
||||
@@ -248,9 +242,9 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleAdjustFontSize(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<AdjustFontSizeArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::AdjustFontSizeArgs>())
|
||||
{
|
||||
const auto termControl = _GetActiveControl();
|
||||
termControl.AdjustFontSize(realArgs.Delta());
|
||||
@@ -259,14 +253,14 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleFind(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_Find();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleResetFontSize(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
const auto termControl = _GetActiveControl();
|
||||
termControl.ResetFontSize();
|
||||
@@ -274,7 +268,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleRetroEffect(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
const auto termControl = _GetActiveControl();
|
||||
termControl.ToggleRetroEffect();
|
||||
@@ -282,28 +276,28 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleFocusMode(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
ToggleFocusMode();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
ToggleFullscreen();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleAlwaysOnTop(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
ToggleAlwaysOnTop();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleCommandPalette(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
// TODO GH#6677: When we add support for commandline mode, first set the
|
||||
// mode that the command palette should be in, before making it visible.
|
||||
@@ -315,24 +309,21 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSetColorScheme(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
args.Handled(false);
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SetColorSchemeArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SetColorSchemeArgs>())
|
||||
{
|
||||
if (auto focusedTab = _GetFocusedTab())
|
||||
if (auto activeTab = _GetFocusedTab())
|
||||
{
|
||||
if (auto activeTab = _GetTerminalTabImpl(focusedTab))
|
||||
if (auto activeControl = activeTab->GetActiveTerminalControl())
|
||||
{
|
||||
if (auto activeControl = activeTab->GetActiveTerminalControl())
|
||||
if (const auto scheme = _settings.GlobalSettings().ColorSchemes().TryLookup(realArgs.SchemeName()))
|
||||
{
|
||||
if (const auto scheme = _settings.GlobalSettings().ColorSchemes().TryLookup(realArgs.SchemeName()))
|
||||
{
|
||||
auto controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
controlSettings->ApplyColorScheme(scheme);
|
||||
activeControl.UpdateSettings(*controlSettings);
|
||||
args.Handled(true);
|
||||
}
|
||||
auto controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
controlSettings->ApplyColorScheme(scheme);
|
||||
activeControl.UpdateSettings(*controlSettings);
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -340,11 +331,11 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSetTabColor(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
std::optional<til::color> tabColor;
|
||||
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SetTabColorArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SetTabColorArgs>())
|
||||
{
|
||||
if (realArgs.TabColor() != nullptr)
|
||||
{
|
||||
@@ -352,69 +343,63 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
if (auto focusedTab = _GetFocusedTab())
|
||||
auto activeTab = _GetFocusedTab();
|
||||
if (activeTab)
|
||||
{
|
||||
if (auto activeTab = _GetTerminalTabImpl(focusedTab))
|
||||
if (tabColor.has_value())
|
||||
{
|
||||
if (tabColor.has_value())
|
||||
{
|
||||
activeTab->SetRuntimeTabColor(tabColor.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
activeTab->ResetRuntimeTabColor();
|
||||
}
|
||||
activeTab->SetRuntimeTabColor(tabColor.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
activeTab->ResetRuntimeTabColor();
|
||||
}
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenTabColorPicker(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
if (auto focusedTab = _GetFocusedTab())
|
||||
auto activeTab = _GetFocusedTab();
|
||||
if (activeTab)
|
||||
{
|
||||
if (auto activeTab = _GetTerminalTabImpl(focusedTab))
|
||||
{
|
||||
activeTab->ActivateColorPicker();
|
||||
}
|
||||
activeTab->ActivateColorPicker();
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleRenameTab(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
std::optional<winrt::hstring> title;
|
||||
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<RenameTabArgs>())
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::RenameTabArgs>())
|
||||
{
|
||||
title = realArgs.Title();
|
||||
}
|
||||
|
||||
if (auto focusedTab = _GetFocusedTab())
|
||||
auto activeTab = _GetFocusedTab();
|
||||
if (activeTab)
|
||||
{
|
||||
if (auto activeTab = _GetTerminalTabImpl(focusedTab))
|
||||
if (title.has_value())
|
||||
{
|
||||
if (title.has_value())
|
||||
{
|
||||
activeTab->SetTabText(title.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
activeTab->ResetTabText();
|
||||
}
|
||||
activeTab->SetTabText(title.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
activeTab->ResetTabText();
|
||||
}
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleExecuteCommandline(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& actionArgs)
|
||||
const TerminalApp::ActionEventArgs& actionArgs)
|
||||
{
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<ExecuteCommandlineArgs>())
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<TerminalApp::ExecuteCommandlineArgs>())
|
||||
{
|
||||
auto actions = winrt::single_threaded_vector<ActionAndArgs>(std::move(
|
||||
auto actions = winrt::single_threaded_vector<winrt::TerminalApp::ActionAndArgs>(std::move(
|
||||
TerminalPage::ConvertExecuteCommandlineToActions(realArgs)));
|
||||
|
||||
if (_startupActions.Size() != 0)
|
||||
@@ -426,9 +411,9 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleCloseOtherTabs(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& actionArgs)
|
||||
const TerminalApp::ActionEventArgs& actionArgs)
|
||||
{
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<CloseOtherTabsArgs>())
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<TerminalApp::CloseOtherTabsArgs>())
|
||||
{
|
||||
uint32_t index;
|
||||
if (realArgs.Index())
|
||||
@@ -463,9 +448,9 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleCloseTabsAfter(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& actionArgs)
|
||||
const TerminalApp::ActionEventArgs& actionArgs)
|
||||
{
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<CloseTabsAfterArgs>())
|
||||
if (const auto& realArgs = actionArgs.ActionArgs().try_as<TerminalApp::CloseTabsAfterArgs>())
|
||||
{
|
||||
uint32_t index;
|
||||
if (realArgs.Index())
|
||||
@@ -500,10 +485,10 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenTabSearch(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
// Tab search is always in-order.
|
||||
auto tabCommands = winrt::single_threaded_vector<Command>();
|
||||
auto tabCommands = winrt::single_threaded_vector<TerminalApp::Command>();
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
tabCommands.Append(tab.SwitchToTabCommand());
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
#include "pch.h"
|
||||
#include "AppLogic.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "ActionArgs.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace TerminalApp;
|
||||
|
||||
// Either a ; at the start of a line, or a ; preceded by any non-\ char.
|
||||
@@ -159,42 +159,33 @@ void AppCommandlineArgs::_buildParser()
|
||||
{
|
||||
// -v,--version: Displays version info
|
||||
auto versionCallback = [this](int64_t /*count*/) {
|
||||
// Set our message to display the application name and the current version.
|
||||
_exitMessage = fmt::format("{0}\n{1}",
|
||||
til::u16u8(CascadiaSettings::ApplicationDisplayName()),
|
||||
til::u16u8(CascadiaSettings::ApplicationVersion()));
|
||||
// Theoretically, we don't need to exit now, since this isn't really
|
||||
// an error case. However, in practice, it feels weird to have `wt
|
||||
// -v` open a new tab, and makes enough sense that `wt -v ;
|
||||
// split-pane` (or whatever) just displays the version and exits.
|
||||
_shouldExitEarly = true;
|
||||
if (const auto appLogic{ winrt::TerminalApp::implementation::AppLogic::Current() })
|
||||
{
|
||||
// Set our message to display the application name and the current version.
|
||||
_exitMessage = fmt::format("{0}\n{1}",
|
||||
til::u16u8(appLogic->ApplicationDisplayName()),
|
||||
til::u16u8(appLogic->ApplicationVersion()));
|
||||
// Theoretically, we don't need to exit now, since this isn't really
|
||||
// an error case. However, in practice, it feels weird to have `wt
|
||||
// -v` open a new tab, and makes enough sense that `wt -v ;
|
||||
// split-pane` (or whatever) just displays the version and exits.
|
||||
_shouldExitEarly = true;
|
||||
}
|
||||
};
|
||||
_app.add_flag_function("-v,--version", versionCallback, RS_A(L"CmdVersionDesc"));
|
||||
|
||||
// Launch mode related flags
|
||||
// Maximized and Fullscreen flags
|
||||
// -M,--maximized: Maximizes the window on launch
|
||||
// -F,--fullscreen: Fullscreens the window on launch
|
||||
// -f,--focus: Sets the terminal into the Focus mode
|
||||
// While fullscreen excludes both maximized and focus mode, the user can combine between the maximized and focused (-fM)
|
||||
auto maximizedCallback = [this](int64_t /*count*/) {
|
||||
_launchMode = (_launchMode.has_value() && _launchMode.value() == LaunchMode::FocusMode) ?
|
||||
LaunchMode::MaximizedFocusMode :
|
||||
LaunchMode::MaximizedMode;
|
||||
_launchMode = winrt::TerminalApp::LaunchMode::MaximizedMode;
|
||||
};
|
||||
auto fullscreenCallback = [this](int64_t /*count*/) {
|
||||
_launchMode = LaunchMode::FullscreenMode;
|
||||
_launchMode = winrt::TerminalApp::LaunchMode::FullscreenMode;
|
||||
};
|
||||
auto focusCallback = [this](int64_t /*count*/) {
|
||||
_launchMode = (_launchMode.has_value() && _launchMode.value() == LaunchMode::MaximizedMode) ?
|
||||
LaunchMode::MaximizedFocusMode :
|
||||
LaunchMode::FocusMode;
|
||||
};
|
||||
|
||||
auto maximized = _app.add_flag_function("-M,--maximized", maximizedCallback, RS_A(L"CmdMaximizedDesc"));
|
||||
auto fullscreen = _app.add_flag_function("-F,--fullscreen", fullscreenCallback, RS_A(L"CmdFullscreenDesc"));
|
||||
auto focus = _app.add_flag_function("-f,--focus", focusCallback, RS_A(L"CmdFocusDesc"));
|
||||
maximized->excludes(fullscreen);
|
||||
focus->excludes(fullscreen);
|
||||
|
||||
// Subcommands
|
||||
_buildNewTabParser();
|
||||
@@ -223,13 +214,14 @@ void AppCommandlineArgs::_buildNewTabParser()
|
||||
// command was parsed.
|
||||
subcommand.subcommand->callback([&, this]() {
|
||||
// Build the NewTab action from the values we've parsed on the commandline.
|
||||
ActionAndArgs newTabAction{};
|
||||
newTabAction.Action(ShortcutAction::NewTab);
|
||||
auto newTabAction = winrt::make_self<implementation::ActionAndArgs>();
|
||||
newTabAction->Action(ShortcutAction::NewTab);
|
||||
auto args = winrt::make_self<implementation::NewTabArgs>();
|
||||
// _getNewTerminalArgs MUST be called before parsing any other options,
|
||||
// as it might clear those options while finding the commandline
|
||||
NewTabArgs args{ _getNewTerminalArgs(subcommand) };
|
||||
newTabAction.Args(args);
|
||||
_startupActions.push_back(newTabAction);
|
||||
args->TerminalArgs(_getNewTerminalArgs(subcommand));
|
||||
newTabAction->Args(*args);
|
||||
_startupActions.push_back(*newTabAction);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -265,29 +257,29 @@ void AppCommandlineArgs::_buildSplitPaneParser()
|
||||
// command was parsed.
|
||||
subcommand.subcommand->callback([&, this]() {
|
||||
// Build the SplitPane action from the values we've parsed on the commandline.
|
||||
ActionAndArgs splitPaneActionAndArgs{};
|
||||
splitPaneActionAndArgs.Action(ShortcutAction::SplitPane);
|
||||
|
||||
auto splitPaneActionAndArgs = winrt::make_self<implementation::ActionAndArgs>();
|
||||
splitPaneActionAndArgs->Action(ShortcutAction::SplitPane);
|
||||
auto args = winrt::make_self<implementation::SplitPaneArgs>();
|
||||
// _getNewTerminalArgs MUST be called before parsing any other options,
|
||||
// as it might clear those options while finding the commandline
|
||||
auto terminalArgs{ _getNewTerminalArgs(subcommand) };
|
||||
auto style{ SplitState::Automatic };
|
||||
args->TerminalArgs(_getNewTerminalArgs(subcommand));
|
||||
args->SplitStyle(SplitState::Automatic);
|
||||
// Make sure to use the `Option`s here to check if they were set -
|
||||
// _getNewTerminalArgs might reset them while parsing a commandline
|
||||
if ((*subcommand._horizontalOption || *subcommand._verticalOption))
|
||||
{
|
||||
if (_splitHorizontal)
|
||||
{
|
||||
style = SplitState::Horizontal;
|
||||
args->SplitStyle(SplitState::Horizontal);
|
||||
}
|
||||
else if (_splitVertical)
|
||||
{
|
||||
style = SplitState::Vertical;
|
||||
args->SplitStyle(SplitState::Vertical);
|
||||
}
|
||||
}
|
||||
SplitPaneArgs args{ style, terminalArgs };
|
||||
splitPaneActionAndArgs.Args(args);
|
||||
_startupActions.push_back(splitPaneActionAndArgs);
|
||||
|
||||
splitPaneActionAndArgs->Args(*args);
|
||||
_startupActions.push_back(*splitPaneActionAndArgs);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -327,19 +319,20 @@ void AppCommandlineArgs::_buildFocusTabParser()
|
||||
// command was parsed.
|
||||
subcommand->callback([&, this]() {
|
||||
// Build the action from the values we've parsed on the commandline.
|
||||
ActionAndArgs focusTabAction{};
|
||||
auto focusTabAction = winrt::make_self<implementation::ActionAndArgs>();
|
||||
|
||||
if (_focusTabIndex >= 0)
|
||||
{
|
||||
focusTabAction.Action(ShortcutAction::SwitchToTab);
|
||||
SwitchToTabArgs args{ static_cast<unsigned int>(_focusTabIndex) };
|
||||
focusTabAction.Args(args);
|
||||
_startupActions.push_back(focusTabAction);
|
||||
focusTabAction->Action(ShortcutAction::SwitchToTab);
|
||||
auto args = winrt::make_self<implementation::SwitchToTabArgs>();
|
||||
args->TabIndex(_focusTabIndex);
|
||||
focusTabAction->Args(*args);
|
||||
_startupActions.push_back(*focusTabAction);
|
||||
}
|
||||
else if (_focusNextTab || _focusPrevTab)
|
||||
{
|
||||
focusTabAction.Action(_focusNextTab ? ShortcutAction::NextTab : ShortcutAction::PrevTab);
|
||||
_startupActions.push_back(std::move(focusTabAction));
|
||||
focusTabAction->Action(_focusNextTab ? ShortcutAction::NextTab : ShortcutAction::PrevTab);
|
||||
_startupActions.push_back(*focusTabAction);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -386,7 +379,7 @@ void AppCommandlineArgs::_addNewTerminalArgs(AppCommandlineArgs::NewTerminalSubc
|
||||
// - A fully initialized NewTerminalArgs corresponding to values we've currently parsed.
|
||||
NewTerminalArgs AppCommandlineArgs::_getNewTerminalArgs(AppCommandlineArgs::NewTerminalSubcommand& subcommand)
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
auto args = winrt::make_self<implementation::NewTerminalArgs>();
|
||||
|
||||
if (!_commandline.empty())
|
||||
{
|
||||
@@ -410,25 +403,25 @@ NewTerminalArgs AppCommandlineArgs::_getNewTerminalArgs(AppCommandlineArgs::NewT
|
||||
}
|
||||
}
|
||||
|
||||
args.Commandline(winrt::to_hstring(cmdlineBuffer.str()));
|
||||
args->Commandline(winrt::to_hstring(cmdlineBuffer.str()));
|
||||
}
|
||||
|
||||
if (*subcommand.profileNameOption)
|
||||
{
|
||||
args.Profile(winrt::to_hstring(_profileName));
|
||||
args->Profile(winrt::to_hstring(_profileName));
|
||||
}
|
||||
|
||||
if (*subcommand.startingDirectoryOption)
|
||||
{
|
||||
args.StartingDirectory(winrt::to_hstring(_startingDirectory));
|
||||
args->StartingDirectory(winrt::to_hstring(_startingDirectory));
|
||||
}
|
||||
|
||||
if (*subcommand.titleOption)
|
||||
{
|
||||
args.TabTitle(winrt::to_hstring(_startingTitle));
|
||||
args->TabTitle(winrt::to_hstring(_startingTitle));
|
||||
}
|
||||
|
||||
return args;
|
||||
return *args;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -606,7 +599,7 @@ void AppCommandlineArgs::_addCommandsForArg(std::vector<Commandline>& commands,
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the deque of actions we've buffered as a result of parsing commands.
|
||||
std::vector<ActionAndArgs>& AppCommandlineArgs::GetStartupActions()
|
||||
std::vector<winrt::TerminalApp::ActionAndArgs>& AppCommandlineArgs::GetStartupActions()
|
||||
{
|
||||
return _startupActions;
|
||||
}
|
||||
@@ -659,15 +652,18 @@ void AppCommandlineArgs::ValidateStartupCommands()
|
||||
_startupActions.front().Action() != ShortcutAction::NewTab)
|
||||
{
|
||||
// Build the NewTab action from the values we've parsed on the commandline.
|
||||
NewTerminalArgs newTerminalArgs{};
|
||||
NewTabArgs args{ newTerminalArgs };
|
||||
ActionAndArgs newTabAction{ ShortcutAction::NewTab, args };
|
||||
auto newTabAction = winrt::make_self<implementation::ActionAndArgs>();
|
||||
newTabAction->Action(ShortcutAction::NewTab);
|
||||
auto args = winrt::make_self<implementation::NewTabArgs>();
|
||||
auto newTerminalArgs = winrt::make_self<implementation::NewTerminalArgs>();
|
||||
args->TerminalArgs(*newTerminalArgs);
|
||||
newTabAction->Args(*args);
|
||||
// push the arg onto the front
|
||||
_startupActions.insert(_startupActions.begin(), 1, newTabAction);
|
||||
_startupActions.insert(_startupActions.begin(), 1, *newTabAction);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> AppCommandlineArgs::GetLaunchMode() const noexcept
|
||||
std::optional<winrt::TerminalApp::LaunchMode> AppCommandlineArgs::GetLaunchMode() const noexcept
|
||||
{
|
||||
return _launchMode;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under the MIT license.
|
||||
#pragma once
|
||||
|
||||
#include "ActionAndArgs.h"
|
||||
|
||||
#include "Commandline.h"
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
@@ -34,11 +36,11 @@ public:
|
||||
static std::vector<Commandline> BuildCommands(winrt::array_view<const winrt::hstring>& args);
|
||||
|
||||
void ValidateStartupCommands();
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>& GetStartupActions();
|
||||
std::vector<winrt::TerminalApp::ActionAndArgs>& GetStartupActions();
|
||||
const std::string& GetExitMessage();
|
||||
bool ShouldExitEarly() const noexcept;
|
||||
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> GetLaunchMode() const noexcept;
|
||||
std::optional<winrt::TerminalApp::LaunchMode> GetLaunchMode() const noexcept;
|
||||
|
||||
private:
|
||||
static const std::wregex _commandDelimiterRegex;
|
||||
@@ -87,14 +89,14 @@ private:
|
||||
bool _focusNextTab{ false };
|
||||
bool _focusPrevTab{ false };
|
||||
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> _launchMode{ std::nullopt };
|
||||
std::optional<winrt::TerminalApp::LaunchMode> _launchMode{ std::nullopt };
|
||||
// Are you adding more args here? Make sure to reset them in _resetStateToDefault
|
||||
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs> _startupActions;
|
||||
std::vector<winrt::TerminalApp::ActionAndArgs> _startupActions;
|
||||
std::string _exitMessage;
|
||||
bool _shouldExitEarly{ false };
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs _getNewTerminalArgs(NewTerminalSubcommand& subcommand);
|
||||
winrt::TerminalApp::NewTerminalArgs _getNewTerminalArgs(NewTerminalSubcommand& subcommand);
|
||||
void _addNewTerminalArgs(NewTerminalSubcommand& subcommand);
|
||||
void _buildParser();
|
||||
void _buildNewTabParser();
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_dispatch = dispatch;
|
||||
}
|
||||
|
||||
void AppKeyBindings::SetKeyMapping(const winrt::Microsoft::Terminal::Settings::Model::KeyMapping& keymap)
|
||||
void AppKeyBindings::SetKeyMapping(const winrt::TerminalApp::KeyMapping& keymap)
|
||||
{
|
||||
_keymap = keymap;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "AppKeyBindings.g.h"
|
||||
#include "ActionArgs.h"
|
||||
#include "ShortcutActionDispatch.h"
|
||||
#include "..\inc\cppwinrt_utils.h"
|
||||
|
||||
@@ -11,6 +12,8 @@
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class SettingsTests;
|
||||
class KeyBindingsTests;
|
||||
class TestUtils;
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@@ -22,14 +25,16 @@ namespace winrt::TerminalApp::implementation
|
||||
bool TryKeyChord(winrt::Microsoft::Terminal::TerminalControl::KeyChord const& kc);
|
||||
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
void SetKeyMapping(const Microsoft::Terminal::Settings::Model::KeyMapping& keymap);
|
||||
void SetKeyMapping(const winrt::TerminalApp::KeyMapping& keymap);
|
||||
|
||||
private:
|
||||
winrt::Microsoft::Terminal::Settings::Model::KeyMapping _keymap{ nullptr };
|
||||
winrt::TerminalApp::KeyMapping _keymap{ nullptr };
|
||||
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch{ nullptr };
|
||||
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::KeyBindingsTests;
|
||||
friend class TerminalAppLocalTests::TestUtils;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
import "ShortcutActionDispatch.idl";
|
||||
import "KeyMapping.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
@@ -9,6 +10,6 @@ namespace TerminalApp
|
||||
AppKeyBindings();
|
||||
|
||||
void SetDispatch(ShortcutActionDispatch dispatch);
|
||||
void SetKeyMapping(Microsoft.Terminal.Settings.Model.KeyMapping keymap);
|
||||
void SetKeyMapping(KeyMapping keymap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::TerminalApp;
|
||||
|
||||
namespace winrt
|
||||
@@ -30,7 +29,7 @@ static const winrt::hstring StartupTaskName = L"StartTerminalOnLoginTask";
|
||||
// !!! IMPORTANT !!!
|
||||
// Make sure that these keys are in the same order as the
|
||||
// SettingsLoadWarnings/Errors enum is!
|
||||
static const std::array<std::wstring_view, static_cast<uint32_t>(SettingsLoadWarnings::WARNINGS_SIZE)> settingsLoadWarningsLabels {
|
||||
static const std::array<std::wstring_view, static_cast<uint32_t>(winrt::TerminalApp::SettingsLoadWarnings::WARNINGS_SIZE)> settingsLoadWarningsLabels {
|
||||
USES_RESOURCE(L"MissingDefaultProfileText"),
|
||||
USES_RESOURCE(L"DuplicateProfileText"),
|
||||
USES_RESOURCE(L"UnknownColorSchemeText"),
|
||||
@@ -40,9 +39,10 @@ static const std::array<std::wstring_view, static_cast<uint32_t>(SettingsLoadWar
|
||||
USES_RESOURCE(L"TooManyKeysForChord"),
|
||||
USES_RESOURCE(L"MissingRequiredParameter"),
|
||||
USES_RESOURCE(L"LegacyGlobalsProperty"),
|
||||
USES_RESOURCE(L"FailedToParseCommandJson")
|
||||
USES_RESOURCE(L"FailedToParseCommandJson"),
|
||||
USES_RESOURCE(L"FailedToWriteToSettings")
|
||||
};
|
||||
static const std::array<std::wstring_view, static_cast<uint32_t>(SettingsLoadErrors::ERRORS_SIZE)> settingsLoadErrorsLabels {
|
||||
static const std::array<std::wstring_view, static_cast<uint32_t>(winrt::TerminalApp::SettingsLoadErrors::ERRORS_SIZE)> settingsLoadErrorsLabels {
|
||||
USES_RESOURCE(L"NoProfilesText"),
|
||||
USES_RESOURCE(L"AllProfilesHiddenText")
|
||||
};
|
||||
@@ -77,7 +77,7 @@ static winrt::hstring _GetMessageText(uint32_t index, std::array<std::wstring_vi
|
||||
// - warning: the SettingsLoadWarnings value to get the localized text for.
|
||||
// Return Value:
|
||||
// - localized text for the given warning
|
||||
static winrt::hstring _GetWarningText(SettingsLoadWarnings warning)
|
||||
static winrt::hstring _GetWarningText(winrt::TerminalApp::SettingsLoadWarnings warning)
|
||||
{
|
||||
return _GetMessageText(static_cast<uint32_t>(warning), settingsLoadWarningsLabels);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ static winrt::hstring _GetWarningText(SettingsLoadWarnings warning)
|
||||
// - error: the SettingsLoadErrors value to get the localized text for.
|
||||
// Return Value:
|
||||
// - localized text for the given error
|
||||
static winrt::hstring _GetErrorText(SettingsLoadErrors error)
|
||||
static winrt::hstring _GetErrorText(winrt::TerminalApp::SettingsLoadErrors error)
|
||||
{
|
||||
return _GetMessageText(static_cast<uint32_t>(error), settingsLoadErrorsLabels);
|
||||
}
|
||||
@@ -170,7 +170,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Returns the settings currently in use by the entire Terminal application.
|
||||
// Throws:
|
||||
// - HR E_INVALIDARG if the app isn't up and running.
|
||||
const CascadiaSettings AppLogic::CurrentAppSettings()
|
||||
const TerminalApp::CascadiaSettings AppLogic::CurrentAppSettings()
|
||||
{
|
||||
auto appLogic{ ::winrt::TerminalApp::implementation::AppLogic::Current() };
|
||||
THROW_HR_IF_NULL(E_INVALIDARG, appLogic);
|
||||
@@ -265,10 +265,6 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
_root->ToggleFullscreen();
|
||||
}
|
||||
else if (launchMode == LaunchMode::FocusMode || launchMode == LaunchMode::MaximizedFocusMode)
|
||||
{
|
||||
_root->ToggleFocusMode();
|
||||
}
|
||||
});
|
||||
_root->Create();
|
||||
|
||||
@@ -469,6 +465,11 @@ namespace winrt::TerminalApp::implementation
|
||||
void AppLogic::_OnLoaded(const IInspectable& /*sender*/,
|
||||
const RoutedEventArgs& /*eventArgs*/)
|
||||
{
|
||||
const auto keyboardServiceIsDisabled = !_IsKeyboardServiceEnabled();
|
||||
if (keyboardServiceIsDisabled)
|
||||
{
|
||||
_root->ShowKeyboardServiceWarning();
|
||||
}
|
||||
if (FAILED(_settingsLoadedResult))
|
||||
{
|
||||
const winrt::hstring titleKey = USES_RESOURCE(L"InitialJsonParseErrorTitle");
|
||||
@@ -481,6 +482,51 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper for determining if the "Touch Keyboard and Handwriting Panel
|
||||
// Service" is enabled. If it isn't, we want to be able to display a
|
||||
// warning to the user, because they won't be able to type in the
|
||||
// Terminal.
|
||||
// Return Value:
|
||||
// - true if the service is enabled, or if we fail to query the service. We
|
||||
// return true in that case, to be less noisy (though, that is unexpected)
|
||||
bool AppLogic::_IsKeyboardServiceEnabled()
|
||||
{
|
||||
if (IsUwp())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If at any point we fail to open the service manager, the service,
|
||||
// etc, then just quick return true to disable the dialog. We'd rather
|
||||
// not be noisy with this dialog if we failed for some reason.
|
||||
|
||||
// Open the service manager. This will return 0 if it failed.
|
||||
wil::unique_schandle hManager{ OpenSCManager(nullptr, nullptr, 0) };
|
||||
|
||||
if (LOG_LAST_ERROR_IF(!hManager.is_valid()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get a handle to the keyboard service
|
||||
wil::unique_schandle hService{ OpenService(hManager.get(), TabletInputServiceKey.data(), SERVICE_QUERY_STATUS) };
|
||||
if (LOG_LAST_ERROR_IF(!hService.is_valid()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the current state of the service
|
||||
SERVICE_STATUS status{ 0 };
|
||||
if (!LOG_IF_WIN32_BOOL_FALSE(QueryServiceStatus(hService.get(), &status)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto state = status.dwCurrentState;
|
||||
return (state == SERVICE_RUNNING || state == SERVICE_START_PENDING);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the size in pixels of the client area we'll need to launch this
|
||||
// terminal app. This method will use the default profile's settings to do
|
||||
@@ -614,6 +660,17 @@ namespace winrt::TerminalApp::implementation
|
||||
return _settings.GlobalSettings().ShowTabsInTitlebar();
|
||||
}
|
||||
|
||||
bool AppLogic::GetInitialAlwaysOnTop()
|
||||
{
|
||||
if (!_loadedInitialSettings)
|
||||
{
|
||||
// Load settings if we haven't already
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
return _settings.GlobalSettings().AlwaysOnTop();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - See Pane::CalcSnappedDimension
|
||||
float AppLogic::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||
@@ -723,7 +780,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void AppLogic::_RegisterSettingsChange()
|
||||
{
|
||||
// Get the containing folder.
|
||||
const std::filesystem::path settingsPath{ std::wstring_view{ CascadiaSettings::SettingsPath() } };
|
||||
const auto settingsPath{ CascadiaSettings::GetSettingsPath() };
|
||||
const auto folder = settingsPath.parent_path();
|
||||
|
||||
_reader.create(folder.c_str(),
|
||||
@@ -875,7 +932,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Returns a pointer to the global shared settings.
|
||||
[[nodiscard]] CascadiaSettings AppLogic::GetSettings() const noexcept
|
||||
[[nodiscard]] TerminalApp::CascadiaSettings AppLogic::GetSettings() const noexcept
|
||||
{
|
||||
return _settings;
|
||||
}
|
||||
@@ -1046,6 +1103,65 @@ namespace winrt::TerminalApp::implementation
|
||||
return _appArgs.ShouldExitEarly();
|
||||
}
|
||||
|
||||
winrt::hstring AppLogic::ApplicationDisplayName() const
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
|
||||
return package.DisplayName();
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return RS_(L"ApplicationDisplayNameUnpackaged");
|
||||
}
|
||||
|
||||
winrt::hstring AppLogic::ApplicationVersion() const
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
|
||||
const auto version{ package.Id().Version() };
|
||||
winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u.%u", version.Major, version.Minor, version.Build, version.Revision) };
|
||||
return formatted;
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// Try to get the version the old-fashioned way
|
||||
try
|
||||
{
|
||||
struct LocalizationInfo
|
||||
{
|
||||
WORD language, codepage;
|
||||
};
|
||||
// Use the current module instance handle for TerminalApp.dll, nullptr for WindowsTerminal.exe
|
||||
auto filename{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
|
||||
auto size{ GetFileVersionInfoSizeExW(0, filename.c_str(), nullptr) };
|
||||
THROW_LAST_ERROR_IF(size == 0);
|
||||
auto versionBuffer{ std::make_unique<std::byte[]>(size) };
|
||||
THROW_IF_WIN32_BOOL_FALSE(GetFileVersionInfoExW(0, filename.c_str(), 0, size, versionBuffer.get()));
|
||||
|
||||
// Get the list of Version localizations
|
||||
LocalizationInfo* pVarLocalization{ nullptr };
|
||||
UINT varLen{ 0 };
|
||||
THROW_IF_WIN32_BOOL_FALSE(VerQueryValueW(versionBuffer.get(), L"\\VarFileInfo\\Translation", reinterpret_cast<void**>(&pVarLocalization), &varLen));
|
||||
THROW_HR_IF(E_UNEXPECTED, varLen < sizeof(*pVarLocalization)); // there must be at least one translation
|
||||
|
||||
// Get the product version from the localized version compartment
|
||||
// We're using String/ProductVersion here because our build pipeline puts more rich information in it (like the branch name)
|
||||
// than in the unlocalized numeric version fields.
|
||||
WCHAR* pProductVersion{ nullptr };
|
||||
UINT versionLen{ 0 };
|
||||
const auto localizedVersionName{ wil::str_printf<std::wstring>(L"\\StringFileInfo\\%04x%04x\\ProductVersion",
|
||||
pVarLocalization->language ? pVarLocalization->language : 0x0409, // well-known en-US LCID
|
||||
pVarLocalization->codepage) };
|
||||
THROW_IF_WIN32_BOOL_FALSE(VerQueryValueW(versionBuffer.get(), localizedVersionName.c_str(), reinterpret_cast<void**>(&pProductVersion), &versionLen));
|
||||
return { pProductVersion };
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return RS_(L"ApplicationVersionUnknown");
|
||||
}
|
||||
|
||||
bool AppLogic::FocusMode() const
|
||||
{
|
||||
return _root ? _root->FocusMode() : false;
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "AppLogic.g.h"
|
||||
|
||||
#include "Tab.h"
|
||||
#include "CascadiaSettings.h"
|
||||
#include "TerminalPage.h"
|
||||
#include "Jumplist.h"
|
||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||
@@ -14,7 +17,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
public:
|
||||
static AppLogic* Current() noexcept;
|
||||
static const Microsoft::Terminal::Settings::Model::CascadiaSettings CurrentAppSettings();
|
||||
static const TerminalApp::CascadiaSettings CurrentAppSettings();
|
||||
|
||||
AppLogic();
|
||||
~AppLogic() = default;
|
||||
@@ -24,12 +27,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void RunAsUwp();
|
||||
bool IsElevated() const noexcept;
|
||||
void LoadSettings();
|
||||
[[nodiscard]] Microsoft::Terminal::Settings::Model::CascadiaSettings GetSettings() const noexcept;
|
||||
[[nodiscard]] TerminalApp::CascadiaSettings GetSettings() const noexcept;
|
||||
|
||||
int32_t SetStartupCommandline(array_view<const winrt::hstring> actions);
|
||||
winrt::hstring ParseCommandlineMessage();
|
||||
bool ShouldExitEarly();
|
||||
|
||||
winrt::hstring ApplicationDisplayName() const;
|
||||
winrt::hstring ApplicationVersion() const;
|
||||
bool FocusMode() const;
|
||||
bool Fullscreen() const;
|
||||
bool AlwaysOnTop() const;
|
||||
@@ -37,8 +42,9 @@ namespace winrt::TerminalApp::implementation
|
||||
Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi);
|
||||
TerminalApp::InitialPosition GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY);
|
||||
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme();
|
||||
Microsoft::Terminal::Settings::Model::LaunchMode GetLaunchMode();
|
||||
LaunchMode GetLaunchMode();
|
||||
bool GetShowTabsInTitlebar();
|
||||
bool GetInitialAlwaysOnTop();
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
|
||||
Windows::UI::Xaml::UIElement GetRoot() noexcept;
|
||||
@@ -65,7 +71,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// updated in _ApplyTheme. The root currently is _root.
|
||||
winrt::com_ptr<TerminalPage> _root{ nullptr };
|
||||
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
TerminalApp::CascadiaSettings _settings{ nullptr };
|
||||
|
||||
HRESULT _settingsLoadedResult;
|
||||
winrt::hstring _settingsLoadExceptionText{};
|
||||
@@ -83,6 +89,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult);
|
||||
void _ShowLoadWarningsDialog();
|
||||
bool _IsKeyboardServiceEnabled();
|
||||
void _ShowKeyboardServiceDisabledDialog();
|
||||
|
||||
fire_and_forget _LoadErrorsDialogRoutine();
|
||||
fire_and_forget _ShowLoadWarningsDialogRoutine();
|
||||
|
||||
@@ -13,6 +13,13 @@ namespace TerminalApp
|
||||
Int64 Y;
|
||||
};
|
||||
|
||||
enum LaunchMode
|
||||
{
|
||||
DefaultMode,
|
||||
MaximizedMode,
|
||||
FullscreenMode,
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass AppLogic : IDirectKeyListener, IDialogPresenter
|
||||
{
|
||||
AppLogic();
|
||||
@@ -37,6 +44,9 @@ namespace TerminalApp
|
||||
|
||||
String Title { get; };
|
||||
|
||||
String ApplicationDisplayName { get; };
|
||||
String ApplicationVersion { get; };
|
||||
|
||||
Boolean FocusMode { get; };
|
||||
Boolean Fullscreen { get; };
|
||||
Boolean AlwaysOnTop { get; };
|
||||
@@ -45,8 +55,9 @@ namespace TerminalApp
|
||||
|
||||
InitialPosition GetInitialPosition(Int64 defaultInitialX, Int64 defaultInitialY);
|
||||
Windows.UI.Xaml.ElementTheme GetRequestedTheme();
|
||||
Microsoft.Terminal.Settings.Model.LaunchMode GetLaunchMode();
|
||||
LaunchMode GetLaunchMode();
|
||||
Boolean GetShowTabsInTitlebar();
|
||||
Boolean GetInitialAlwaysOnTop();
|
||||
Single CalcSnappedDimension(Boolean widthOrHeight, Single dimension);
|
||||
void TitlebarClicked();
|
||||
void WindowCloseButtonClicked();
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
|
||||
|
||||
#include "AzureCloudShellGenerator.h"
|
||||
#include "LegacyProfileGeneratorNamespaces.h"
|
||||
|
||||
@@ -11,9 +13,8 @@
|
||||
#include "Utils.h"
|
||||
#include "DefaultProfileUtils.h"
|
||||
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace ::TerminalApp;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
std::wstring_view AzureCloudShellGenerator::GetNamespace()
|
||||
{
|
||||
@@ -31,13 +32,13 @@ std::vector<Profile> AzureCloudShellGenerator::GenerateProfiles()
|
||||
{
|
||||
std::vector<Profile> profiles;
|
||||
|
||||
if (AzureConnection::IsAzureConnectionAvailable())
|
||||
if (winrt::Microsoft::Terminal::TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
||||
{
|
||||
auto azureCloudShellProfile{ CreateDefaultProfile(L"Azure Cloud Shell") };
|
||||
azureCloudShellProfile.Commandline(L"Azure");
|
||||
azureCloudShellProfile.StartingDirectory(DEFAULT_STARTING_DIRECTORY);
|
||||
azureCloudShellProfile.ColorSchemeName(L"Vintage");
|
||||
azureCloudShellProfile.ConnectionType(AzureConnection::ConnectionType());
|
||||
azureCloudShellProfile.ConnectionType(AzureConnectionType);
|
||||
profiles.emplace_back(azureCloudShellProfile);
|
||||
}
|
||||
|
||||
@@ -18,15 +18,17 @@ Author(s):
|
||||
#pragma once
|
||||
#include "IDynamicProfileGenerator.h"
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model
|
||||
static constexpr winrt::guid AzureConnectionType = { 0xd9fcfdfa, 0xa479, 0x412c, { 0x83, 0xb7, 0xc5, 0x64, 0xe, 0x61, 0xcd, 0x62 } };
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
class AzureCloudShellGenerator : public IDynamicProfileGenerator
|
||||
class AzureCloudShellGenerator : public TerminalApp::IDynamicProfileGenerator
|
||||
{
|
||||
public:
|
||||
AzureCloudShellGenerator() = default;
|
||||
~AzureCloudShellGenerator() = default;
|
||||
std::wstring_view GetNamespace() override;
|
||||
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::Profile> GenerateProfiles() override;
|
||||
std::vector<winrt::TerminalApp::Profile> GenerateProfiles() override;
|
||||
};
|
||||
};
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "CascadiaSettings.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
#include "AppLogic.h"
|
||||
#include "Utils.h"
|
||||
#include "LibraryResources.h"
|
||||
|
||||
@@ -18,9 +19,9 @@
|
||||
|
||||
#include "CascadiaSettings.g.cpp"
|
||||
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace winrt::TerminalApp::implementation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace Microsoft::Console;
|
||||
|
||||
@@ -45,7 +46,7 @@ CascadiaSettings::CascadiaSettings() :
|
||||
// - addDynamicProfiles: if true, we'll add the built-in DPGs.
|
||||
CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) :
|
||||
_globals{ winrt::make_self<implementation::GlobalAppSettings>() },
|
||||
_profiles{ winrt::single_threaded_observable_vector<Model::Profile>() },
|
||||
_profiles{ winrt::single_threaded_observable_vector<TerminalApp::Profile>() },
|
||||
_warnings{ winrt::single_threaded_vector<SettingsLoadWarnings>() },
|
||||
_deserializationErrorMessage{ L"" }
|
||||
{
|
||||
@@ -57,38 +58,6 @@ CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) :
|
||||
}
|
||||
}
|
||||
|
||||
CascadiaSettings::CascadiaSettings(winrt::hstring json) :
|
||||
CascadiaSettings(false)
|
||||
{
|
||||
const auto jsonString{ til::u16u8(json) };
|
||||
_ParseJsonString(jsonString, false);
|
||||
LayerJson(_userSettings);
|
||||
_ValidateSettings();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::Copy() const
|
||||
{
|
||||
// dynamic profile generators added by default
|
||||
auto settings{ winrt::make_self<CascadiaSettings>() };
|
||||
settings->_globals = _globals->Copy();
|
||||
for (const auto profile : _profiles)
|
||||
{
|
||||
auto profImpl{ winrt::get_self<Profile>(profile) };
|
||||
settings->_profiles.Append(*profImpl->Copy());
|
||||
}
|
||||
for (auto warning : _warnings)
|
||||
{
|
||||
settings->_warnings.Append(warning);
|
||||
}
|
||||
settings->_loadError = _loadError;
|
||||
settings->_deserializationErrorMessage = _deserializationErrorMessage;
|
||||
settings->_userSettingsString = _userSettingsString;
|
||||
settings->_userSettings = _userSettings;
|
||||
settings->_defaultSettings = _defaultSettings;
|
||||
settings->_userDefaultProfileSettings = _userDefaultProfileSettings;
|
||||
return *settings;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Finds a profile that matches the given GUID. If there is no profile in this
|
||||
// settings object that matches, returns nullptr.
|
||||
@@ -97,7 +66,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
// Return Value:
|
||||
// - a non-ownership pointer to the profile matching the given guid, or nullptr
|
||||
// if there is no match.
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::FindProfile(winrt::guid profileGuid) const noexcept
|
||||
winrt::TerminalApp::Profile CascadiaSettings::FindProfile(winrt::guid profileGuid) const noexcept
|
||||
{
|
||||
const winrt::guid guid{ profileGuid };
|
||||
for (auto profile : _profiles)
|
||||
@@ -120,7 +89,7 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::FindProfi
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - an iterable collection of all of our Profiles.
|
||||
IObservableVector<winrt::Microsoft::Terminal::Settings::Model::Profile> CascadiaSettings::Profiles() const noexcept
|
||||
IObservableVector<winrt::TerminalApp::Profile> CascadiaSettings::Profiles() const noexcept
|
||||
{
|
||||
return _profiles;
|
||||
}
|
||||
@@ -131,7 +100,7 @@ IObservableVector<winrt::Microsoft::Terminal::Settings::Model::Profile> Cascadia
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the globally configured keybindings
|
||||
winrt::Microsoft::Terminal::Settings::Model::KeyMapping CascadiaSettings::KeyMap() const noexcept
|
||||
winrt::TerminalApp::KeyMapping CascadiaSettings::KeyMap() const noexcept
|
||||
{
|
||||
return _globals->KeyMap();
|
||||
}
|
||||
@@ -142,7 +111,7 @@ winrt::Microsoft::Terminal::Settings::Model::KeyMapping CascadiaSettings::KeyMap
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a reference to our global settings
|
||||
winrt::Microsoft::Terminal::Settings::Model::GlobalAppSettings CascadiaSettings::GlobalSettings() const
|
||||
winrt::TerminalApp::GlobalAppSettings CascadiaSettings::GlobalSettings() const
|
||||
{
|
||||
return *_globals;
|
||||
}
|
||||
@@ -152,12 +121,22 @@ winrt::Microsoft::Terminal::Settings::Model::GlobalAppSettings CascadiaSettings:
|
||||
// knew were bad when we called `_ValidateSettings` last.
|
||||
// Return Value:
|
||||
// - a reference to our list of warnings.
|
||||
IVectorView<winrt::Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> CascadiaSettings::Warnings()
|
||||
IVectorView<winrt::TerminalApp::SettingsLoadWarnings> CascadiaSettings::Warnings()
|
||||
{
|
||||
return _warnings.GetView();
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Settings::Model::SettingsLoadErrors> CascadiaSettings::GetLoadingError()
|
||||
void CascadiaSettings::ClearWarnings()
|
||||
{
|
||||
_warnings.Clear();
|
||||
}
|
||||
|
||||
void CascadiaSettings::AppendWarning(SettingsLoadWarnings warning)
|
||||
{
|
||||
_warnings.Append(warning);
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IReference<winrt::TerminalApp::SettingsLoadErrors> CascadiaSettings::GetLoadingError()
|
||||
{
|
||||
return _loadError;
|
||||
}
|
||||
@@ -179,8 +158,6 @@ winrt::hstring CascadiaSettings::GetSerializationErrorMessage()
|
||||
// - <none>
|
||||
void CascadiaSettings::_ValidateSettings()
|
||||
{
|
||||
_warnings.Clear();
|
||||
|
||||
// Make sure to check that profiles exists at all first and foremost:
|
||||
_ValidateProfilesExist();
|
||||
|
||||
@@ -241,7 +218,7 @@ void CascadiaSettings::_ValidateProfilesExist()
|
||||
// We can't add the warning to the list of warnings here, because this
|
||||
// object is not going to be returned at any point.
|
||||
|
||||
throw SettingsException(Microsoft::Terminal::Settings::Model::SettingsLoadErrors::NoProfiles);
|
||||
throw SettingsException(TerminalApp::SettingsLoadErrors::NoProfiles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +272,7 @@ void CascadiaSettings::_ValidateDefaultProfileExists()
|
||||
|
||||
if (nullDefaultProfile || defaultProfileNotInProfiles)
|
||||
{
|
||||
_warnings.Append(Microsoft::Terminal::Settings::Model::SettingsLoadWarnings::MissingDefaultProfile);
|
||||
_warnings.Append(TerminalApp::SettingsLoadWarnings::MissingDefaultProfile);
|
||||
// Use the first profile as the new default
|
||||
|
||||
// _temporarily_ set the default profile to the first profile. Because
|
||||
@@ -338,7 +315,7 @@ void CascadiaSettings::_ValidateNoDuplicateProfiles()
|
||||
|
||||
if (foundDupe)
|
||||
{
|
||||
_warnings.Append(Microsoft::Terminal::Settings::Model::SettingsLoadWarnings::DuplicateProfile);
|
||||
_warnings.Append(TerminalApp::SettingsLoadWarnings::DuplicateProfile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +404,7 @@ void CascadiaSettings::_RemoveHiddenProfiles()
|
||||
{
|
||||
// Throw an exception. This is an invalid state, and we want the app to
|
||||
// be able to gracefully use the default settings.
|
||||
throw SettingsException(SettingsLoadErrors::AllProfilesHidden);
|
||||
throw SettingsException(TerminalApp::SettingsLoadErrors::AllProfilesHidden);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,35 +471,29 @@ void CascadiaSettings::_ValidateMediaResources()
|
||||
}
|
||||
}
|
||||
|
||||
if (!profile.Icon().empty())
|
||||
if (!profile.IconPath().empty())
|
||||
{
|
||||
const auto iconPath{ wil::ExpandEnvironmentStringsW<std::wstring>(profile.Icon().c_str()) };
|
||||
try
|
||||
{
|
||||
winrt::Windows::Foundation::Uri imagePath{ iconPath };
|
||||
winrt::Windows::Foundation::Uri imagePath{ profile.ExpandedIconPath() };
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Anything longer than 2 wchar_t's _isn't_ an emoji or symbol,
|
||||
// so treat it as an invalid path.
|
||||
if (iconPath.size() > 2)
|
||||
{
|
||||
// reset icon path
|
||||
profile.Icon(L"");
|
||||
invalidIcon = true;
|
||||
}
|
||||
// reset icon path
|
||||
profile.IconPath(L"");
|
||||
invalidIcon = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidBackground)
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::InvalidBackgroundImage);
|
||||
_warnings.Append(TerminalApp::SettingsLoadWarnings::InvalidBackgroundImage);
|
||||
}
|
||||
|
||||
if (invalidIcon)
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::InvalidIcon);
|
||||
_warnings.Append(TerminalApp::SettingsLoadWarnings::InvalidIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +513,7 @@ void CascadiaSettings::_ValidateMediaResources()
|
||||
// and attempt to look the profile up by name instead.
|
||||
// Return Value:
|
||||
// - the GUID of the profile corresponding to this combination of index and NewTerminalArgs
|
||||
winrt::guid CascadiaSettings::GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const
|
||||
winrt::guid CascadiaSettings::GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const
|
||||
{
|
||||
std::optional<winrt::guid> profileByIndex, profileByName;
|
||||
if (newTerminalArgs)
|
||||
@@ -646,7 +617,7 @@ void CascadiaSettings::_ValidateKeybindings()
|
||||
|
||||
if (!keybindingWarnings.empty())
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::AtLeastOneKeybindingWarning);
|
||||
_warnings.Append(TerminalApp::SettingsLoadWarnings::AtLeastOneKeybindingWarning);
|
||||
for (auto warning : keybindingWarnings)
|
||||
{
|
||||
_warnings.Append(warning);
|
||||
@@ -669,7 +640,7 @@ void CascadiaSettings::_ValidateNoGlobalsKey()
|
||||
{
|
||||
if (auto oldGlobalsProperty{ _userSettings["globals"] })
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::LegacyGlobalsProperty);
|
||||
_warnings.Append(TerminalApp::SettingsLoadWarnings::LegacyGlobalsProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,13 +669,15 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin
|
||||
til::replace_needle_in_haystack_inplace(finalSettings,
|
||||
"%DEFAULT_PROFILE%",
|
||||
til::u16u8(defaultProfileGuid));
|
||||
|
||||
til::replace_needle_in_haystack_inplace(finalSettings,
|
||||
"%VERSION%",
|
||||
til::u16u8(ApplicationVersion()));
|
||||
til::replace_needle_in_haystack_inplace(finalSettings,
|
||||
"%PRODUCT%",
|
||||
til::u16u8(ApplicationDisplayName()));
|
||||
if (const auto appLogic{ winrt::TerminalApp::implementation::AppLogic::Current() })
|
||||
{
|
||||
til::replace_needle_in_haystack_inplace(finalSettings,
|
||||
"%VERSION%",
|
||||
til::u16u8(appLogic->ApplicationVersion()));
|
||||
til::replace_needle_in_haystack_inplace(finalSettings,
|
||||
"%PRODUCT%",
|
||||
til::u16u8(appLogic->ApplicationDisplayName()));
|
||||
}
|
||||
|
||||
til::replace_needle_in_haystack_inplace(finalSettings,
|
||||
"%COMMAND_PROMPT_LOCALIZED_NAME%",
|
||||
@@ -721,7 +694,7 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin
|
||||
// - profileGuid: the GUID of the profile to find the scheme for.
|
||||
// Return Value:
|
||||
// - a non-owning pointer to the scheme.
|
||||
winrt::Microsoft::Terminal::Settings::Model::ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid profileGuid) const
|
||||
winrt::TerminalApp::ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid profileGuid) const
|
||||
{
|
||||
auto profile = FindProfile(profileGuid);
|
||||
if (!profile)
|
||||
@@ -731,62 +704,3 @@ winrt::Microsoft::Terminal::Settings::Model::ColorScheme CascadiaSettings::GetCo
|
||||
const auto schemeName = profile.ColorSchemeName();
|
||||
return _globals->ColorSchemes().TryLookup(schemeName);
|
||||
}
|
||||
|
||||
winrt::hstring CascadiaSettings::ApplicationDisplayName()
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
|
||||
return package.DisplayName();
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return RS_(L"ApplicationDisplayNameUnpackaged");
|
||||
}
|
||||
|
||||
winrt::hstring CascadiaSettings::ApplicationVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
|
||||
const auto version{ package.Id().Version() };
|
||||
winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u.%u", version.Major, version.Minor, version.Build, version.Revision) };
|
||||
return formatted;
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// Try to get the version the old-fashioned way
|
||||
try
|
||||
{
|
||||
struct LocalizationInfo
|
||||
{
|
||||
WORD language, codepage;
|
||||
};
|
||||
// Use the current module instance handle for TerminalApp.dll, nullptr for WindowsTerminal.exe
|
||||
auto filename{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
|
||||
auto size{ GetFileVersionInfoSizeExW(0, filename.c_str(), nullptr) };
|
||||
THROW_LAST_ERROR_IF(size == 0);
|
||||
auto versionBuffer{ std::make_unique<std::byte[]>(size) };
|
||||
THROW_IF_WIN32_BOOL_FALSE(GetFileVersionInfoExW(0, filename.c_str(), 0, size, versionBuffer.get()));
|
||||
|
||||
// Get the list of Version localizations
|
||||
LocalizationInfo* pVarLocalization{ nullptr };
|
||||
UINT varLen{ 0 };
|
||||
THROW_IF_WIN32_BOOL_FALSE(VerQueryValueW(versionBuffer.get(), L"\\VarFileInfo\\Translation", reinterpret_cast<void**>(&pVarLocalization), &varLen));
|
||||
THROW_HR_IF(E_UNEXPECTED, varLen < sizeof(*pVarLocalization)); // there must be at least one translation
|
||||
|
||||
// Get the product version from the localized version compartment
|
||||
// We're using String/ProductVersion here because our build pipeline puts more rich information in it (like the branch name)
|
||||
// than in the unlocalized numeric version fields.
|
||||
WCHAR* pProductVersion{ nullptr };
|
||||
UINT versionLen{ 0 };
|
||||
const auto localizedVersionName{ wil::str_printf<std::wstring>(L"\\StringFileInfo\\%04x%04x\\ProductVersion",
|
||||
pVarLocalization->language ? pVarLocalization->language : 0x0409, // well-known en-US LCID
|
||||
pVarLocalization->codepage) };
|
||||
THROW_IF_WIN32_BOOL_FALSE(VerQueryValueW(versionBuffer.get(), localizedVersionName.c_str(), reinterpret_cast<void**>(&pProductVersion), &versionLen));
|
||||
return { pProductVersion };
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return RS_(L"ApplicationVersionUnknown");
|
||||
}
|
||||
@@ -19,6 +19,7 @@ Author(s):
|
||||
|
||||
#include "CascadiaSettings.g.h"
|
||||
|
||||
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
|
||||
#include "GlobalAppSettings.h"
|
||||
#include "TerminalWarnings.h"
|
||||
#include "IDynamicProfileGenerator.h"
|
||||
@@ -27,12 +28,13 @@ Author(s):
|
||||
#include "ColorScheme.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class DeserializationTests;
|
||||
class SettingsTests;
|
||||
class ProfileTests;
|
||||
class ColorSchemeTests;
|
||||
class KeyBindingsTests;
|
||||
class TabTests;
|
||||
};
|
||||
namespace TerminalAppUnitTests
|
||||
{
|
||||
@@ -40,62 +42,61 @@ namespace TerminalAppUnitTests
|
||||
class JsonTests;
|
||||
};
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
class SettingsTypedDeserializationException;
|
||||
};
|
||||
|
||||
class Microsoft::Terminal::Settings::Model::SettingsTypedDeserializationException final : public std::runtime_error
|
||||
class TerminalApp::SettingsTypedDeserializationException final : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
SettingsTypedDeserializationException(const std::string_view description) :
|
||||
runtime_error(description.data()) {}
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct CascadiaSettings : CascadiaSettingsT<CascadiaSettings>
|
||||
{
|
||||
public:
|
||||
CascadiaSettings();
|
||||
explicit CascadiaSettings(const bool addDynamicProfiles);
|
||||
CascadiaSettings(hstring json);
|
||||
Model::CascadiaSettings Copy() const;
|
||||
|
||||
static Model::CascadiaSettings LoadDefaults();
|
||||
static Model::CascadiaSettings LoadAll();
|
||||
static Model::CascadiaSettings LoadUniversal();
|
||||
static TerminalApp::CascadiaSettings LoadDefaults();
|
||||
static TerminalApp::CascadiaSettings LoadAll();
|
||||
static TerminalApp::CascadiaSettings LoadUniversal();
|
||||
|
||||
Model::GlobalAppSettings GlobalSettings() const;
|
||||
Windows::Foundation::Collections::IObservableVector<Model::Profile> Profiles() const noexcept;
|
||||
Model::KeyMapping KeyMap() const noexcept;
|
||||
TerminalApp::GlobalAppSettings GlobalSettings() const;
|
||||
|
||||
static com_ptr<CascadiaSettings> FromJson(const Json::Value& json);
|
||||
Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Profile> Profiles() const noexcept;
|
||||
|
||||
TerminalApp::KeyMapping KeyMap() const noexcept;
|
||||
|
||||
static std::unique_ptr<CascadiaSettings> FromJson(const Json::Value& json);
|
||||
void LayerJson(const Json::Value& json);
|
||||
|
||||
static hstring SettingsPath();
|
||||
static hstring DefaultSettingsPath();
|
||||
static std::filesystem::path GetSettingsPath();
|
||||
static std::filesystem::path GetDefaultSettingsPath();
|
||||
|
||||
static winrt::hstring ApplicationDisplayName();
|
||||
static winrt::hstring ApplicationVersion();
|
||||
|
||||
Model::Profile FindProfile(guid profileGuid) const noexcept;
|
||||
Model::ColorScheme GetColorSchemeForProfile(const guid profileGuid) const;
|
||||
TerminalApp::Profile FindProfile(guid profileGuid) const noexcept;
|
||||
TerminalApp::ColorScheme GetColorSchemeForProfile(const guid profileGuid) const;
|
||||
|
||||
Windows::Foundation::Collections::IVectorView<SettingsLoadWarnings> Warnings();
|
||||
void ClearWarnings();
|
||||
void AppendWarning(SettingsLoadWarnings warning);
|
||||
Windows::Foundation::IReference<SettingsLoadErrors> GetLoadingError();
|
||||
hstring GetSerializationErrorMessage();
|
||||
|
||||
winrt::guid GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const;
|
||||
winrt::guid GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const;
|
||||
|
||||
private:
|
||||
com_ptr<GlobalAppSettings> _globals;
|
||||
Windows::Foundation::Collections::IObservableVector<Model::Profile> _profiles;
|
||||
Windows::Foundation::Collections::IVector<Model::SettingsLoadWarnings> _warnings;
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Profile> _profiles;
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::SettingsLoadWarnings> _warnings;
|
||||
Windows::Foundation::IReference<SettingsLoadErrors> _loadError;
|
||||
hstring _deserializationErrorMessage;
|
||||
|
||||
std::vector<std::unique_ptr<::Microsoft::Terminal::Settings::Model::IDynamicProfileGenerator>> _profileGenerators;
|
||||
std::vector<std::unique_ptr<::TerminalApp::IDynamicProfileGenerator>> _profileGenerators;
|
||||
|
||||
std::string _userSettingsString;
|
||||
Json::Value _userSettings;
|
||||
@@ -103,9 +104,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
Json::Value _userDefaultProfileSettings{ Json::Value::null };
|
||||
|
||||
void _LayerOrCreateProfile(const Json::Value& profileJson);
|
||||
winrt::com_ptr<implementation::Profile> _FindMatchingProfile(const Json::Value& profileJson);
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::Profile> _FindMatchingProfile(const Json::Value& profileJson);
|
||||
void _LayerOrCreateColorScheme(const Json::Value& schemeJson);
|
||||
winrt::com_ptr<implementation::ColorScheme> _FindMatchingColorScheme(const Json::Value& schemeJson);
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::ColorScheme> _FindMatchingColorScheme(const Json::Value& schemeJson);
|
||||
void _ParseJsonString(std::string_view fileData, const bool isDefaultSettings);
|
||||
static const Json::Value& _GetProfilesJsonObject(const Json::Value& json);
|
||||
static const Json::Value& _GetDisabledProfileSourcesJsonObject(const Json::Value& json);
|
||||
@@ -138,16 +139,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
void _ValidateKeybindings();
|
||||
void _ValidateNoGlobalsKey();
|
||||
|
||||
friend class SettingsModelLocalTests::DeserializationTests;
|
||||
friend class SettingsModelLocalTests::ProfileTests;
|
||||
friend class SettingsModelLocalTests::ColorSchemeTests;
|
||||
friend class SettingsModelLocalTests::KeyBindingsTests;
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::ProfileTests;
|
||||
friend class TerminalAppLocalTests::ColorSchemeTests;
|
||||
friend class TerminalAppLocalTests::KeyBindingsTests;
|
||||
friend class TerminalAppLocalTests::TabTests;
|
||||
friend class TerminalAppUnitTests::DynamicProfileTests;
|
||||
friend class TerminalAppUnitTests::JsonTests;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(CascadiaSettings);
|
||||
}
|
||||
@@ -5,22 +5,13 @@ import "GlobalAppSettings.idl";
|
||||
import "Profile.idl";
|
||||
import "TerminalWarnings.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass CascadiaSettings {
|
||||
CascadiaSettings(String json);
|
||||
CascadiaSettings Copy();
|
||||
|
||||
static CascadiaSettings LoadDefaults();
|
||||
static CascadiaSettings LoadAll();
|
||||
static CascadiaSettings LoadUniversal();
|
||||
|
||||
static String SettingsPath { get; };
|
||||
static String DefaultSettingsPath { get; };
|
||||
|
||||
static String ApplicationDisplayName { get; };
|
||||
static String ApplicationVersion { get; };
|
||||
|
||||
GlobalAppSettings GlobalSettings { get; };
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<Profile> Profiles { get; };
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <argb.h>
|
||||
#include "CascadiaSettings.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
#include "JsonUtils.h"
|
||||
#include <appmodel.h>
|
||||
#include <shlobj.h>
|
||||
@@ -18,7 +18,7 @@
|
||||
// Both defaults.h and userDefaults.h are generated at build time into the
|
||||
// "Generated Files" directory.
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace winrt::TerminalApp::implementation;
|
||||
using namespace ::Microsoft::Console;
|
||||
|
||||
static constexpr std::wstring_view SettingsFilename{ L"settings.json" };
|
||||
@@ -100,12 +100,13 @@ static void _CatchRethrowSerializationExceptionWithLocationInfo(std::string_view
|
||||
// profiles inserted into their list of profiles.
|
||||
// Return Value:
|
||||
// - a unique_ptr containing a new CascadiaSettings object.
|
||||
winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::LoadAll()
|
||||
winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
auto settings = LoadDefaults();
|
||||
auto resultPtr = winrt::get_self<CascadiaSettings>(settings);
|
||||
resultPtr->ClearWarnings();
|
||||
|
||||
// GH 3588, we need this below to know if the user chose something that wasn't our default.
|
||||
// Collect it up here in case it gets modified by any of the other layers between now and when
|
||||
@@ -185,7 +186,14 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
// We should re-parse, but not re-layer
|
||||
resultPtr->_ParseJsonString(resultPtr->_userSettingsString, false);
|
||||
|
||||
_WriteSettings(resultPtr->_userSettingsString);
|
||||
try
|
||||
{
|
||||
_WriteSettings(resultPtr->_userSettingsString);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resultPtr->AppendWarning(SettingsLoadWarnings::FailedToWriteToSettings);
|
||||
}
|
||||
}
|
||||
|
||||
// If this throws, the app will catch it and use the default settings
|
||||
@@ -195,7 +203,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
// Do it after everything else so it won't happen unless validation passed.
|
||||
// Also, avoid processing unless someone's listening for measures. The keybindings work, at least,
|
||||
// is a lot of computation we can skip if no one cares.
|
||||
if (TraceLoggingProviderEnabled(g_hSettingsModelProvider, 0, MICROSOFT_KEYWORD_MEASURES))
|
||||
if (TraceLoggingProviderEnabled(g_hTerminalAppProvider, 0, MICROSOFT_KEYWORD_MEASURES))
|
||||
{
|
||||
const auto guid = resultPtr->GlobalSettings().DefaultProfile();
|
||||
|
||||
@@ -204,7 +212,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
if (hardcodedDefaultGuid != guid)
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hSettingsModelProvider, // handle to TerminalApp tracelogging provider
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"CustomDefaultProfile",
|
||||
TraceLoggingDescription("Event emitted when user has chosen a different default profile than hardcoded one on load/reload"),
|
||||
TraceLoggingGuid(guid, "DefaultProfile", "ID of user-chosen default profile"),
|
||||
@@ -233,7 +241,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
const auto keybindingsString = Json::writeString(wbuilder, value);
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hSettingsModelProvider, // handle to TerminalApp tracelogging provider
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"CustomKeybindings",
|
||||
TraceLoggingDescription("Event emitted when custom keybindings are identified on load/reload"),
|
||||
TraceLoggingUtf8String(keybindingsString.c_str(), "Keybindings", "Keybindings as JSON"),
|
||||
@@ -265,7 +273,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a unique_ptr to a CascadiaSettings with the connection types and settings for Universal terminal
|
||||
winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::LoadUniversal()
|
||||
winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadUniversal()
|
||||
{
|
||||
// We're going to do this ourselves because we want to exclude almost everything
|
||||
// from the special Universal-for-developers configuration
|
||||
@@ -305,7 +313,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a unique_ptr to a CascadiaSettings with the settings from defaults.json
|
||||
winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::LoadDefaults()
|
||||
winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadDefaults()
|
||||
{
|
||||
auto resultPtr{ winrt::make_self<CascadiaSettings>() };
|
||||
|
||||
@@ -472,6 +480,8 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings()
|
||||
// * Serialize that diff
|
||||
// * Insert that diff to the end of the list of profiles.
|
||||
|
||||
const Profile defaultProfile;
|
||||
|
||||
Json::StreamWriterBuilder wbuilder;
|
||||
// Use 4 spaces to indent instead of \t
|
||||
wbuilder.settings_["indentation"] = " ";
|
||||
@@ -482,7 +492,7 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings()
|
||||
{
|
||||
if (profileJson.isObject())
|
||||
{
|
||||
const auto profileImpl = winrt::get_self<implementation::Profile>(profile);
|
||||
const auto profileImpl = winrt::get_self<winrt::TerminalApp::implementation::Profile>(profile);
|
||||
if (profileImpl->ShouldBeLayered(profileJson))
|
||||
{
|
||||
return true;
|
||||
@@ -533,7 +543,7 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings()
|
||||
|
||||
// Generate a diff for the profile, that contains the minimal set of
|
||||
// changes to re-create this profile.
|
||||
const auto profileImpl = winrt::get_self<implementation::Profile>(profile);
|
||||
const auto profileImpl = winrt::get_self<winrt::TerminalApp::implementation::Profile>(profile);
|
||||
const auto diff = profileImpl->GenerateStub();
|
||||
auto profileSerialization = Json::writeString(wbuilder, diff);
|
||||
|
||||
@@ -571,9 +581,9 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings()
|
||||
// - json: an object which should be a serialization of a CascadiaSettings object.
|
||||
// Return Value:
|
||||
// - a new CascadiaSettings instance created from the values in `json`
|
||||
winrt::com_ptr<CascadiaSettings> CascadiaSettings::FromJson(const Json::Value& json)
|
||||
std::unique_ptr<CascadiaSettings> CascadiaSettings::FromJson(const Json::Value& json)
|
||||
{
|
||||
auto resultPtr = winrt::make_self<CascadiaSettings>();
|
||||
auto resultPtr = std::make_unique<CascadiaSettings>();
|
||||
resultPtr->LayerJson(json);
|
||||
return resultPtr;
|
||||
}
|
||||
@@ -791,7 +801,7 @@ bool CascadiaSettings::_IsPackaged()
|
||||
// fail to write the file
|
||||
void CascadiaSettings::_WriteSettings(const std::string_view content)
|
||||
{
|
||||
auto pathToSettingsFile{ CascadiaSettings::SettingsPath() };
|
||||
auto pathToSettingsFile{ CascadiaSettings::GetSettingsPath() };
|
||||
|
||||
wil::unique_hfile hOut{ CreateFileW(pathToSettingsFile.c_str(),
|
||||
GENERIC_WRITE,
|
||||
@@ -818,7 +828,7 @@ void CascadiaSettings::_WriteSettings(const std::string_view content)
|
||||
// from reading the file
|
||||
std::optional<std::string> CascadiaSettings::_ReadUserSettings()
|
||||
{
|
||||
const auto pathToSettingsFile{ CascadiaSettings::SettingsPath() };
|
||||
const auto pathToSettingsFile{ CascadiaSettings::GetSettingsPath() };
|
||||
wil::unique_hfile hFile{ CreateFileW(pathToSettingsFile.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
@@ -832,7 +842,7 @@ std::optional<std::string> CascadiaSettings::_ReadUserSettings()
|
||||
// GH#5186 - We moved from profiles.json to settings.json; we want to
|
||||
// migrate any file we find. We're using MoveFile in case their settings.json
|
||||
// is a symbolic link.
|
||||
std::filesystem::path pathToLegacySettingsFile{ std::wstring_view{ pathToSettingsFile } };
|
||||
auto pathToLegacySettingsFile{ pathToSettingsFile };
|
||||
pathToLegacySettingsFile.replace_filename(LegacySettingsFilename);
|
||||
|
||||
wil::unique_hfile hLegacyFile{ CreateFileW(pathToLegacySettingsFile.c_str(),
|
||||
@@ -916,7 +926,7 @@ std::optional<std::string> CascadiaSettings::_ReadFile(HANDLE hFile)
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the full path to the settings file
|
||||
winrt::hstring CascadiaSettings::SettingsPath()
|
||||
std::filesystem::path CascadiaSettings::GetSettingsPath()
|
||||
{
|
||||
wil::unique_cotaskmem_string localAppDataFolder;
|
||||
// KF_FLAG_FORCE_APP_DATA_REDIRECTION, when engaged, causes SHGet... to return
|
||||
@@ -934,10 +944,10 @@ winrt::hstring CascadiaSettings::SettingsPath()
|
||||
// Create the directory if it doesn't exist
|
||||
std::filesystem::create_directories(parentDirectoryForSettingsFile);
|
||||
|
||||
return winrt::hstring{ (parentDirectoryForSettingsFile / SettingsFilename).wstring() };
|
||||
return parentDirectoryForSettingsFile / SettingsFilename;
|
||||
}
|
||||
|
||||
winrt::hstring CascadiaSettings::DefaultSettingsPath()
|
||||
std::filesystem::path CascadiaSettings::GetDefaultSettingsPath()
|
||||
{
|
||||
// Both of these posts suggest getting the path to the exe, then removing
|
||||
// the exe's name to get the package root:
|
||||
@@ -957,7 +967,7 @@ winrt::hstring CascadiaSettings::DefaultSettingsPath()
|
||||
|
||||
const std::filesystem::path exePath{ exePathString };
|
||||
const std::filesystem::path rootDir = exePath.parent_path();
|
||||
return winrt::hstring{ (rootDir / DefaultsFilename).wstring() };
|
||||
return rootDir / DefaultsFilename;
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
@@ -129,7 +129,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
<ColorPicker x:Name="customColorPicker"
|
||||
IsMoreButtonVisible="True"
|
||||
IsColorSliderVisible="False"
|
||||
IsColorSliderVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsAlphaEnabled="False"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include "ColorScheme.g.cpp"
|
||||
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp::implementation;
|
||||
using namespace winrt::Windows::UI;
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
@@ -20,7 +20,6 @@ static constexpr std::string_view ForegroundKey{ "foreground" };
|
||||
static constexpr std::string_view BackgroundKey{ "background" };
|
||||
static constexpr std::string_view SelectionBackgroundKey{ "selectionBackground" };
|
||||
static constexpr std::string_view CursorColorKey{ "cursorColor" };
|
||||
|
||||
static constexpr std::array<std::string_view, 16> TableColors = {
|
||||
"black",
|
||||
"red",
|
||||
@@ -41,32 +40,27 @@ static constexpr std::array<std::string_view, 16> TableColors = {
|
||||
};
|
||||
|
||||
ColorScheme::ColorScheme() :
|
||||
_Foreground{ DEFAULT_FOREGROUND_WITH_ALPHA },
|
||||
_Background{ DEFAULT_BACKGROUND_WITH_ALPHA },
|
||||
_SelectionBackground{ DEFAULT_FOREGROUND },
|
||||
_CursorColor{ DEFAULT_CURSOR_COLOR }
|
||||
_schemeName{ L"" },
|
||||
_table{},
|
||||
_defaultForeground{ DEFAULT_FOREGROUND_WITH_ALPHA },
|
||||
_defaultBackground{ DEFAULT_BACKGROUND_WITH_ALPHA },
|
||||
_selectionBackground{ DEFAULT_FOREGROUND },
|
||||
_cursorColor{ DEFAULT_CURSOR_COLOR }
|
||||
{
|
||||
}
|
||||
|
||||
ColorScheme::ColorScheme(winrt::hstring name, Color defaultFg, Color defaultBg, Color cursorColor) :
|
||||
_Name{ name },
|
||||
_Foreground{ defaultFg },
|
||||
_Background{ defaultBg },
|
||||
_SelectionBackground{ DEFAULT_FOREGROUND },
|
||||
_CursorColor{ cursorColor }
|
||||
_schemeName{ name },
|
||||
_table{},
|
||||
_defaultForeground{ defaultFg },
|
||||
_defaultBackground{ defaultBg },
|
||||
_selectionBackground{ DEFAULT_FOREGROUND },
|
||||
_cursorColor{ cursorColor }
|
||||
{
|
||||
}
|
||||
|
||||
winrt::com_ptr<ColorScheme> ColorScheme::Copy() const
|
||||
ColorScheme::~ColorScheme()
|
||||
{
|
||||
auto scheme{ winrt::make_self<ColorScheme>() };
|
||||
scheme->_Name = _Name;
|
||||
scheme->_Foreground = _Foreground;
|
||||
scheme->_Background = _Background;
|
||||
scheme->_SelectionBackground = _SelectionBackground;
|
||||
scheme->_CursorColor = _CursorColor;
|
||||
scheme->_table = _table;
|
||||
return scheme;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -95,7 +89,7 @@ bool ColorScheme::ShouldBeLayered(const Json::Value& json) const
|
||||
std::wstring nameFromJson{};
|
||||
if (JsonUtils::GetValueForKey(json, NameKey, nameFromJson))
|
||||
{
|
||||
return nameFromJson == _Name;
|
||||
return nameFromJson == _schemeName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -112,60 +106,50 @@ bool ColorScheme::ShouldBeLayered(const Json::Value& json) const
|
||||
// <none>
|
||||
void ColorScheme::LayerJson(const Json::Value& json)
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, NameKey, _Name);
|
||||
JsonUtils::GetValueForKey(json, ForegroundKey, _Foreground);
|
||||
JsonUtils::GetValueForKey(json, BackgroundKey, _Background);
|
||||
JsonUtils::GetValueForKey(json, SelectionBackgroundKey, _SelectionBackground);
|
||||
JsonUtils::GetValueForKey(json, CursorColorKey, _CursorColor);
|
||||
JsonUtils::GetValueForKey(json, NameKey, _schemeName);
|
||||
JsonUtils::GetValueForKey(json, ForegroundKey, _defaultForeground);
|
||||
JsonUtils::GetValueForKey(json, BackgroundKey, _defaultBackground);
|
||||
JsonUtils::GetValueForKey(json, SelectionBackgroundKey, _selectionBackground);
|
||||
JsonUtils::GetValueForKey(json, CursorColorKey, _cursorColor);
|
||||
|
||||
for (unsigned int i = 0; i < TableColors.size(); ++i)
|
||||
int i = 0;
|
||||
for (const auto& current : TableColors)
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, til::at(TableColors, i), _table.at(i));
|
||||
JsonUtils::GetValueForKey(json, current, _table.at(i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a new serialized JsonObject from an instance of this class
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// <none>
|
||||
Json::Value ColorScheme::ToJson()
|
||||
winrt::hstring ColorScheme::Name() const noexcept
|
||||
{
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, NameKey, _Name);
|
||||
JsonUtils::SetValueForKey(json, ForegroundKey, _Foreground);
|
||||
JsonUtils::SetValueForKey(json, BackgroundKey, _Background);
|
||||
JsonUtils::SetValueForKey(json, SelectionBackgroundKey, _SelectionBackground);
|
||||
JsonUtils::SetValueForKey(json, CursorColorKey, _CursorColor);
|
||||
|
||||
for (unsigned int i = 0; i < TableColors.size(); ++i)
|
||||
{
|
||||
JsonUtils::SetValueForKey(json, til::at(TableColors, i), _table.at(i));
|
||||
}
|
||||
|
||||
return json;
|
||||
return _schemeName;
|
||||
}
|
||||
|
||||
winrt::com_array<Color> ColorScheme::Table() const noexcept
|
||||
{
|
||||
winrt::com_array<Color> result{ base::checked_cast<uint32_t>(_table.size()) };
|
||||
winrt::com_array<Color> result{ COLOR_TABLE_SIZE };
|
||||
std::transform(_table.begin(), _table.end(), result.begin(), [](til::color c) -> Color { return c; });
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Set a color in the color table
|
||||
// Arguments:
|
||||
// - index: the index of the desired color within the table
|
||||
// - value: the color value we are setting the color table color to
|
||||
// Return Value:
|
||||
// - none
|
||||
void ColorScheme::SetColorTableEntry(uint8_t index, const winrt::Windows::UI::Color& value) noexcept
|
||||
Color ColorScheme::Foreground() const noexcept
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, index > _table.size() - 1);
|
||||
_table[index] = value;
|
||||
return _defaultForeground;
|
||||
}
|
||||
|
||||
Color ColorScheme::Background() const noexcept
|
||||
{
|
||||
return _defaultBackground;
|
||||
}
|
||||
|
||||
Color ColorScheme::SelectionBackground() const noexcept
|
||||
{
|
||||
return _selectionBackground;
|
||||
}
|
||||
|
||||
Color ColorScheme::CursorColor() const noexcept
|
||||
{
|
||||
return _cursorColor;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -21,42 +21,48 @@ Author(s):
|
||||
#include "ColorScheme.g.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class SettingsTests;
|
||||
class ColorSchemeTests;
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct ColorScheme : ColorSchemeT<ColorScheme>
|
||||
{
|
||||
public:
|
||||
ColorScheme();
|
||||
ColorScheme(hstring name, Windows::UI::Color defaultFg, Windows::UI::Color defaultBg, Windows::UI::Color cursorColor);
|
||||
com_ptr<ColorScheme> Copy() const;
|
||||
~ColorScheme();
|
||||
|
||||
static com_ptr<ColorScheme> FromJson(const Json::Value& json);
|
||||
bool ShouldBeLayered(const Json::Value& json) const;
|
||||
void LayerJson(const Json::Value& json);
|
||||
|
||||
Json::Value ToJson();
|
||||
hstring Name() const noexcept;
|
||||
com_array<Windows::UI::Color> Table() const noexcept;
|
||||
Windows::UI::Color Foreground() const noexcept;
|
||||
Windows::UI::Color Background() const noexcept;
|
||||
Windows::UI::Color SelectionBackground() const noexcept;
|
||||
Windows::UI::Color CursorColor() const noexcept;
|
||||
|
||||
static std::optional<std::wstring> GetNameFromJson(const Json::Value& json);
|
||||
|
||||
com_array<Windows::UI::Color> Table() const noexcept;
|
||||
void SetColorTableEntry(uint8_t index, const winrt::Windows::UI::Color& value) noexcept;
|
||||
|
||||
GETSET_PROPERTY(winrt::hstring, Name);
|
||||
GETSET_COLORPROPERTY(Foreground); // defined in constructor
|
||||
GETSET_COLORPROPERTY(Background); // defined in constructor
|
||||
GETSET_COLORPROPERTY(SelectionBackground); // defined in constructor
|
||||
GETSET_COLORPROPERTY(CursorColor); // defined in constructor
|
||||
|
||||
private:
|
||||
hstring _schemeName;
|
||||
std::array<til::color, COLOR_TABLE_SIZE> _table;
|
||||
til::color _defaultForeground;
|
||||
til::color _defaultBackground;
|
||||
til::color _selectionBackground;
|
||||
til::color _cursorColor;
|
||||
|
||||
friend class SettingsModelLocalTests::SettingsTests;
|
||||
friend class SettingsModelLocalTests::ColorSchemeTests;
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::ColorSchemeTests;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ColorScheme);
|
||||
}
|
||||
19
src/cascadia/TerminalApp/ColorScheme.idl
Normal file
19
src/cascadia/TerminalApp/ColorScheme.idl
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass ColorScheme {
|
||||
ColorScheme();
|
||||
ColorScheme(String name, Windows.UI.Color defaultFg, Windows.UI.Color defaultBg, Windows.UI.Color cursorColor);
|
||||
|
||||
String Name { get; };
|
||||
|
||||
Windows.UI.Color Foreground { get; };
|
||||
Windows.UI.Color Background { get; };
|
||||
Windows.UI.Color SelectionBackground { get; };
|
||||
Windows.UI.Color CursorColor { get; };
|
||||
|
||||
Windows.UI.Color[] Table { get; };
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,15 @@
|
||||
#include "Command.h"
|
||||
#include "Command.g.cpp"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "ActionAndArgs.h"
|
||||
#include "JsonUtils.h"
|
||||
#include <LibraryResources.h>
|
||||
#include "TerminalSettingsSerializationHelpers.h"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace ::TerminalApp;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
@@ -31,41 +32,19 @@ static constexpr std::string_view ProfileNameToken{ "${profile.name}" };
|
||||
static constexpr std::string_view ProfileIconToken{ "${profile.icon}" };
|
||||
static constexpr std::string_view SchemeNameToken{ "${scheme.name}" };
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
Command::Command()
|
||||
{
|
||||
_setAction(nullptr);
|
||||
}
|
||||
|
||||
com_ptr<Command> Command::Copy() const
|
||||
{
|
||||
auto command{ winrt::make_self<Command>() };
|
||||
command->_Name = _Name;
|
||||
command->_Action = _Action;
|
||||
command->_KeyChordText = _KeyChordText;
|
||||
command->_Icon = _Icon;
|
||||
command->_IterateOn = _IterateOn;
|
||||
|
||||
command->_originalJson = _originalJson;
|
||||
if (HasNestedCommands())
|
||||
{
|
||||
command->_subcommands = winrt::single_threaded_map<winrt::hstring, Model::Command>();
|
||||
for (auto kv : NestedCommands())
|
||||
{
|
||||
const auto subCmd{ winrt::get_self<Command>(kv.Value()) };
|
||||
command->_subcommands.Insert(kv.Key(), *subCmd->Copy());
|
||||
}
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
IMapView<winrt::hstring, Model::Command> Command::NestedCommands() const
|
||||
Collections::IMapView<winrt::hstring, TerminalApp::Command> Command::NestedCommands()
|
||||
{
|
||||
return _subcommands ? _subcommands.GetView() : nullptr;
|
||||
}
|
||||
|
||||
bool Command::HasNestedCommands() const
|
||||
bool Command::HasNestedCommands()
|
||||
{
|
||||
return _subcommands ? _subcommands.Size() > 0 : false;
|
||||
}
|
||||
@@ -128,6 +107,70 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return actionAndArgs->GenerateName();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Actually initialize our IconSource for our _lastIconPath. Supports a variety of icons:
|
||||
// * If the icon is a path to an image, we'll use that.
|
||||
// * If it isn't, then we'll try and use the text as a FontIcon. If the
|
||||
// character is in the range of symbols reserved for the Segoe MDL2
|
||||
// Asserts, well treat it as such. Otherwise, we'll default to a Sego
|
||||
// UI icon, so things like emoji will work.
|
||||
// - MUST BE CALLED ON THE UI THREAD.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Command::RefreshIcon()
|
||||
{
|
||||
if (!_lastIconPath.empty())
|
||||
{
|
||||
_setIconSource(GetColoredIcon<winrt::WUX::Controls::IconSource>(_lastIconPath));
|
||||
|
||||
// If we fail to set the icon source using the "icon" as a path,
|
||||
// let's try it as a symbol/emoji.
|
||||
//
|
||||
// Anything longer that 2 wchar_t's _isn't_ an emoji or symbol, so
|
||||
// don't do this if it's just an invalid path.
|
||||
if (IconSource() == nullptr && _lastIconPath.size() <= 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
WUX::Controls::FontIconSource icon;
|
||||
const wchar_t ch = _lastIconPath[0];
|
||||
|
||||
// The range of MDL2 Icons isn't explicitly defined, but
|
||||
// we're using this based off the table on:
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font
|
||||
const bool isMDL2Icon = ch >= L'\uE700' && ch <= L'\uF8FF';
|
||||
if (isMDL2Icon)
|
||||
{
|
||||
icon.FontFamily(WUX::Media::FontFamily{ L"Segoe MDL2 Assets" });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: you _do_ need to manually set the font here.
|
||||
icon.FontFamily(WUX::Media::FontFamily{ L"Segoe UI" });
|
||||
}
|
||||
icon.FontSize(12);
|
||||
icon.Glyph(_lastIconPath);
|
||||
_setIconSource(icon);
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
if (IconSource() == nullptr)
|
||||
{
|
||||
// Set the default IconSource to a BitmapIconSource with a null source
|
||||
// (instead of just nullptr) because there's a really weird crash when swapping
|
||||
// data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette).
|
||||
// Swapping between nullptr IconSources and non-null IconSources causes a crash
|
||||
// to occur, but swapping between IconSources with a null source and non-null IconSources
|
||||
// work perfectly fine :shrug:.
|
||||
winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon;
|
||||
icon.UriSource(nullptr);
|
||||
_setIconSource(icon);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Deserialize a Command from the `json` object. The json object should
|
||||
// contain a "name" and "action", and optionally an "icon".
|
||||
@@ -157,7 +200,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
if (const auto nestedCommandsJson{ json[JsonKey(CommandsKey)] })
|
||||
{
|
||||
// Initialize our list of subcommands.
|
||||
result->_subcommands = winrt::single_threaded_map<winrt::hstring, Model::Command>();
|
||||
result->_subcommands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
auto nestedWarnings = Command::LayerJson(result->_subcommands, nestedCommandsJson);
|
||||
// It's possible that the nested commands have some warnings
|
||||
warnings.insert(warnings.end(), nestedWarnings.begin(), nestedWarnings.end());
|
||||
@@ -171,7 +214,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JsonUtils::GetValueForKey(json, IconKey, result->_Icon);
|
||||
// Only get the icon path right now. The icon needs to be resolved into
|
||||
// an IconSource on the UI thread, which will be done by RefreshIcon.
|
||||
JsonUtils::GetValueForKey(json, IconKey, result->_lastIconPath);
|
||||
|
||||
// If we're a nested command, we can ignore the current action.
|
||||
if (!nested)
|
||||
@@ -235,7 +280,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// - json: A Json::Value containing an array of serialized commands
|
||||
// Return Value:
|
||||
// - A vector containing any warnings detected while parsing
|
||||
std::vector<SettingsLoadWarnings> Command::LayerJson(IMap<winrt::hstring, Model::Command>& commands,
|
||||
std::vector<SettingsLoadWarnings> Command::LayerJson(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
|
||||
const Json::Value& json)
|
||||
{
|
||||
std::vector<SettingsLoadWarnings> warnings;
|
||||
@@ -307,13 +352,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// appended to this vector.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Command::ExpandCommands(IMap<winrt::hstring, Model::Command> commands,
|
||||
IVectorView<Model::Profile> profiles,
|
||||
IVectorView<Model::ColorScheme> schemes,
|
||||
IVector<SettingsLoadWarnings> warnings)
|
||||
void Command::ExpandCommands(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
|
||||
Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles,
|
||||
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
|
||||
std::vector<SettingsLoadWarnings>& warnings)
|
||||
{
|
||||
std::vector<winrt::hstring> commandsToRemove;
|
||||
std::vector<Model::Command> commandsToAdd;
|
||||
std::vector<winrt::TerminalApp::Command> commandsToAdd;
|
||||
|
||||
// First, collect up all the commands that need replacing.
|
||||
for (const auto& nameAndCmd : commands)
|
||||
@@ -363,12 +408,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// Return Value:
|
||||
// - and empty vector if the command wasn't expandable, otherwise a list of
|
||||
// the newly-created commands.
|
||||
std::vector<Model::Command> Command::_expandCommand(Command* const expandable,
|
||||
IVectorView<Model::Profile> profiles,
|
||||
IVectorView<Model::ColorScheme> schemes,
|
||||
IVector<SettingsLoadWarnings>& warnings)
|
||||
std::vector<winrt::TerminalApp::Command> Command::_expandCommand(Command* const expandable,
|
||||
Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles,
|
||||
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
|
||||
std::vector<SettingsLoadWarnings>& warnings)
|
||||
{
|
||||
std::vector<Model::Command> newCommands;
|
||||
std::vector<winrt::TerminalApp::Command> newCommands;
|
||||
|
||||
if (expandable->HasNestedCommands())
|
||||
{
|
||||
@@ -393,18 +438,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
const auto actualDataEnd = newJsonString.data() + newJsonString.size();
|
||||
if (!reader->parse(actualDataStart, actualDataEnd, &newJsonValue, &errs))
|
||||
{
|
||||
warnings.Append(SettingsLoadWarnings::FailedToParseCommandJson);
|
||||
warnings.push_back(SettingsLoadWarnings::FailedToParseCommandJson);
|
||||
// If we encounter a re-parsing error, just stop processing the rest of the commands.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pass the new json back though FromJson, to get the new expanded value.
|
||||
std::vector<SettingsLoadWarnings> newWarnings;
|
||||
if (auto newCmd{ Command::FromJson(newJsonValue, newWarnings) })
|
||||
if (auto newCmd{ Command::FromJson(newJsonValue, warnings) })
|
||||
{
|
||||
newCommands.push_back(*newCmd);
|
||||
}
|
||||
std::for_each(newWarnings.begin(), newWarnings.end(), [warnings](auto& warn) { warnings.Append(warn); });
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -424,7 +467,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
// - Escape the profile name for JSON appropriately
|
||||
auto escapedProfileName = _escapeForJson(til::u16u8(p.Name()));
|
||||
auto escapedProfileIcon = _escapeForJson(til::u16u8(p.Icon()));
|
||||
auto escapedProfileIcon = _escapeForJson(til::u16u8(p.ExpandedIconPath()));
|
||||
auto newJsonString = til::replace_needle_in_haystack(oldJsonString,
|
||||
ProfileNameToken,
|
||||
escapedProfileName);
|
||||
83
src/cascadia/TerminalApp/Command.h
Normal file
83
src/cascadia/TerminalApp/Command.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- Command.h
|
||||
|
||||
Abstract:
|
||||
- A command represents a single entry in the Command Palette. This is an object
|
||||
that has a user facing "name" to display to the user, and an associated action
|
||||
which can be dispatched.
|
||||
|
||||
- For more information, see GH#2046, #5400, #5674, and #6635
|
||||
|
||||
Author(s):
|
||||
- Mike Griese - June 2020
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "Command.g.h"
|
||||
#include "TerminalWarnings.h"
|
||||
#include "Profile.h"
|
||||
#include "..\inc\cppwinrt_utils.h"
|
||||
#include "SettingsTypes.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class SettingsTests;
|
||||
class CommandTests;
|
||||
};
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct Command : CommandT<Command>
|
||||
{
|
||||
Command();
|
||||
|
||||
static winrt::com_ptr<Command> FromJson(const Json::Value& json,
|
||||
std::vector<TerminalApp::SettingsLoadWarnings>& warnings);
|
||||
|
||||
static void ExpandCommands(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
|
||||
Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles,
|
||||
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
|
||||
std::vector<TerminalApp::SettingsLoadWarnings>& warnings);
|
||||
|
||||
static std::vector<TerminalApp::SettingsLoadWarnings> LayerJson(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
|
||||
const Json::Value& json);
|
||||
bool HasNestedCommands();
|
||||
Windows::Foundation::Collections::IMapView<winrt::hstring, TerminalApp::Command> NestedCommands();
|
||||
|
||||
void RefreshIcon();
|
||||
|
||||
winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker;
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Name, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::TerminalApp::ActionAndArgs, Action, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr);
|
||||
|
||||
GETSET_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None);
|
||||
|
||||
private:
|
||||
Json::Value _originalJson;
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command> _subcommands{ nullptr };
|
||||
|
||||
winrt::hstring _lastIconPath{};
|
||||
|
||||
static std::vector<winrt::TerminalApp::Command> _expandCommand(Command* const expandable,
|
||||
Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles,
|
||||
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
|
||||
std::vector<TerminalApp::SettingsLoadWarnings>& warnings);
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::CommandTests;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Command);
|
||||
}
|
||||
22
src/cascadia/TerminalApp/Command.idl
Normal file
22
src/cascadia/TerminalApp/Command.idl
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "ShortcutActionDispatch.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass Command : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
Command();
|
||||
|
||||
String Name;
|
||||
ActionAndArgs Action;
|
||||
String KeyChordText;
|
||||
|
||||
Windows.UI.Xaml.Controls.IconSource IconSource;
|
||||
void RefreshIcon();
|
||||
|
||||
Boolean HasNestedCommands { get; };
|
||||
Windows.Foundation.Collections.IMapView<String, Command> NestedCommands { get; };
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "CommandPalette.h"
|
||||
#include "ActionAndArgs.h"
|
||||
#include "ActionArgs.h"
|
||||
#include "Command.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
@@ -15,7 +18,6 @@ using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
@@ -24,11 +26,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_filteredActions = winrt::single_threaded_observable_vector<Command>();
|
||||
_nestedActionStack = winrt::single_threaded_vector<Command>();
|
||||
_currentNestedCommands = winrt::single_threaded_vector<Command>();
|
||||
_allCommands = winrt::single_threaded_vector<Command>();
|
||||
_allTabActions = winrt::single_threaded_vector<Command>();
|
||||
_filteredActions = winrt::single_threaded_observable_vector<winrt::TerminalApp::Command>();
|
||||
_nestedActionStack = winrt::single_threaded_vector<winrt::TerminalApp::Command>();
|
||||
_currentNestedCommands = winrt::single_threaded_vector<winrt::TerminalApp::Command>();
|
||||
_allCommands = winrt::single_threaded_vector<winrt::TerminalApp::Command>();
|
||||
_allTabActions = winrt::single_threaded_vector<winrt::TerminalApp::Command>();
|
||||
|
||||
_switchToMode(CommandPaletteMode::ActionMode);
|
||||
|
||||
@@ -117,6 +119,90 @@ namespace winrt::TerminalApp::implementation
|
||||
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Scroll the command palette to the specified index
|
||||
// Arguments:
|
||||
// - index within a list view of commands
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::_scrollToIndex(uint32_t index)
|
||||
{
|
||||
auto numItems = _filteredActionsView().Items().Size();
|
||||
|
||||
if (numItems == 0)
|
||||
{
|
||||
// if the list is empty no need to scroll
|
||||
return;
|
||||
}
|
||||
|
||||
auto clampedIndex = std::clamp<int32_t>(index, 0, numItems - 1);
|
||||
_filteredActionsView().SelectedIndex(clampedIndex);
|
||||
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Computes the number of visible commands
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the approximate number of items visible in the list (in other words the size of the page)
|
||||
uint32_t CommandPalette::_getNumVisibleItems()
|
||||
{
|
||||
const auto container = _filteredActionsView().ContainerFromIndex(0);
|
||||
const auto item = container.try_as<winrt::Windows::UI::Xaml::Controls::ListViewItem>();
|
||||
const auto itemHeight = ::base::saturated_cast<int>(item.ActualHeight());
|
||||
const auto listHeight = ::base::saturated_cast<int>(_filteredActionsView().ActualHeight());
|
||||
return listHeight / itemHeight;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Scrolls the focus one page up the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollPageUp()
|
||||
{
|
||||
auto selected = _filteredActionsView().SelectedIndex();
|
||||
auto numVisibleItems = _getNumVisibleItems();
|
||||
_scrollToIndex(selected - numVisibleItems);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Scrolls the focus one page down the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollPageDown()
|
||||
{
|
||||
auto selected = _filteredActionsView().SelectedIndex();
|
||||
auto numVisibleItems = _getNumVisibleItems();
|
||||
_scrollToIndex(selected + numVisibleItems);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the focus to the top item in the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollToTop()
|
||||
{
|
||||
_scrollToIndex(0);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the focus to the bottom item in the list of commands.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::ScrollToBottom()
|
||||
{
|
||||
_scrollToIndex(_filteredActionsView().Items().Size() - 1);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when the command selection changes. We'll use this in the tab
|
||||
// switcher to "preview" tabs as the user navigates the list of tabs. To
|
||||
@@ -132,7 +218,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_currentMode == CommandPaletteMode::TabSwitchMode)
|
||||
{
|
||||
const auto& selectedCommand = _filteredActionsView().SelectedItem();
|
||||
if (const auto& command = selectedCommand.try_as<Command>())
|
||||
if (const auto& command = selectedCommand.try_as<TerminalApp::Command>())
|
||||
{
|
||||
const auto& actionAndArgs = command.Action();
|
||||
_dispatch.DoAction(actionAndArgs);
|
||||
@@ -193,6 +279,30 @@ namespace winrt::TerminalApp::implementation
|
||||
SelectNextItem(true);
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::PageUp)
|
||||
{
|
||||
// Action Mode: Move focus to the first visible item in the list.
|
||||
ScrollPageUp();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::PageDown)
|
||||
{
|
||||
// Action Mode: Move focus to the last visible item in the list.
|
||||
ScrollPageDown();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::Home)
|
||||
{
|
||||
// Action Mode: Move focus to the first item in the list.
|
||||
ScrollToTop();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::End)
|
||||
{
|
||||
// Action Mode: Move focus to the last item in the list.
|
||||
ScrollToBottom();
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::Enter)
|
||||
{
|
||||
// Action, TabSwitch or TabSearchMode Mode: Dispatch the action of the selected command.
|
||||
@@ -200,7 +310,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto selectedItem = _filteredActionsView().SelectedItem())
|
||||
{
|
||||
_dispatchCommand(selectedItem.try_as<Command>());
|
||||
_dispatchCommand(selectedItem.try_as<TerminalApp::Command>());
|
||||
}
|
||||
}
|
||||
// Commandline Mode: Use the input to synthesize an ExecuteCommandline action
|
||||
@@ -213,27 +323,41 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else if (key == VirtualKey::Escape)
|
||||
{
|
||||
// Dismiss the palette if the text is empty, otherwise clear the
|
||||
// search string.
|
||||
if (_searchBox().Text().empty())
|
||||
// Action, TabSearch, TabSwitch Mode: Dismiss the palette if the
|
||||
// text is empty, otherwise clear the search string.
|
||||
if (_currentMode != CommandPaletteMode::CommandlineMode)
|
||||
{
|
||||
_dismissPalette();
|
||||
if (_searchBox().Text().empty())
|
||||
{
|
||||
_dismissPalette();
|
||||
}
|
||||
else
|
||||
{
|
||||
_searchBox().Text(L"");
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_currentMode == CommandPaletteMode::CommandlineMode)
|
||||
{
|
||||
_searchBox().Text(L"");
|
||||
}
|
||||
const auto currentInput = _getPostPrefixInput();
|
||||
if (currentInput.empty())
|
||||
{
|
||||
// The user's only input "> " so far. We should just dismiss
|
||||
// the palette. This is like dismissing the Action mode with
|
||||
// empty input.
|
||||
_dismissPalette();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear out the current input. We'll leave a ">" in the
|
||||
// input (to stay in commandline mode), and a leading space
|
||||
// (if they currently had one).
|
||||
const bool hasLeadingSpace = (_searchBox().Text().size()) - (currentInput.size()) > 1;
|
||||
_searchBox().Text(hasLeadingSpace ? L"> " : L">");
|
||||
|
||||
e.Handled(true);
|
||||
}
|
||||
else if (key == VirtualKey::Back)
|
||||
{
|
||||
// If the last filter text was empty, and we're backspacing from
|
||||
// that state, then the user "backspaced" the virtual '>' we're
|
||||
// using as the action mode indicator. Switch into commandline mode.
|
||||
if (_searchBox().Text().empty() && _lastFilterTextWasEmpty && _currentMode == CommandPaletteMode::ActionMode)
|
||||
{
|
||||
_switchToMode(CommandPaletteMode::CommandlineMode);
|
||||
// This will conveniently move the cursor to the end of the
|
||||
// text input for us.
|
||||
_searchBox().Select(_searchBox().Text().size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled(true);
|
||||
@@ -309,7 +433,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto selectedItem = _filteredActionsView().SelectedItem())
|
||||
{
|
||||
if (const auto data = selectedItem.try_as<Command>())
|
||||
if (const auto data = selectedItem.try_as<TerminalApp::Command>())
|
||||
{
|
||||
_dispatchCommand(data);
|
||||
}
|
||||
@@ -356,7 +480,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_listItemClicked(Windows::Foundation::IInspectable const& /*sender*/,
|
||||
Windows::UI::Xaml::Controls::ItemClickEventArgs const& e)
|
||||
{
|
||||
_dispatchCommand(e.ClickedItem().try_as<Command>());
|
||||
_dispatchCommand(e.ClickedItem().try_as<TerminalApp::Command>());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -391,7 +515,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - A list of Commands to filter.
|
||||
Collections::IVector<Command> CommandPalette::_commandsToFilter()
|
||||
Collections::IVector<TerminalApp::Command> CommandPalette::_commandsToFilter()
|
||||
{
|
||||
switch (_currentMode)
|
||||
{
|
||||
@@ -406,7 +530,7 @@ namespace winrt::TerminalApp::implementation
|
||||
case CommandPaletteMode::TabSwitchMode:
|
||||
return _allTabActions;
|
||||
case CommandPaletteMode::CommandlineMode:
|
||||
return winrt::single_threaded_vector<Command>();
|
||||
return winrt::single_threaded_vector<TerminalApp::Command>();
|
||||
default:
|
||||
return _allCommands;
|
||||
}
|
||||
@@ -421,7 +545,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - command: the Command to dispatch. This might be null.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::_dispatchCommand(const Command& command)
|
||||
void CommandPalette::_dispatchCommand(const TerminalApp::Command& command)
|
||||
{
|
||||
if (command)
|
||||
{
|
||||
@@ -466,13 +590,18 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get all the input text in _searchBox that follows any leading spaces.
|
||||
// - Get all the input text in _searchBox that follows the prefix character
|
||||
// and any whitespace following that prefix character. This can be used in
|
||||
// commandline mode to get all the useful input that the user input after
|
||||
// the leading ">" prefix.
|
||||
// - Note that this will behave unexpectedly in Action Mode.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the string of input following any number of leading spaces
|
||||
std::wstring CommandPalette::_getTrimmedInput()
|
||||
// - the string of input following the prefix character.
|
||||
std::wstring CommandPalette::_getPostPrefixInput()
|
||||
{
|
||||
const std::wstring input{ _searchBox().Text() };
|
||||
if (input.empty())
|
||||
@@ -480,15 +609,17 @@ namespace winrt::TerminalApp::implementation
|
||||
return input;
|
||||
}
|
||||
|
||||
const auto rawCmdline{ input.substr(1) };
|
||||
|
||||
// Trim leading whitespace
|
||||
const auto firstNonSpace = input.find_first_not_of(L" ");
|
||||
const auto firstNonSpace = rawCmdline.find_first_not_of(L" ");
|
||||
if (firstNonSpace == std::wstring::npos)
|
||||
{
|
||||
// All the following characters are whitespace.
|
||||
return L"";
|
||||
}
|
||||
|
||||
return input.substr(firstNonSpace);
|
||||
return rawCmdline.substr(firstNonSpace);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -499,15 +630,19 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void CommandPalette::_dispatchCommandline()
|
||||
{
|
||||
auto cmdline{ _getTrimmedInput() };
|
||||
if (cmdline.empty())
|
||||
const auto input = _getPostPrefixInput();
|
||||
if (input.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
winrt::hstring cmdline{ input };
|
||||
|
||||
// Build the ExecuteCommandline action from the values we've parsed on the commandline.
|
||||
ExecuteCommandlineArgs args{ cmdline };
|
||||
ActionAndArgs executeActionAndArgs{ ShortcutAction::ExecuteCommandline, args };
|
||||
auto executeActionAndArgs = winrt::make_self<implementation::ActionAndArgs>();
|
||||
executeActionAndArgs->Action(ShortcutAction::ExecuteCommandline);
|
||||
auto args = winrt::make_self<implementation::ExecuteCommandlineArgs>();
|
||||
args->Commandline(cmdline);
|
||||
executeActionAndArgs->Args(*args);
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
@@ -516,7 +651,7 @@ namespace winrt::TerminalApp::implementation
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
|
||||
if (_dispatch.DoAction(executeActionAndArgs))
|
||||
if (_dispatch.DoAction(*executeActionAndArgs))
|
||||
{
|
||||
_close();
|
||||
}
|
||||
@@ -552,54 +687,37 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_filterTextChanged(IInspectable const& /*sender*/,
|
||||
Windows::UI::Xaml::RoutedEventArgs const& /*args*/)
|
||||
{
|
||||
if (_currentMode == CommandPaletteMode::CommandlineMode)
|
||||
if (_currentMode == CommandPaletteMode::CommandlineMode || _currentMode == CommandPaletteMode::ActionMode)
|
||||
{
|
||||
_evaluatePrefix();
|
||||
}
|
||||
|
||||
// We're setting _lastFilterTextWasEmpty here, because if the user tries
|
||||
// to backspace the last character in the input, the Backspace KeyDown
|
||||
// event will fire _before_ _filterTextChanged does. Updating the value
|
||||
// here will ensure that we can check this case appropriately.
|
||||
_lastFilterTextWasEmpty = _searchBox().Text().empty();
|
||||
|
||||
_updateFilteredActions();
|
||||
_filteredActionsView().SelectedIndex(0);
|
||||
|
||||
if (_currentMode == CommandPaletteMode::TabSearchMode || _currentMode == CommandPaletteMode::ActionMode)
|
||||
{
|
||||
_noMatchesText().Visibility(_filteredActions.Size() > 0 ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
_noMatchesText().Visibility(Visibility::Collapsed);
|
||||
}
|
||||
_noMatchesText().Visibility(_filteredActions.Size() > 0 ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
|
||||
void CommandPalette::_evaluatePrefix()
|
||||
{
|
||||
// This will take you from commandline mode, into action mode. The
|
||||
// backspace handler in _keyDownHandler will handle taking us from
|
||||
// action mode to commandline mode.
|
||||
auto newMode = CommandPaletteMode::CommandlineMode;
|
||||
auto newMode = CommandPaletteMode::ActionMode;
|
||||
|
||||
auto inputText = _getTrimmedInput();
|
||||
auto inputText = _searchBox().Text();
|
||||
if (inputText.size() > 0)
|
||||
{
|
||||
if (inputText[0] == L'>')
|
||||
{
|
||||
newMode = CommandPaletteMode::ActionMode;
|
||||
newMode = CommandPaletteMode::CommandlineMode;
|
||||
}
|
||||
}
|
||||
|
||||
if (newMode != _currentMode)
|
||||
{
|
||||
//_switchToMode will remove the '>' character from the input.
|
||||
_switchToMode(newMode);
|
||||
}
|
||||
}
|
||||
|
||||
Collections::IObservableVector<Command> CommandPalette::FilteredActions()
|
||||
Collections::IObservableVector<TerminalApp::Command> CommandPalette::FilteredActions()
|
||||
{
|
||||
return _filteredActions;
|
||||
}
|
||||
@@ -609,13 +727,13 @@ namespace winrt::TerminalApp::implementation
|
||||
_bindings = bindings;
|
||||
}
|
||||
|
||||
void CommandPalette::SetCommands(Collections::IVector<Command> const& actions)
|
||||
void CommandPalette::SetCommands(Collections::IVector<TerminalApp::Command> const& actions)
|
||||
{
|
||||
_allCommands = actions;
|
||||
_updateFilteredActions();
|
||||
}
|
||||
|
||||
void CommandPalette::SetTabActions(Collections::IVector<Command> const& tabs)
|
||||
void CommandPalette::SetTabActions(Collections::IVector<TerminalApp::Command> const& tabs)
|
||||
{
|
||||
_allTabActions = tabs;
|
||||
_updateFilteredActions();
|
||||
@@ -645,8 +763,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
_searchBox().Text(L"");
|
||||
_searchBox().Select(_searchBox().Text().size(), 0);
|
||||
// Leaving this block of code outside the above if-statement
|
||||
// guarantees that the correct text is shown for the mode
|
||||
// whenever _switchToMode is called.
|
||||
@@ -655,30 +771,26 @@ namespace winrt::TerminalApp::implementation
|
||||
case CommandPaletteMode::TabSearchMode:
|
||||
case CommandPaletteMode::TabSwitchMode:
|
||||
{
|
||||
SearchBoxPlaceholderText(RS_(L"TabSwitcher_SearchBoxText"));
|
||||
SearchBoxText(RS_(L"TabSwitcher_SearchBoxText"));
|
||||
NoMatchesText(RS_(L"TabSwitcher_NoMatchesText"));
|
||||
ControlName(RS_(L"TabSwitcherControlName"));
|
||||
PrefixCharacter(L"");
|
||||
break;
|
||||
}
|
||||
case CommandPaletteMode::CommandlineMode:
|
||||
SearchBoxPlaceholderText(RS_(L"CmdPalCommandlinePrompt"));
|
||||
NoMatchesText(L"");
|
||||
NoMatchesText(RS_(L"CmdPalCommandlinePrompt"));
|
||||
ControlName(RS_(L"CommandPaletteControlName"));
|
||||
PrefixCharacter(L"");
|
||||
break;
|
||||
case CommandPaletteMode::ActionMode:
|
||||
default:
|
||||
SearchBoxPlaceholderText(RS_(L"CommandPalette_SearchBox/PlaceholderText"));
|
||||
SearchBoxText(RS_(L"CommandPalette_SearchBox/PlaceholderText"));
|
||||
NoMatchesText(RS_(L"CommandPalette_NoMatchesText/Text"));
|
||||
ControlName(RS_(L"CommandPaletteControlName"));
|
||||
PrefixCharacter(L">");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This is a helper to aid in sorting commands by their `Name`s, alphabetically.
|
||||
static bool _compareCommandNames(const Command& lhs, const Command& rhs)
|
||||
static bool _compareCommandNames(const TerminalApp::Command& lhs, const TerminalApp::Command& rhs)
|
||||
{
|
||||
std::wstring_view leftName{ lhs.Name() };
|
||||
std::wstring_view rightName{ rhs.Name() };
|
||||
@@ -688,7 +800,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// This is a helper struct to aid in sorting Commands by a given weighting.
|
||||
struct WeightedCommand
|
||||
{
|
||||
Command command;
|
||||
TerminalApp::Command command;
|
||||
int weight;
|
||||
int inOrderCounter;
|
||||
|
||||
@@ -720,11 +832,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// - A collection that will receive the filtered actions
|
||||
// Return Value:
|
||||
// - <none>
|
||||
std::vector<Command> CommandPalette::_collectFilteredActions()
|
||||
std::vector<winrt::TerminalApp::Command> CommandPalette::_collectFilteredActions()
|
||||
{
|
||||
std::vector<Command> actions;
|
||||
std::vector<winrt::TerminalApp::Command> actions;
|
||||
|
||||
winrt::hstring searchText{ _getTrimmedInput() };
|
||||
auto searchText = _searchBox().Text();
|
||||
const bool addAll = searchText.empty();
|
||||
|
||||
auto commandsToFilter = _commandsToFilter();
|
||||
@@ -747,7 +859,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Add all the commands, but make sure they're sorted alphabetically.
|
||||
std::vector<Command> sortedCommands;
|
||||
std::vector<TerminalApp::Command> sortedCommands;
|
||||
sortedCommands.reserve(commandsToFilter.Size());
|
||||
|
||||
for (auto action : commandsToFilter)
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
CommandPalette();
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Model::Command> FilteredActions();
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Command> FilteredActions();
|
||||
|
||||
void SetCommands(Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> const& actions);
|
||||
void SetTabActions(Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> const& tabs);
|
||||
void SetCommands(Windows::Foundation::Collections::IVector<TerminalApp::Command> const& actions);
|
||||
void SetTabActions(Windows::Foundation::Collections::IVector<TerminalApp::Command> const& tabs);
|
||||
void SetKeyBindings(Microsoft::Terminal::TerminalControl::IKeyBindings bindings);
|
||||
|
||||
void EnableCommandPaletteMode();
|
||||
@@ -34,29 +34,31 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void SelectNextItem(const bool moveDown);
|
||||
|
||||
void ScrollPageUp();
|
||||
void ScrollPageDown();
|
||||
void ScrollToTop();
|
||||
void ScrollToBottom();
|
||||
|
||||
// Tab Switcher
|
||||
void EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx);
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, PrefixCharacter, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, SearchBoxText, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ControlName, _PropertyChangedHandlers);
|
||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ParentCommandName, _PropertyChangedHandlers);
|
||||
|
||||
private:
|
||||
friend struct CommandPaletteT<CommandPalette>; // for Xaml to bind events
|
||||
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> _allCommands{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> _currentNestedCommands{ nullptr };
|
||||
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Model::Command> _filteredActions{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> _nestedActionStack{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _allCommands{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _currentNestedCommands{ nullptr };
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Command> _filteredActions{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _nestedActionStack{ nullptr };
|
||||
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> _commandsToFilter();
|
||||
|
||||
bool _lastFilterTextWasEmpty{ true };
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _commandsToFilter();
|
||||
|
||||
void _filterTextChanged(Windows::Foundation::IInspectable const& sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs const& args);
|
||||
@@ -79,7 +81,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _updateFilteredActions();
|
||||
|
||||
std::vector<Microsoft::Terminal::Settings::Model::Command> _collectFilteredActions();
|
||||
std::vector<winrt::TerminalApp::Command> _collectFilteredActions();
|
||||
|
||||
static int _getWeight(const winrt::hstring& searchText, const winrt::hstring& name);
|
||||
void _close();
|
||||
@@ -87,21 +89,24 @@ namespace winrt::TerminalApp::implementation
|
||||
CommandPaletteMode _currentMode;
|
||||
void _switchToMode(CommandPaletteMode mode);
|
||||
|
||||
std::wstring _getTrimmedInput();
|
||||
void _evaluatePrefix();
|
||||
std::wstring _getPostPrefixInput();
|
||||
|
||||
Microsoft::Terminal::TerminalControl::IKeyBindings _bindings;
|
||||
|
||||
// Tab Switcher
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command> _allTabActions{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _allTabActions{ nullptr };
|
||||
uint32_t _switcherStartIdx;
|
||||
void _anchorKeyUpHandler();
|
||||
|
||||
winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker;
|
||||
|
||||
void _dispatchCommand(const Microsoft::Terminal::Settings::Model::Command& command);
|
||||
void _dispatchCommand(const TerminalApp::Command& command);
|
||||
void _dispatchCommandline();
|
||||
void _dismissPalette();
|
||||
|
||||
void _scrollToIndex(uint32_t index);
|
||||
uint32_t _getNumVisibleItems();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "Command.idl";
|
||||
import "IDirectKeyListener.idl";
|
||||
import "ShortcutActionDispatch.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
@@ -11,15 +11,14 @@ namespace TerminalApp
|
||||
CommandPalette();
|
||||
|
||||
String NoMatchesText { get; };
|
||||
String SearchBoxPlaceholderText { get; };
|
||||
String PrefixCharacter { get; };
|
||||
String SearchBoxText { get; };
|
||||
String ControlName { get; };
|
||||
String ParentCommandName { get; };
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Model.Command> FilteredActions { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<Command> FilteredActions { get; };
|
||||
|
||||
void SetCommands(Windows.Foundation.Collections.IVector<Microsoft.Terminal.Settings.Model.Command> actions);
|
||||
void SetTabActions(Windows.Foundation.Collections.IVector<Microsoft.Terminal.Settings.Model.Command> tabs);
|
||||
void SetCommands(Windows.Foundation.Collections.IVector<Command> actions);
|
||||
void SetTabActions(Windows.Foundation.Collections.IVector<Command> tabs);
|
||||
void SetKeyBindings(Microsoft.Terminal.TerminalControl.IKeyBindings bindings);
|
||||
void EnableCommandPaletteMode();
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:Windows10version1903="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 8)"
|
||||
xmlns:SettingsModel="using:Microsoft.Terminal.Settings.Model"
|
||||
TabNavigation="Cycle"
|
||||
IsTabStop="True"
|
||||
AllowFocusOnInteraction="True"
|
||||
@@ -31,7 +30,6 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter"/>
|
||||
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter"/>
|
||||
<local:HasNestedCommandsVisibilityConverter x:Key="HasNestedCommandsVisibilityConverter"/>
|
||||
<local:IconPathConverter x:Key="IconSourceConverter"/>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
@@ -135,27 +133,27 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
to receive clicks _anywhere_ in its bounds. -->
|
||||
|
||||
<Grid
|
||||
x:Name="_shadowBackdrop"
|
||||
Background="Transparent"
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Grid.RowSpan="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
x:Name="_shadowBackdrop"
|
||||
Background="Transparent"
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Grid.RowSpan="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
x:Name="_backdrop"
|
||||
Style="{ThemeResource CommandPaletteBackground}"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}"
|
||||
PointerPressed="_backdropPointerPressed"
|
||||
Margin="8"
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
Windows10version1903:Shadow="{StaticResource CommandPaletteShadow}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top">
|
||||
x:Name="_backdrop"
|
||||
Style="{ThemeResource CommandPaletteBackground}"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}"
|
||||
PointerPressed="_backdropPointerPressed"
|
||||
Margin="8"
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
Windows10version1903:Shadow="{StaticResource CommandPaletteShadow}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
@@ -164,28 +162,15 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox
|
||||
Grid.Row="0"
|
||||
x:Name="_searchBox"
|
||||
Margin="8"
|
||||
Padding="18,8,8,8"
|
||||
IsSpellCheckEnabled="False"
|
||||
TextChanged="_filterTextChanged"
|
||||
PlaceholderText="{x:Bind SearchBoxPlaceholderText, Mode=OneWay}"
|
||||
Text="">
|
||||
Grid.Row="0"
|
||||
x:Name="_searchBox"
|
||||
Margin="8"
|
||||
IsSpellCheckEnabled="False"
|
||||
TextChanged="_filterTextChanged"
|
||||
PlaceholderText="{x:Bind SearchBoxText, Mode=OneWay}"
|
||||
Text="">
|
||||
</TextBox>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
x:Name="_prefixCharacter"
|
||||
Margin="16,16,0,-8"
|
||||
FontSize="14"
|
||||
Visibility="{x:Bind PrefixCharacter,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource ParentCommandVisibilityConverter}}"
|
||||
Text="{x:Bind PrefixCharacter, Mode=OneWay}"
|
||||
>
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock
|
||||
Padding="16, 0, 16, 4"
|
||||
x:Name="_parentCommandText"
|
||||
@@ -207,20 +192,20 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</TextBlock>
|
||||
|
||||
<ListView
|
||||
Grid.Row="2"
|
||||
x:Name="_filteredActionsView"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
SelectionMode="Single"
|
||||
CanReorderItems="False"
|
||||
AllowDrop="False"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="_listItemClicked"
|
||||
PreviewKeyDown="_keyDownHandler"
|
||||
ItemsSource="{x:Bind FilteredActions}">
|
||||
Grid.Row="2"
|
||||
x:Name="_filteredActionsView"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
SelectionMode="Single"
|
||||
CanReorderItems="False"
|
||||
AllowDrop="False"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="_listItemClicked"
|
||||
PreviewKeyDown="_keyDownHandler"
|
||||
ItemsSource="{x:Bind FilteredActions}">
|
||||
|
||||
<ItemsControl.ItemTemplate >
|
||||
<DataTemplate x:DataType="SettingsModel:Command">
|
||||
<DataTemplate x:DataType="local:Command">
|
||||
|
||||
<!-- This HorizontalContentAlignment="Stretch" is important
|
||||
to make sure it takes the entire width of the line -->
|
||||
@@ -241,9 +226,7 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Icon,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource IconSourceConverter}}"/>
|
||||
IconSource="{x:Bind IconSource, Mode=OneWay}"/>
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "Utils.h"
|
||||
|
||||
using namespace ::winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace ::winrt::Windows::Foundation;
|
||||
@@ -93,13 +94,13 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
|
||||
void DebugTapConnection::_OutputHandler(const hstring str)
|
||||
{
|
||||
_TerminalOutputHandlers(til::visualize_control_codes(str));
|
||||
_TerminalOutputHandlers(VisualizeControlCodes(str));
|
||||
}
|
||||
|
||||
// Called by the DebugInputTapConnection to print user input
|
||||
void DebugTapConnection::_PrintInput(const hstring& str)
|
||||
{
|
||||
auto clean{ til::visualize_control_codes(str) };
|
||||
auto clean{ VisualizeControlCodes(str) };
|
||||
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
|
||||
_TerminalOutputHandlers(formatted);
|
||||
}
|
||||
|
||||
@@ -15,18 +15,18 @@ static constexpr std::wstring_view PACKAGED_PROFILE_ICON_EXTENSION{ L".png" };
|
||||
// - name: the name of the new profile.
|
||||
// Return Value:
|
||||
// - A Profile, ready to be filled in
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile CreateDefaultProfile(const std::wstring_view name)
|
||||
winrt::TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name)
|
||||
{
|
||||
const winrt::guid profileGuid{ Microsoft::Console::Utils::CreateV5Uuid(TERMINAL_PROFILE_NAMESPACE_GUID,
|
||||
gsl::as_bytes(gsl::make_span(name))) };
|
||||
auto newProfile = winrt::make<winrt::Microsoft::Terminal::Settings::Model::implementation::Profile>(profileGuid);
|
||||
auto newProfile = winrt::make<winrt::TerminalApp::implementation::Profile>(profileGuid);
|
||||
newProfile.Name(name);
|
||||
|
||||
std::wstring iconPath{ PACKAGED_PROFILE_ICON_PATH };
|
||||
iconPath.append(Microsoft::Console::Utils::GuidToString(profileGuid));
|
||||
iconPath.append(PACKAGED_PROFILE_ICON_EXTENSION);
|
||||
|
||||
newProfile.Icon(iconPath);
|
||||
newProfile.IconPath(iconPath);
|
||||
|
||||
return newProfile;
|
||||
}
|
||||
@@ -20,4 +20,4 @@ Author(s):
|
||||
// uuidv5 properties: name format is UTF-16LE bytes
|
||||
static constexpr GUID TERMINAL_PROFILE_NAMESPACE_GUID = { 0x2bde4a90, 0xd05f, 0x401c, { 0x94, 0x92, 0xe4, 0x8, 0x84, 0xea, 0xd1, 0xd8 } };
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile CreateDefaultProfile(const std::wstring_view name);
|
||||
winrt::TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name);
|
||||
@@ -5,13 +5,14 @@
|
||||
#include "GlobalAppSettings.h"
|
||||
#include "../../types/inc/Utils.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
#include "Utils.h"
|
||||
#include "JsonUtils.h"
|
||||
#include "TerminalSettingsSerializationHelpers.h"
|
||||
|
||||
#include "GlobalAppSettings.g.cpp"
|
||||
|
||||
using namespace Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp::implementation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace winrt::Microsoft::UI::Xaml::Controls;
|
||||
@@ -38,7 +39,6 @@ static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" };
|
||||
static constexpr std::string_view EnableStartupTaskKey{ "startOnUserLogin" };
|
||||
static constexpr std::string_view AlwaysOnTopKey{ "alwaysOnTop" };
|
||||
static constexpr std::string_view UseTabSwitcherKey{ "useTabSwitcher" };
|
||||
static constexpr std::string_view DisableAnimationsKey{ "disableAnimations" };
|
||||
|
||||
static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" };
|
||||
|
||||
@@ -59,58 +59,11 @@ GlobalAppSettings::GlobalAppSettings() :
|
||||
_defaultProfile{},
|
||||
_DebugFeaturesEnabled{ debugFeaturesDefault }
|
||||
{
|
||||
_commands = winrt::single_threaded_map<winrt::hstring, Model::Command>();
|
||||
_colorSchemes = winrt::single_threaded_map<winrt::hstring, Model::ColorScheme>();
|
||||
_commands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
|
||||
_colorSchemes = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::ColorScheme>();
|
||||
}
|
||||
|
||||
winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
{
|
||||
auto globals{ winrt::make_self<GlobalAppSettings>() };
|
||||
globals->_InitialRows = _InitialRows;
|
||||
globals->_InitialCols = _InitialCols;
|
||||
globals->_AlwaysShowTabs = _AlwaysShowTabs;
|
||||
globals->_ShowTitleInTitlebar = _ShowTitleInTitlebar;
|
||||
globals->_ConfirmCloseAllTabs = _ConfirmCloseAllTabs;
|
||||
globals->_Theme = _Theme;
|
||||
globals->_TabWidthMode = _TabWidthMode;
|
||||
globals->_ShowTabsInTitlebar = _ShowTabsInTitlebar;
|
||||
globals->_WordDelimiters = _WordDelimiters;
|
||||
globals->_CopyOnSelect = _CopyOnSelect;
|
||||
globals->_CopyFormatting = _CopyFormatting;
|
||||
globals->_WarnAboutLargePaste = _WarnAboutLargePaste;
|
||||
globals->_WarnAboutMultiLinePaste = _WarnAboutMultiLinePaste;
|
||||
globals->_InitialPosition = _InitialPosition;
|
||||
globals->_LaunchMode = _LaunchMode;
|
||||
globals->_SnapToGridOnResize = _SnapToGridOnResize;
|
||||
globals->_ForceFullRepaintRendering = _ForceFullRepaintRendering;
|
||||
globals->_SoftwareRendering = _SoftwareRendering;
|
||||
globals->_ForceVTInput = _ForceVTInput;
|
||||
globals->_DebugFeaturesEnabled = _DebugFeaturesEnabled;
|
||||
globals->_StartOnUserLogin = _StartOnUserLogin;
|
||||
globals->_AlwaysOnTop = _AlwaysOnTop;
|
||||
globals->_UseTabSwitcher = _UseTabSwitcher;
|
||||
globals->_DisableAnimations = _DisableAnimations;
|
||||
|
||||
globals->_unparsedDefaultProfile = _unparsedDefaultProfile;
|
||||
globals->_defaultProfile = _defaultProfile;
|
||||
globals->_keymap = _keymap->Copy();
|
||||
std::copy(_keybindingsWarnings.begin(), _keybindingsWarnings.end(), std::back_inserter(globals->_keybindingsWarnings));
|
||||
|
||||
for (auto kv : _colorSchemes)
|
||||
{
|
||||
const auto schemeImpl{ winrt::get_self<ColorScheme>(kv.Value()) };
|
||||
globals->_colorSchemes.Insert(kv.Key(), *schemeImpl->Copy());
|
||||
}
|
||||
|
||||
for (auto kv : _commands)
|
||||
{
|
||||
const auto commandImpl{ winrt::get_self<Command>(kv.Value()) };
|
||||
globals->_commands.Insert(kv.Key(), *commandImpl->Copy());
|
||||
}
|
||||
return globals;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Microsoft::Terminal::Settings::Model::ColorScheme> GlobalAppSettings::ColorSchemes() noexcept
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::TerminalApp::ColorScheme> GlobalAppSettings::ColorSchemes() noexcept
|
||||
{
|
||||
return _colorSchemes.GetView();
|
||||
}
|
||||
@@ -133,7 +86,7 @@ winrt::hstring GlobalAppSettings::UnparsedDefaultProfile() const
|
||||
return _unparsedDefaultProfile;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::KeyMapping GlobalAppSettings::KeyMap() const noexcept
|
||||
winrt::TerminalApp::KeyMapping GlobalAppSettings::KeyMap() const noexcept
|
||||
{
|
||||
return *_keymap;
|
||||
}
|
||||
@@ -201,8 +154,6 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
|
||||
|
||||
JsonUtils::GetValueForKey(json, UseTabSwitcherKey, _UseTabSwitcher);
|
||||
|
||||
JsonUtils::GetValueForKey(json, DisableAnimationsKey, _DisableAnimations);
|
||||
|
||||
// This is a helper lambda to get the keybindings and commands out of both
|
||||
// and array of objects. We'll use this twice, once on the legacy
|
||||
// `keybindings` key, and again on the newer `bindings` key.
|
||||
@@ -219,7 +170,7 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
|
||||
_keybindingsWarnings.insert(_keybindingsWarnings.end(), warnings.begin(), warnings.end());
|
||||
|
||||
// Now parse the array again, but this time as a list of commands.
|
||||
warnings = implementation::Command::LayerJson(_commands, bindings);
|
||||
warnings = winrt::TerminalApp::implementation::Command::LayerJson(_commands, bindings);
|
||||
}
|
||||
};
|
||||
parseBindings(LegacyKeybindingsKey);
|
||||
@@ -232,7 +183,7 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
|
||||
// - scheme: the color scheme to add
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void GlobalAppSettings::AddColorScheme(const Model::ColorScheme& scheme)
|
||||
void GlobalAppSettings::AddColorScheme(const winrt::TerminalApp::ColorScheme& scheme)
|
||||
{
|
||||
_colorSchemes.Insert(scheme.Name(), scheme);
|
||||
}
|
||||
@@ -246,12 +197,12 @@ void GlobalAppSettings::AddColorScheme(const Model::ColorScheme& scheme)
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> GlobalAppSettings::KeybindingsWarnings() const
|
||||
std::vector<winrt::TerminalApp::SettingsLoadWarnings> GlobalAppSettings::KeybindingsWarnings() const
|
||||
{
|
||||
return _keybindingsWarnings;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Microsoft::Terminal::Settings::Model::Command> GlobalAppSettings::Commands() noexcept
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::TerminalApp::Command> GlobalAppSettings::Commands() noexcept
|
||||
{
|
||||
return _commands.GetView();
|
||||
}
|
||||
@@ -22,31 +22,30 @@ Author(s):
|
||||
#include "ColorScheme.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelLocalTests
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class DeserializationTests;
|
||||
class SettingsTests;
|
||||
class ColorSchemeTests;
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct GlobalAppSettings : GlobalAppSettingsT<GlobalAppSettings>
|
||||
{
|
||||
public:
|
||||
GlobalAppSettings();
|
||||
com_ptr<GlobalAppSettings> Copy() const;
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> ColorSchemes() noexcept;
|
||||
void AddColorScheme(const Model::ColorScheme& scheme);
|
||||
Windows::Foundation::Collections::IMapView<hstring, TerminalApp::ColorScheme> ColorSchemes() noexcept;
|
||||
void AddColorScheme(const TerminalApp::ColorScheme& scheme);
|
||||
|
||||
Model::KeyMapping KeyMap() const noexcept;
|
||||
TerminalApp::KeyMapping KeyMap() const noexcept;
|
||||
|
||||
static com_ptr<GlobalAppSettings> FromJson(const Json::Value& json);
|
||||
void LayerJson(const Json::Value& json);
|
||||
|
||||
std::vector<SettingsLoadWarnings> KeybindingsWarnings() const;
|
||||
std::vector<TerminalApp::SettingsLoadWarnings> KeybindingsWarnings() const;
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::Command> Commands() noexcept;
|
||||
Windows::Foundation::Collections::IMapView<hstring, TerminalApp::Command> Commands() noexcept;
|
||||
|
||||
// These are implemented manually to handle the string/GUID exchange
|
||||
// by higher layers in the app.
|
||||
@@ -67,8 +66,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
GETSET_PROPERTY(winrt::Microsoft::Terminal::TerminalControl::CopyFormat, CopyFormatting, 0);
|
||||
GETSET_PROPERTY(bool, WarnAboutLargePaste, true);
|
||||
GETSET_PROPERTY(bool, WarnAboutMultiLinePaste, true);
|
||||
GETSET_PROPERTY(Model::LaunchPosition, InitialPosition, nullptr, nullptr);
|
||||
GETSET_PROPERTY(Model::LaunchMode, LaunchMode, LaunchMode::DefaultMode);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::LaunchPosition, InitialPosition, nullptr, nullptr);
|
||||
GETSET_PROPERTY(winrt::TerminalApp::LaunchMode, LaunchMode, winrt::TerminalApp::LaunchMode::DefaultMode);
|
||||
GETSET_PROPERTY(bool, SnapToGridOnResize, true);
|
||||
GETSET_PROPERTY(bool, ForceFullRepaintRendering, false);
|
||||
GETSET_PROPERTY(bool, SoftwareRendering, false);
|
||||
@@ -76,20 +75,19 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
GETSET_PROPERTY(bool, DebugFeaturesEnabled); // default value set in constructor
|
||||
GETSET_PROPERTY(bool, StartOnUserLogin, false);
|
||||
GETSET_PROPERTY(bool, AlwaysOnTop, false);
|
||||
GETSET_PROPERTY(bool, UseTabSwitcher, true);
|
||||
GETSET_PROPERTY(bool, DisableAnimations, false);
|
||||
GETSET_PROPERTY(bool, UseTabSwitcher, false);
|
||||
|
||||
private:
|
||||
hstring _unparsedDefaultProfile;
|
||||
guid _defaultProfile;
|
||||
|
||||
com_ptr<KeyMapping> _keymap;
|
||||
std::vector<SettingsLoadWarnings> _keybindingsWarnings;
|
||||
std::vector<TerminalApp::SettingsLoadWarnings> _keybindingsWarnings;
|
||||
|
||||
Windows::Foundation::Collections::IMap<hstring, Model::ColorScheme> _colorSchemes;
|
||||
Windows::Foundation::Collections::IMap<hstring, Model::Command> _commands;
|
||||
Windows::Foundation::Collections::IMap<hstring, TerminalApp::ColorScheme> _colorSchemes;
|
||||
Windows::Foundation::Collections::IMap<hstring, TerminalApp::Command> _commands;
|
||||
|
||||
friend class SettingsModelLocalTests::DeserializationTests;
|
||||
friend class SettingsModelLocalTests::ColorSchemeTests;
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::ColorSchemeTests;
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "AppLogic.idl";
|
||||
import "ColorScheme.idl";
|
||||
import "KeyMapping.idl";
|
||||
import "Command.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
// MIDL 3 allows for structs to hold nullable types
|
||||
// Though IReference is a WinRT object, MIDL 3
|
||||
@@ -17,15 +18,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Windows.Foundation.IReference<Int64> Y;
|
||||
};
|
||||
|
||||
enum LaunchMode
|
||||
{
|
||||
DefaultMode,
|
||||
MaximizedMode,
|
||||
FullscreenMode,
|
||||
FocusMode,
|
||||
MaximizedFocusMode,
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass GlobalAppSettings {
|
||||
Guid DefaultProfile;
|
||||
String UnparsedDefaultProfile();
|
||||
@@ -53,7 +45,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Boolean StartOnUserLogin;
|
||||
Boolean AlwaysOnTop;
|
||||
Boolean UseTabSwitcher;
|
||||
Boolean DisableAnimations;
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||
void AddColorScheme(ColorScheme scheme);
|
||||
@@ -22,16 +22,16 @@ Author(s):
|
||||
#pragma once
|
||||
#include "Profile.h"
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
class IDynamicProfileGenerator;
|
||||
};
|
||||
|
||||
class Microsoft::Terminal::Settings::Model::IDynamicProfileGenerator
|
||||
class TerminalApp::IDynamicProfileGenerator
|
||||
{
|
||||
public:
|
||||
virtual ~IDynamicProfileGenerator() = 0;
|
||||
virtual std::wstring_view GetNamespace() = 0;
|
||||
virtual std::vector<winrt::Microsoft::Terminal::Settings::Model::Profile> GenerateProfiles() = 0;
|
||||
virtual std::vector<winrt::TerminalApp::Profile> GenerateProfiles() = 0;
|
||||
};
|
||||
inline Microsoft::Terminal::Settings::Model::IDynamicProfileGenerator::~IDynamicProfileGenerator() {}
|
||||
inline TerminalApp::IDynamicProfileGenerator::~IDynamicProfileGenerator() {}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
import "ShortcutActionDispatch.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
interface ITab
|
||||
{
|
||||
String Title { get; };
|
||||
String Icon { get; };
|
||||
Microsoft.Terminal.Settings.Model.Command SwitchToTabCommand;
|
||||
Microsoft.UI.Xaml.Controls.TabViewItem TabViewItem { get; };
|
||||
Windows.UI.Xaml.FrameworkElement Content { get; };
|
||||
Windows.UI.Xaml.FocusState FocusState { get; };
|
||||
|
||||
void Focus(Windows.UI.Xaml.FocusState focusState);
|
||||
void Shutdown();
|
||||
|
||||
void SetDispatch(ShortcutActionDispatch dispatch);
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "IconPathConverter.h"
|
||||
#include "IconPathConverter.g.cpp"
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// These are templates that help us figure out which BitmapIconSource/FontIconSource to use for a given IconSource.
|
||||
// We have to do this because some of our code still wants to use WUX/MUX IconSources.
|
||||
#pragma region BitmapIconSource
|
||||
template<typename TIconSource>
|
||||
struct BitmapIconSource
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BitmapIconSource<winrt::Microsoft::UI::Xaml::Controls::IconSource>
|
||||
{
|
||||
using type = winrt::Microsoft::UI::Xaml::Controls::BitmapIconSource;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BitmapIconSource<winrt::Windows::UI::Xaml::Controls::IconSource>
|
||||
{
|
||||
using type = winrt::Windows::UI::Xaml::Controls::BitmapIconSource;
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
#pragma region FontIconSource
|
||||
template<typename TIconSource>
|
||||
struct FontIconSource
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct FontIconSource<winrt::Microsoft::UI::Xaml::Controls::IconSource>
|
||||
{
|
||||
using type = winrt::Microsoft::UI::Xaml::Controls::FontIconSource;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct FontIconSource<winrt::Windows::UI::Xaml::Controls::IconSource>
|
||||
{
|
||||
using type = winrt::Windows::UI::Xaml::Controls::FontIconSource;
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
// Method Description:
|
||||
// - Creates an IconSource for the given path. The icon returned is a colored
|
||||
// icon. If we couldn't create the icon for any reason, we return an empty
|
||||
// IconElement.
|
||||
// Template Types:
|
||||
// - <TIconSource>: The type of IconSource (MUX, WUX) to generate.
|
||||
// Arguments:
|
||||
// - path: the full, expanded path to the icon.
|
||||
// Return Value:
|
||||
// - An IconElement with its IconSource set, if possible.
|
||||
template<typename TIconSource>
|
||||
TIconSource _getColoredBitmapIcon(const winrt::hstring& path)
|
||||
{
|
||||
if (!path.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
winrt::Windows::Foundation::Uri iconUri{ path };
|
||||
BitmapIconSource<TIconSource>::type iconSource;
|
||||
// Make sure to set this to false, so we keep the RGB data of the
|
||||
// image. Otherwise, the icon will be white for all the
|
||||
// non-transparent pixels in the image.
|
||||
iconSource.ShowAsMonochrome(false);
|
||||
iconSource.UriSource(iconUri);
|
||||
return iconSource;
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates an IconSource for the given path.
|
||||
// * If the icon is a path to an image, we'll use that.
|
||||
// * If it isn't, then we'll try and use the text as a FontIcon. If the
|
||||
// character is in the range of symbols reserved for the Segoe MDL2
|
||||
// Asserts, well treat it as such. Otherwise, we'll default to a Sego
|
||||
// UI icon, so things like emoji will work.
|
||||
// * If we couldn't create the icon for any reason, we return an empty
|
||||
// IconElement.
|
||||
// Template Types:
|
||||
// - <TIconSource>: The type of IconSource (MUX, WUX) to generate.
|
||||
// Arguments:
|
||||
// - path: the unprocessed path to the icon.
|
||||
// Return Value:
|
||||
// - An IconElement with its IconSource set, if possible.
|
||||
template<typename TIconSource>
|
||||
TIconSource _getIconSource(const winrt::hstring& iconPath)
|
||||
{
|
||||
TIconSource iconSource{ nullptr };
|
||||
|
||||
if (iconPath.size() != 0)
|
||||
{
|
||||
const auto expandedIconPath{ _expandIconPath(iconPath) };
|
||||
iconSource = _getColoredBitmapIcon<TIconSource>(expandedIconPath);
|
||||
|
||||
// If we fail to set the icon source using the "icon" as a path,
|
||||
// let's try it as a symbol/emoji.
|
||||
//
|
||||
// Anything longer than 2 wchar_t's _isn't_ an emoji or symbol, so
|
||||
// don't do this if it's just an invalid path.
|
||||
if (!iconSource && iconPath.size() <= 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
FontIconSource<TIconSource>::type icon;
|
||||
const wchar_t ch = iconPath[0];
|
||||
|
||||
// The range of MDL2 Icons isn't explicitly defined, but
|
||||
// we're using this based off the table on:
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font
|
||||
const bool isMDL2Icon = ch >= L'\uE700' && ch <= L'\uF8FF';
|
||||
if (isMDL2Icon)
|
||||
{
|
||||
icon.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily{ L"Segoe MDL2 Assets" });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: you _do_ need to manually set the font here.
|
||||
icon.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily{ L"Segoe UI" });
|
||||
}
|
||||
icon.FontSize(12);
|
||||
icon.Glyph(iconPath);
|
||||
iconSource = icon;
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
if (!iconSource)
|
||||
{
|
||||
// Set the default IconSource to a BitmapIconSource with a null source
|
||||
// (instead of just nullptr) because there's a really weird crash when swapping
|
||||
// data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette).
|
||||
// Swapping between nullptr IconSources and non-null IconSources causes a crash
|
||||
// to occur, but swapping between IconSources with a null source and non-null IconSources
|
||||
// work perfectly fine :shrug:.
|
||||
BitmapIconSource<TIconSource>::type icon;
|
||||
icon.UriSource(nullptr);
|
||||
iconSource = icon;
|
||||
}
|
||||
|
||||
return iconSource;
|
||||
}
|
||||
|
||||
static winrt::hstring _expandIconPath(hstring iconPath)
|
||||
{
|
||||
if (iconPath.empty())
|
||||
{
|
||||
return iconPath;
|
||||
}
|
||||
winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW<std::wstring>(iconPath.c_str()) };
|
||||
return envExpandedPath;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempt to convert something into another type. For the
|
||||
// IconPathConverter, we support a variety of icons:
|
||||
// * If the icon is a path to an image, we'll use that.
|
||||
// * If it isn't, then we'll try and use the text as a FontIcon. If the
|
||||
// character is in the range of symbols reserved for the Segoe MDL2
|
||||
// Asserts, well treat it as such. Otherwise, we'll default to a Sego
|
||||
// UI icon, so things like emoji will work.
|
||||
// - MUST BE CALLED ON THE UI THREAD.
|
||||
// Arguments:
|
||||
// - value: the input object to attempt to convert into an IconSource.
|
||||
// Return Value:
|
||||
// - Visible if the object was a string and wasn't the empty string.
|
||||
Foundation::IInspectable IconPathConverter::Convert(Foundation::IInspectable const& value,
|
||||
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
|
||||
Foundation::IInspectable const& /* parameter */,
|
||||
hstring const& /* language */)
|
||||
{
|
||||
const auto& iconPath = winrt::unbox_value_or<winrt::hstring>(value, L"");
|
||||
return _getIconSource<Controls::IconSource>(iconPath);
|
||||
}
|
||||
|
||||
// unused for one-way bindings
|
||||
Foundation::IInspectable IconPathConverter::ConvertBack(Foundation::IInspectable const& /* value */,
|
||||
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
|
||||
Foundation::IInspectable const& /* parameter */,
|
||||
hstring const& /* language */)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::Controls::IconSource IconPathConverter::IconSourceWUX(hstring path)
|
||||
{
|
||||
return _getIconSource<Windows::UI::Xaml::Controls::IconSource>(path);
|
||||
}
|
||||
|
||||
Microsoft::UI::Xaml::Controls::IconSource IconPathConverter::IconSourceMUX(hstring path)
|
||||
{
|
||||
return _getIconSource<Microsoft::UI::Xaml::Controls::IconSource>(path);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "IconPathConverter.g.h"
|
||||
#include "..\inc\cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct IconPathConverter : IconPathConverterT<IconPathConverter>
|
||||
{
|
||||
IconPathConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value,
|
||||
Windows::UI::Xaml::Interop::TypeName const& targetType,
|
||||
Windows::Foundation::IInspectable const& parameter,
|
||||
hstring const& language);
|
||||
|
||||
Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value,
|
||||
Windows::UI::Xaml::Interop::TypeName const& targetType,
|
||||
Windows::Foundation::IInspectable const& parameter,
|
||||
hstring const& language);
|
||||
|
||||
static Windows::UI::Xaml::Controls::IconSource IconSourceWUX(hstring path);
|
||||
static Microsoft::UI::Xaml::Controls::IconSource IconSourceMUX(hstring path);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(IconPathConverter);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart
|
||||
|
||||
// We use the default attribute to declare IValueConverter as the default
|
||||
// interface. In the listing, IconPathConverter has only a
|
||||
// constructor, and no methods, so no default interface is generated for it.
|
||||
// The default attribute is optimal if you won't be adding instance members
|
||||
// to IconPathConverter, because no QueryInterface will be
|
||||
// required to call the IValueConverter methods
|
||||
runtimeclass IconPathConverter : [default] Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
IconPathConverter();
|
||||
|
||||
static Windows.UI.Xaml.Controls.IconSource IconSourceWUX(String path);
|
||||
static Microsoft.UI.Xaml.Controls.IconSource IconSourceMUX(String path);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ Module Name:
|
||||
- JsonUtils.h
|
||||
|
||||
Abstract:
|
||||
- Helpers for the Terminal Settings Model project
|
||||
- Helpers for the TerminalApp project
|
||||
Author(s):
|
||||
- Mike Griese - August 2019
|
||||
- Dustin Howett - January 2020
|
||||
@@ -31,21 +31,7 @@ namespace winrt
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a std::string from a string_view. We do this because we can't look
|
||||
// up a key in a Json::Value with a string_view directly, so instead we'll use
|
||||
// this helper. Should a string_view lookup ever be added to jsoncpp, we can
|
||||
// remove this entirely.
|
||||
// Arguments:
|
||||
// - key: the string_view to build a string from
|
||||
// Return Value:
|
||||
// - a std::string to use for looking up a value from a Json::Value
|
||||
inline std::string JsonKey(const std::string_view key)
|
||||
{
|
||||
return static_cast<std::string>(key);
|
||||
}
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
namespace TerminalApp::JsonUtils
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
@@ -117,8 +103,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
T FromJson(const Json::Value&);
|
||||
bool CanConvert(const Json::Value& json);
|
||||
|
||||
Json::Value ToJson(const T& val);
|
||||
|
||||
std::string TypeDescription() const { return "<unknown>"; }
|
||||
};
|
||||
|
||||
@@ -135,11 +119,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isString();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const std::string& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "string";
|
||||
@@ -159,11 +138,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isString();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const std::wstring& val)
|
||||
{
|
||||
return til::u16u8(val);
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "string";
|
||||
@@ -179,11 +153,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
{
|
||||
return winrt::hstring{ til::u8u16(Detail::GetStringView(json)) };
|
||||
}
|
||||
|
||||
Json::Value ToJson(const winrt::hstring& val)
|
||||
{
|
||||
return til::u16u8(val);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -200,11 +169,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isBool();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const bool val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "true | false";
|
||||
@@ -224,11 +188,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isInt();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const int& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "number";
|
||||
@@ -248,11 +207,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isUInt();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const unsigned int& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "number (>= 0)";
|
||||
@@ -272,11 +226,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isNumeric();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const float& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "number";
|
||||
@@ -296,11 +245,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isNumeric();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const double& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "number";
|
||||
@@ -326,11 +270,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return string.length() == 38 && string.front() == '{' && string.back() == '}';
|
||||
}
|
||||
|
||||
Json::Value ToJson(const GUID& val)
|
||||
{
|
||||
return til::u16u8(::Microsoft::Console::Utils::GuidToString(val));
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "guid";
|
||||
@@ -352,11 +291,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return ConversionTrait<GUID>{}.CanConvert(json);
|
||||
}
|
||||
|
||||
Json::Value ToJson(const winrt::guid& val)
|
||||
{
|
||||
return ConversionTrait<GUID>{}.ToJson(val);
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return ConversionTrait<GUID>{}.TypeDescription();
|
||||
@@ -382,11 +316,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return (string.length() == 7 || string.length() == 4) && string.front() == '#';
|
||||
}
|
||||
|
||||
Json::Value ToJson(const til::color& val)
|
||||
{
|
||||
return til::u16u8(val.ToHexString(true));
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "color (#rrggbb, #rgb)";
|
||||
@@ -407,11 +336,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return ConversionTrait<til::color>{}.CanConvert(json);
|
||||
}
|
||||
|
||||
Json::Value ToJson(const winrt::Windows::UI::Color& val)
|
||||
{
|
||||
return ConversionTrait<til::color>{}.ToJson(val);
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return ConversionTrait<til::color>{}.TypeDescription();
|
||||
@@ -446,18 +370,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return json.isString();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const T& val)
|
||||
{
|
||||
for (const auto& pair : TBase::mappings)
|
||||
{
|
||||
if (pair.second == val)
|
||||
{
|
||||
return { pair.first.data() };
|
||||
}
|
||||
}
|
||||
FAIL_FAST();
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
std::vector<std::string_view> names;
|
||||
@@ -515,35 +427,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
return AllClear;
|
||||
}
|
||||
|
||||
Json::Value ToJson(const T& val)
|
||||
{
|
||||
if (val == AllClear)
|
||||
{
|
||||
return BaseEnumMapper::ToJson(AllClear);
|
||||
}
|
||||
else if (val == AllSet)
|
||||
{
|
||||
return BaseEnumMapper::ToJson(AllSet);
|
||||
}
|
||||
else if (WI_IsSingleFlagSet(val))
|
||||
{
|
||||
return BaseEnumMapper::ToJson(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Json::Value json{ Json::ValueType::arrayValue };
|
||||
for (const auto& pair : TBase::mappings)
|
||||
{
|
||||
if (pair.second != AllClear &&
|
||||
(val & pair.second) == pair.second)
|
||||
{
|
||||
json.append(BaseEnumMapper::ToJson(pair.second));
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json)
|
||||
{
|
||||
return BaseEnumMapper::CanConvert(json) || json.isArray();
|
||||
@@ -691,32 +574,17 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
GetValueForKey(json, key1, val1);
|
||||
GetValuesForKeys(json, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// SetValueForKey, type-deduced, manual converter
|
||||
template<typename T, typename Converter>
|
||||
void SetValueForKey(Json::Value& json, std::string_view key, const T& target, Converter&& conv)
|
||||
{
|
||||
// demand guarantees that it will return a value or throw an exception
|
||||
*json.demand(&*key.cbegin(), (&*key.cbegin()) + key.size()) = conv.ToJson(target);
|
||||
}
|
||||
|
||||
// SetValueForKey, type-deduced, with automatic converter
|
||||
template<typename T>
|
||||
void SetValueForKey(Json::Value& json, std::string_view key, const T& target)
|
||||
{
|
||||
SetValueForKey(json, key, target, ConversionTrait<typename Detail::DeduceOptional<T>::Type>{});
|
||||
}
|
||||
};
|
||||
|
||||
#define JSON_ENUM_MAPPER(...) \
|
||||
template<> \
|
||||
struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<__VA_ARGS__> : \
|
||||
public ::Microsoft::Terminal::Settings::Model::JsonUtils::EnumMapper<__VA_ARGS__, ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<__VA_ARGS__>>
|
||||
#define JSON_ENUM_MAPPER(...) \
|
||||
template<> \
|
||||
struct ::TerminalApp::JsonUtils::ConversionTrait<__VA_ARGS__> : \
|
||||
public ::TerminalApp::JsonUtils::EnumMapper<__VA_ARGS__, ::TerminalApp::JsonUtils::ConversionTrait<__VA_ARGS__>>
|
||||
|
||||
#define JSON_FLAG_MAPPER(...) \
|
||||
template<> \
|
||||
struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<__VA_ARGS__> : \
|
||||
public ::Microsoft::Terminal::Settings::Model::JsonUtils::FlagMapper<__VA_ARGS__, ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<__VA_ARGS__>>
|
||||
#define JSON_FLAG_MAPPER(...) \
|
||||
template<> \
|
||||
struct ::TerminalApp::JsonUtils::ConversionTrait<__VA_ARGS__> : \
|
||||
public ::TerminalApp::JsonUtils::FlagMapper<__VA_ARGS__, ::TerminalApp::JsonUtils::ConversionTrait<__VA_ARGS__>>
|
||||
|
||||
#define JSON_MAPPINGS(Count) \
|
||||
static constexpr std::array<pair_type, Count> mappings
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <ShObjIdl.h>
|
||||
#include <Propkey.h>
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
// This property key isn't already defined in propkey.h, but is used by UWP Jumplist to determine the icon of the jumplist item.
|
||||
// IShellLink's SetIconLocation isn't going to read "ms-appx://" icon paths, so we'll need to use this to set the icon.
|
||||
@@ -43,13 +43,12 @@ static constexpr bool _isProbableFilePath(std::wstring_view path)
|
||||
// paths to have the "correct" slash direction.
|
||||
static std::wstring _normalizeIconPath(std::wstring_view path)
|
||||
{
|
||||
const auto fullPath{ wil::ExpandEnvironmentStringsW<std::wstring>(path.data()) };
|
||||
if (_isProbableFilePath(fullPath))
|
||||
if (_isProbableFilePath(path))
|
||||
{
|
||||
std::filesystem::path asPath{ fullPath };
|
||||
std::filesystem::path asPath{ path };
|
||||
return asPath.make_preferred().wstring();
|
||||
}
|
||||
return std::wstring{ fullPath };
|
||||
return std::wstring{ path };
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
@@ -118,8 +117,13 @@ static std::wstring_view _getExePath()
|
||||
// - settings - The settings object to update the jumplist with.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||
winrt::fire_and_forget Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||
{
|
||||
// make sure to capture the settings _before_ the co_await
|
||||
const auto strongSettings = settings;
|
||||
|
||||
co_await winrt::resume_background();
|
||||
|
||||
try
|
||||
{
|
||||
auto jumplistInstance = winrt::create_instance<ICustomDestinationList>(CLSID_DestinationList, CLSCTX_ALL);
|
||||
@@ -131,10 +135,10 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||
|
||||
// It's easier to clear the list and re-add everything. The settings aren't
|
||||
// updated often, and there likely isn't a huge amount of items to add.
|
||||
RETURN_IF_FAILED(jumplistItems->Clear());
|
||||
THROW_IF_FAILED(jumplistItems->Clear());
|
||||
|
||||
// Update the list of profiles.
|
||||
RETURN_IF_FAILED(_updateProfiles(jumplistItems.get(), settings.Profiles().GetView()));
|
||||
THROW_IF_FAILED(_updateProfiles(jumplistItems.get(), strongSettings.Profiles().GetView()));
|
||||
|
||||
// TODO GH#1571: Add items from the future customizable new tab dropdown as well.
|
||||
// This could either replace the default profiles, or be added alongside them.
|
||||
@@ -142,13 +146,11 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||
// Add the items to the jumplist Task section.
|
||||
// The Tasks section is immutable by the user, unlike the destinations
|
||||
// section that can have its items pinned and removed.
|
||||
RETURN_IF_FAILED(jumplistInstance->AddUserTasks(jumplistItems.get()));
|
||||
THROW_IF_FAILED(jumplistInstance->AddUserTasks(jumplistItems.get()));
|
||||
|
||||
RETURN_IF_FAILED(jumplistInstance->CommitList());
|
||||
|
||||
return S_OK;
|
||||
THROW_IF_FAILED(jumplistInstance->CommitList());
|
||||
}
|
||||
CATCH_RETURN();
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -158,7 +160,7 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||
// - profiles - The profiles to add to the jumplist
|
||||
// Return Value:
|
||||
// - S_OK or HRESULT failure code.
|
||||
[[nodiscard]] HRESULT Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<Profile> profiles) noexcept
|
||||
[[nodiscard]] HRESULT Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -169,7 +171,7 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||
|
||||
// Create the shell link object for the profile
|
||||
winrt::com_ptr<IShellLinkW> shLink;
|
||||
const auto normalizedIconPath{ _normalizeIconPath(profile.Icon()) };
|
||||
const auto normalizedIconPath{ _normalizeIconPath(profile.ExpandedIconPath()) };
|
||||
RETURN_IF_FAILED(_createShellLink(profile.Name(), normalizedIconPath, args, shLink.put()));
|
||||
|
||||
RETURN_IF_FAILED(jumplistItems->AddObject(shLink.get()));
|
||||
|
||||
@@ -12,15 +12,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CascadiaSettings.h"
|
||||
|
||||
struct IObjectCollection;
|
||||
struct IShellLinkW;
|
||||
|
||||
class Jumplist
|
||||
{
|
||||
public:
|
||||
static HRESULT UpdateJumplist(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) noexcept;
|
||||
static winrt::fire_and_forget UpdateJumplist(const winrt::TerminalApp::CascadiaSettings& settings) noexcept;
|
||||
|
||||
private:
|
||||
[[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Terminal::Settings::Model::Profile> profiles) noexcept;
|
||||
[[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles) noexcept;
|
||||
[[nodiscard]] static HRESULT _createShellLink(const std::wstring_view name, const std::wstring_view path, const std::wstring_view args, IShellLinkW** shLink) noexcept;
|
||||
};
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "KeyChordSerialization.h"
|
||||
#include "KeyChordSerialization.g.cpp"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
|
||||
static constexpr std::wstring_view CTRL_KEY{ L"ctrl" };
|
||||
static constexpr std::wstring_view SHIFT_KEY{ L"shift" };
|
||||
12
src/cascadia/TerminalApp/KeyChordSerialization.h
Normal file
12
src/cascadia/TerminalApp/KeyChordSerialization.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
#include <winrt/Microsoft.Terminal.TerminalControl.h>
|
||||
|
||||
class KeyChordSerialization final
|
||||
{
|
||||
public:
|
||||
static winrt::Microsoft::Terminal::TerminalControl::KeyChord FromString(const winrt::hstring& str);
|
||||
static winrt::hstring ToString(const winrt::Microsoft::Terminal::TerminalControl::KeyChord& chord);
|
||||
};
|
||||
@@ -4,26 +4,15 @@
|
||||
#include "pch.h"
|
||||
#include "KeyMapping.h"
|
||||
#include "KeyChordSerialization.h"
|
||||
#include "ActionAndArgs.h"
|
||||
|
||||
#include "KeyMapping.g.cpp"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
winrt::com_ptr<KeyMapping> KeyMapping::Copy() const
|
||||
{
|
||||
auto keymap{ winrt::make_self<KeyMapping>() };
|
||||
std::for_each(_keyShortcuts.begin(), _keyShortcuts.end(), [keymap](auto& kv) {
|
||||
const auto actionAndArgsImpl{ winrt::get_self<ActionAndArgs>(kv.second) };
|
||||
keymap->_keyShortcuts[kv.first] = *actionAndArgsImpl->Copy();
|
||||
});
|
||||
return keymap;
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::Model::ActionAndArgs KeyMapping::TryLookup(KeyChord const& chord) const
|
||||
TerminalApp::ActionAndArgs KeyMapping::TryLookup(KeyChord const& chord) const
|
||||
{
|
||||
const auto result = _keyShortcuts.find(chord);
|
||||
if (result != _keyShortcuts.end())
|
||||
@@ -33,12 +22,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t KeyMapping::Size() const
|
||||
{
|
||||
return _keyShortcuts.size();
|
||||
}
|
||||
|
||||
void KeyMapping::SetKeyBinding(const Microsoft::Terminal::Settings::Model::ActionAndArgs& actionAndArgs,
|
||||
void KeyMapping::SetKeyBinding(const TerminalApp::ActionAndArgs& actionAndArgs,
|
||||
const KeyChord& chord)
|
||||
{
|
||||
_keyShortcuts[chord] = actionAndArgs;
|
||||
@@ -55,7 +39,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
_keyShortcuts.erase(chord);
|
||||
}
|
||||
|
||||
KeyChord KeyMapping::GetKeyBindingForAction(Microsoft::Terminal::Settings::Model::ShortcutAction const& action)
|
||||
KeyChord KeyMapping::GetKeyBindingForAction(TerminalApp::ShortcutAction const& action)
|
||||
{
|
||||
for (auto& kv : _keyShortcuts)
|
||||
{
|
||||
@@ -76,7 +60,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// - actionAndArgs: The ActionAndArgs to lookup the keybinding for.
|
||||
// Return Value:
|
||||
// - The bound keychord, if this ActionAndArgs is bound to a key, otherwise nullptr.
|
||||
KeyChord KeyMapping::GetKeyBindingForActionWithArgs(Microsoft::Terminal::Settings::Model::ActionAndArgs const& actionAndArgs)
|
||||
KeyChord KeyMapping::GetKeyBindingForActionWithArgs(TerminalApp::ActionAndArgs const& actionAndArgs)
|
||||
{
|
||||
if (actionAndArgs == nullptr)
|
||||
{
|
||||
77
src/cascadia/TerminalApp/KeyMapping.h
Normal file
77
src/cascadia/TerminalApp/KeyMapping.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- KeyMapping.h
|
||||
|
||||
Abstract:
|
||||
- A mapping of key chords to actions. Includes (de)serialization logic.
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora - September 2020
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "KeyMapping.g.h"
|
||||
#include "ActionArgs.h"
|
||||
#include "..\inc\cppwinrt_utils.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class SettingsTests;
|
||||
class KeyBindingsTests;
|
||||
class TestUtils;
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct KeyChordHash
|
||||
{
|
||||
std::size_t operator()(const winrt::Microsoft::Terminal::TerminalControl::KeyChord& key) const
|
||||
{
|
||||
std::hash<int32_t> keyHash;
|
||||
std::hash<winrt::Microsoft::Terminal::TerminalControl::KeyModifiers> modifiersHash;
|
||||
std::size_t hashedKey = keyHash(key.Vkey());
|
||||
std::size_t hashedMods = modifiersHash(key.Modifiers());
|
||||
return hashedKey ^ hashedMods;
|
||||
}
|
||||
};
|
||||
|
||||
struct KeyChordEquality
|
||||
{
|
||||
bool operator()(const winrt::Microsoft::Terminal::TerminalControl::KeyChord& lhs, const winrt::Microsoft::Terminal::TerminalControl::KeyChord& rhs) const
|
||||
{
|
||||
return lhs.Modifiers() == rhs.Modifiers() && lhs.Vkey() == rhs.Vkey();
|
||||
}
|
||||
};
|
||||
|
||||
struct KeyMapping : KeyMappingT<KeyMapping>
|
||||
{
|
||||
KeyMapping() = default;
|
||||
|
||||
TerminalApp::ActionAndArgs TryLookup(winrt::Microsoft::Terminal::TerminalControl::KeyChord const& chord) const;
|
||||
|
||||
void SetKeyBinding(TerminalApp::ActionAndArgs const& actionAndArgs,
|
||||
winrt::Microsoft::Terminal::TerminalControl::KeyChord const& chord);
|
||||
void ClearKeyBinding(winrt::Microsoft::Terminal::TerminalControl::KeyChord const& chord);
|
||||
Microsoft::Terminal::TerminalControl::KeyChord GetKeyBindingForAction(TerminalApp::ShortcutAction const& action);
|
||||
Microsoft::Terminal::TerminalControl::KeyChord GetKeyBindingForActionWithArgs(TerminalApp::ActionAndArgs const& actionAndArgs);
|
||||
|
||||
static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::TerminalControl::KeyModifiers modifiers);
|
||||
|
||||
// Defined in KeyMappingSerialization.cpp
|
||||
std::vector<TerminalApp::SettingsLoadWarnings> LayerJson(const Json::Value& json);
|
||||
Json::Value ToJson();
|
||||
|
||||
private:
|
||||
std::unordered_map<winrt::Microsoft::Terminal::TerminalControl::KeyChord, TerminalApp::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
|
||||
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::KeyBindingsTests;
|
||||
friend class TerminalAppLocalTests::TestUtils;
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "ActionArgs.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
enum ShortcutAction
|
||||
{
|
||||
@@ -52,8 +51,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
[default_interface] runtimeclass ActionAndArgs {
|
||||
ActionAndArgs();
|
||||
ActionAndArgs(ShortcutAction action, IActionArgs args);
|
||||
|
||||
IActionArgs Args;
|
||||
ShortcutAction Action;
|
||||
};
|
||||
@@ -61,7 +58,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
[default_interface] runtimeclass KeyMapping
|
||||
{
|
||||
ActionAndArgs TryLookup(Microsoft.Terminal.TerminalControl.KeyChord chord);
|
||||
UInt64 Size();
|
||||
|
||||
void SetKeyBinding(ActionAndArgs actionAndArgs, Microsoft.Terminal.TerminalControl.KeyChord chord);
|
||||
void ClearKeyBinding(Microsoft.Terminal.TerminalControl.KeyChord chord);
|
||||
@@ -10,10 +10,11 @@
|
||||
#include "KeyMapping.h"
|
||||
#include "ActionAndArgs.h"
|
||||
#include "KeyChordSerialization.h"
|
||||
#include "Utils.h"
|
||||
#include "JsonUtils.h"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
static constexpr std::string_view KeysKey{ "keys" };
|
||||
static constexpr std::string_view CommandKey{ "command" };
|
||||
@@ -56,7 +57,7 @@ static Json::Value _ShortcutAsJsonObject(const KeyChord& chord,
|
||||
// ShortcutAction.
|
||||
// Return Value:
|
||||
// - a Json::Value which is an equivalent serialization of this object.
|
||||
Json::Value winrt::Microsoft::Terminal::Settings::Model::implementation::KeyMapping::ToJson()
|
||||
Json::Value winrt::TerminalApp::implementation::KeyMapping::ToJson()
|
||||
{
|
||||
Json::Value bindingsArray;
|
||||
|
||||
@@ -92,7 +93,7 @@ Json::Value winrt::Microsoft::Terminal::Settings::Model::implementation::KeyMapp
|
||||
// `"unbound"`, then we'll clear the keybinding from the existing keybindings.
|
||||
// Arguments:
|
||||
// - json: an array of Json::Value's to deserialize into our _keyShortcuts mapping.
|
||||
std::vector<SettingsLoadWarnings> winrt::Microsoft::Terminal::Settings::Model::implementation::KeyMapping::LayerJson(const Json::Value& json)
|
||||
std::vector<SettingsLoadWarnings> winrt::TerminalApp::implementation::KeyMapping::LayerJson(const Json::Value& json)
|
||||
{
|
||||
// It's possible that the user provided keybindings have some warnings in
|
||||
// them - problems that we should alert the user to, but we can recover
|
||||
@@ -3,17 +3,15 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "Pane.h"
|
||||
#include "Profile.h"
|
||||
#include "AppLogic.h"
|
||||
|
||||
#include <Mmsystem.h>
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::UI;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Xaml::Media;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace winrt::TerminalApp;
|
||||
@@ -23,15 +21,6 @@ static const int PaneBorderSize = 2;
|
||||
static const int CombinedPaneBorderSize = 2 * PaneBorderSize;
|
||||
static const float Half = 0.50f;
|
||||
|
||||
// WARNING: Don't do this! This won't work
|
||||
// Duration duration{ std::chrono::milliseconds{ 200 } };
|
||||
// Instead, make a duration from a TimeSpan from the time in millis
|
||||
//
|
||||
// 200ms was chosen because it's quick enough that it doesn't break your
|
||||
// flow, but not too quick to see
|
||||
static const int AnimationDurationInMilliseconds = 200;
|
||||
static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Windows::Foundation::TimeSpan(std::chrono::milliseconds(AnimationDurationInMilliseconds)));
|
||||
|
||||
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_focusedBorderBrush = { nullptr };
|
||||
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr };
|
||||
|
||||
@@ -44,7 +33,6 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus
|
||||
_border.Child(_control);
|
||||
|
||||
_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
|
||||
_warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler });
|
||||
|
||||
// On the first Pane's creation, lookup resources we'll use to theme the
|
||||
// Pane, including the brushed to use for the focused/unfocused border
|
||||
@@ -54,10 +42,6 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus
|
||||
_SetupResources();
|
||||
}
|
||||
|
||||
// Use the unfocused border color as the pane background, so an actual color
|
||||
// appears behind panes as we animate them sliding in.
|
||||
_root.Background(s_unfocusedBorderBrush);
|
||||
|
||||
// Register an event with the control to have it inform us when it gains focus.
|
||||
_gotFocusRevoker = control.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
|
||||
|
||||
@@ -312,8 +296,7 @@ bool Pane::NavigateFocus(const Direction& direction)
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Pane::_ControlConnectionStateChangedHandler(const TermControl& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||
void Pane::_ControlConnectionStateChangedHandler(const TermControl& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||
{
|
||||
std::unique_lock lock{ _createCloseLock };
|
||||
// It's possible that this event handler started being executed, then before
|
||||
@@ -341,35 +324,10 @@ void Pane::_ControlConnectionStateChangedHandler(const TermControl& /*sender*/,
|
||||
if (paneProfile)
|
||||
{
|
||||
auto mode = paneProfile.CloseOnExit();
|
||||
if ((mode == CloseOnExitMode::Always) ||
|
||||
(mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed))
|
||||
if ((mode == winrt::TerminalApp::CloseOnExitMode::Always) ||
|
||||
(mode == winrt::TerminalApp::CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed))
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Plays a warning note when triggered by the BEL control character,
|
||||
// using the sound configured for the "Critical Stop" system event.`
|
||||
// This matches the behavior of the Windows Console host.
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (!_IsLeaf())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
auto paneProfile = settings.FindProfile(_profile.value());
|
||||
if (paneProfile)
|
||||
{
|
||||
if (paneProfile.BellStyle() == winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible)
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
_ClosedHandlers(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,7 +612,6 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
|
||||
// Add our new event handler before revoking the old one.
|
||||
_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
|
||||
_warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler });
|
||||
|
||||
// Revoke the old event handlers. Remove both the handlers for the panes
|
||||
// themselves closing, and remove their handlers for their controls
|
||||
@@ -664,8 +621,6 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
_secondChild->Closed(_secondClosedToken);
|
||||
closedChild->_control.ConnectionStateChanged(closedChild->_connectionStateChangedToken);
|
||||
remainingChild->_control.ConnectionStateChanged(remainingChild->_connectionStateChangedToken);
|
||||
closedChild->_control.WarningBell(closedChild->_warningBellToken);
|
||||
remainingChild->_control.WarningBell(remainingChild->_warningBellToken);
|
||||
|
||||
// If either of our children was focused, we want to take that focus from
|
||||
// them.
|
||||
@@ -756,7 +711,6 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
oldFirst->Closed(oldFirstToken);
|
||||
oldSecond->Closed(oldSecondToken);
|
||||
closedChild->_control.ConnectionStateChanged(closedChild->_connectionStateChangedToken);
|
||||
closedChild->_control.WarningBell(closedChild->_warningBellToken);
|
||||
|
||||
// Reset our UI:
|
||||
_root.Children().Clear();
|
||||
@@ -817,131 +771,7 @@ winrt::fire_and_forget Pane::_CloseChildRoutine(const bool closeFirst)
|
||||
|
||||
if (auto pane{ weakThis.get() })
|
||||
{
|
||||
// This will query if animations are enabled via the "Show animations in
|
||||
// Windows" setting in the OS
|
||||
winrt::Windows::UI::ViewManagement::UISettings uiSettings;
|
||||
const auto animationsEnabledInOS = uiSettings.AnimationsEnabled();
|
||||
const auto animationsEnabledInApp = Media::Animation::Timeline::AllowDependentAnimations();
|
||||
|
||||
// GH#7252: If either child is zoomed, just skip the animation. It won't work.
|
||||
const bool eitherChildZoomed = pane->_firstChild->_zoomed || pane->_secondChild->_zoomed;
|
||||
// If animations are disabled, just skip this and go straight to
|
||||
// _CloseChild. Curiously, the pane opening animation doesn't need this,
|
||||
// and will skip straight to Completed when animations are disabled, but
|
||||
// this one doesn't seem to.
|
||||
if (!animationsEnabledInOS || !animationsEnabledInApp || eitherChildZoomed)
|
||||
{
|
||||
pane->_CloseChild(closeFirst);
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Setup the animation
|
||||
|
||||
auto removedChild = closeFirst ? _firstChild : _secondChild;
|
||||
auto remainingChild = closeFirst ? _secondChild : _firstChild;
|
||||
const bool splitWidth = _splitState == SplitState::Vertical;
|
||||
const auto totalSize = splitWidth ? _root.ActualWidth() : _root.ActualHeight();
|
||||
|
||||
Size removedOriginalSize{
|
||||
::base::saturated_cast<float>(removedChild->_root.ActualWidth()),
|
||||
::base::saturated_cast<float>(removedChild->_root.ActualHeight())
|
||||
};
|
||||
Size remainingOriginalSize{
|
||||
::base::saturated_cast<float>(remainingChild->_root.ActualWidth()),
|
||||
::base::saturated_cast<float>(remainingChild->_root.ActualHeight())
|
||||
};
|
||||
|
||||
// Remove both children from the grid
|
||||
_root.Children().Clear();
|
||||
// Add the remaining child back to the grid, in the right place.
|
||||
_root.Children().Append(remainingChild->GetRootElement());
|
||||
if (_splitState == SplitState::Vertical)
|
||||
{
|
||||
Controls::Grid::SetColumn(remainingChild->GetRootElement(), closeFirst ? 1 : 0);
|
||||
}
|
||||
else if (_splitState == SplitState::Horizontal)
|
||||
{
|
||||
Controls::Grid::SetRow(remainingChild->GetRootElement(), closeFirst ? 1 : 0);
|
||||
}
|
||||
|
||||
// Create the dummy grid. This grid will be the one we actually animate,
|
||||
// in the place of the closed pane.
|
||||
Controls::Grid dummyGrid;
|
||||
dummyGrid.Background(s_unfocusedBorderBrush);
|
||||
// It should be the size of the closed pane.
|
||||
dummyGrid.Width(removedOriginalSize.Width);
|
||||
dummyGrid.Height(removedOriginalSize.Height);
|
||||
// Put it where the removed child is
|
||||
if (_splitState == SplitState::Vertical)
|
||||
{
|
||||
Controls::Grid::SetColumn(dummyGrid, closeFirst ? 0 : 1);
|
||||
}
|
||||
else if (_splitState == SplitState::Horizontal)
|
||||
{
|
||||
Controls::Grid::SetRow(dummyGrid, closeFirst ? 0 : 1);
|
||||
}
|
||||
// Add it to the tree
|
||||
_root.Children().Append(dummyGrid);
|
||||
|
||||
// Set up the rows/cols as auto/auto, so they'll only use the size of
|
||||
// the elements in the grid.
|
||||
//
|
||||
// * For the closed pane, we want to make that row/col "auto" sized, so
|
||||
// it takes up as much space as is available.
|
||||
// * For the remaining pane, we'll make that row/col "*" sized, so it
|
||||
// takes all the remaining space. As the dummy grid is resized down,
|
||||
// the remaining pane will expand to take the rest of the space.
|
||||
_root.ColumnDefinitions().Clear();
|
||||
_root.RowDefinitions().Clear();
|
||||
if (_splitState == SplitState::Vertical)
|
||||
{
|
||||
auto firstColDef = Controls::ColumnDefinition();
|
||||
auto secondColDef = Controls::ColumnDefinition();
|
||||
firstColDef.Width(!closeFirst ? GridLengthHelper::FromValueAndType(1, GridUnitType::Star) : GridLengthHelper::Auto());
|
||||
secondColDef.Width(closeFirst ? GridLengthHelper::FromValueAndType(1, GridUnitType::Star) : GridLengthHelper::Auto());
|
||||
_root.ColumnDefinitions().Append(firstColDef);
|
||||
_root.ColumnDefinitions().Append(secondColDef);
|
||||
}
|
||||
else if (_splitState == SplitState::Horizontal)
|
||||
{
|
||||
auto firstRowDef = Controls::RowDefinition();
|
||||
auto secondRowDef = Controls::RowDefinition();
|
||||
firstRowDef.Height(!closeFirst ? GridLengthHelper::FromValueAndType(1, GridUnitType::Star) : GridLengthHelper::Auto());
|
||||
secondRowDef.Height(closeFirst ? GridLengthHelper::FromValueAndType(1, GridUnitType::Star) : GridLengthHelper::Auto());
|
||||
_root.RowDefinitions().Append(firstRowDef);
|
||||
_root.RowDefinitions().Append(secondRowDef);
|
||||
}
|
||||
|
||||
// Animate the dummy grid from its current size down to 0
|
||||
Media::Animation::DoubleAnimation animation{};
|
||||
animation.Duration(AnimationDuration);
|
||||
animation.From(splitWidth ? removedOriginalSize.Width : removedOriginalSize.Height);
|
||||
animation.To(0.0);
|
||||
// This easing is the same as the entrance animation.
|
||||
animation.EasingFunction(Media::Animation::QuadraticEase{});
|
||||
animation.EnableDependentAnimation(true);
|
||||
|
||||
Media::Animation::Storyboard s;
|
||||
s.Duration(AnimationDuration);
|
||||
s.Children().Append(animation);
|
||||
s.SetTarget(animation, dummyGrid);
|
||||
s.SetTargetProperty(animation, splitWidth ? L"Width" : L"Height");
|
||||
|
||||
// Start the animation.
|
||||
s.Begin();
|
||||
|
||||
std::weak_ptr<Pane> weakThis{ shared_from_this() };
|
||||
|
||||
// When the animation is completed, reparent the child's content up to
|
||||
// us, and remove the child nodes from the tree.
|
||||
animation.Completed([weakThis, closeFirst](auto&&, auto&&) {
|
||||
if (auto pane{ weakThis.lock() })
|
||||
{
|
||||
// We don't need to manually undo any of the above trickiness.
|
||||
// We're going to re-parent the child's content into us anyways
|
||||
pane->_CloseChild(closeFirst);
|
||||
}
|
||||
});
|
||||
_CloseChild(closeFirst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,140 +913,6 @@ void Pane::_ApplySplitDefinitions()
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a pair of animations when a new control enters this pane. This
|
||||
// should _ONLY_ be called in _Split, AFTER the first and second child panes
|
||||
// have been set up.
|
||||
void Pane::_SetupEntranceAnimation()
|
||||
{
|
||||
// This will query if animations are enabled via the "Show animations in
|
||||
// Windows" setting in the OS
|
||||
winrt::Windows::UI::ViewManagement::UISettings uiSettings;
|
||||
const auto animationsEnabledInOS = uiSettings.AnimationsEnabled();
|
||||
|
||||
const bool splitWidth = _splitState == SplitState::Vertical;
|
||||
const auto totalSize = splitWidth ? _root.ActualWidth() : _root.ActualHeight();
|
||||
// If we don't have a size yet, it's likely that we're in startup, or we're
|
||||
// being executed as a sequence of actions. In that case, just skip the
|
||||
// animation.
|
||||
if (totalSize <= 0 || !animationsEnabledInOS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto [firstSize, secondSize] = _CalcChildrenSizes(::base::saturated_cast<float>(totalSize));
|
||||
|
||||
// This is safe to capture this, because it's only being called in the
|
||||
// context of this method (not on another thread)
|
||||
auto setupAnimation = [&](const auto& size, const bool isFirstChild) {
|
||||
auto child = isFirstChild ? _firstChild : _secondChild;
|
||||
auto childGrid = child->_root;
|
||||
auto control = child->_control;
|
||||
// Build up our animation:
|
||||
// * it'll take as long as our duration (200ms)
|
||||
// * it'll change the value of our property from 0 to secondSize
|
||||
// * it'll animate that value using a quadratic function (like f(t) = t^2)
|
||||
// * IMPORTANT! We'll manually tell the animation that "yes we know what
|
||||
// we're doing, we want an animation here."
|
||||
Media::Animation::DoubleAnimation animation{};
|
||||
animation.Duration(AnimationDuration);
|
||||
if (isFirstChild)
|
||||
{
|
||||
// If we're animating the first pane, the size should decrease, from
|
||||
// the full size down to the given size.
|
||||
animation.From(totalSize);
|
||||
animation.To(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, we want to show the pane getting larger, so animate
|
||||
// from 0 to the requested size.
|
||||
animation.From(0.0);
|
||||
animation.To(size);
|
||||
}
|
||||
animation.EasingFunction(Media::Animation::QuadraticEase{});
|
||||
animation.EnableDependentAnimation(true);
|
||||
|
||||
// Now we're going to set up the Storyboard. This is a unit that uses the
|
||||
// Animation from above, and actually applies it to a property.
|
||||
// * we'll set it up for the same duration as the animation we have
|
||||
// * Apply the animation to the grid of the new pane we're adding to the tree.
|
||||
// * apply the animation to the Width or Height property.
|
||||
Media::Animation::Storyboard s;
|
||||
s.Duration(AnimationDuration);
|
||||
s.Children().Append(animation);
|
||||
s.SetTarget(animation, childGrid);
|
||||
s.SetTargetProperty(animation, splitWidth ? L"Width" : L"Height");
|
||||
|
||||
// BE TRICKY:
|
||||
// We're animating the width or height of our child pane's grid.
|
||||
//
|
||||
// We DON'T want to change the size of the control itself, because the
|
||||
// terminal has to reflow the buffer every time the control changes size. So
|
||||
// what we're going to do there is manually set the control's size to how
|
||||
// big we _actually know_ the control will be.
|
||||
//
|
||||
// We're also going to be changing alignment of our child pane and the
|
||||
// control. This way, we'll be able to have the control stick to the inside
|
||||
// of the child pane's grid (the side that's moving), while we also have the
|
||||
// pane's grid stick to "outside" of the grid (the side that's not moving)
|
||||
if (splitWidth)
|
||||
{
|
||||
// If we're animating the first child, then stick to the top/left of
|
||||
// the parent pane, otherwise use the bottom/right. This is always
|
||||
// the "outside" of the parent pane.
|
||||
childGrid.HorizontalAlignment(isFirstChild ? HorizontalAlignment::Left : HorizontalAlignment::Right);
|
||||
control.HorizontalAlignment(HorizontalAlignment::Left);
|
||||
control.Width(isFirstChild ? totalSize : size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're animating the first child, then stick to the top/left of
|
||||
// the parent pane, otherwise use the bottom/right. This is always
|
||||
// the "outside" of the parent pane.
|
||||
childGrid.VerticalAlignment(isFirstChild ? VerticalAlignment::Top : VerticalAlignment::Bottom);
|
||||
control.VerticalAlignment(VerticalAlignment::Top);
|
||||
control.Height(isFirstChild ? totalSize : size);
|
||||
}
|
||||
|
||||
// Start the animation.
|
||||
s.Begin();
|
||||
|
||||
std::weak_ptr<Pane> weakThis{ shared_from_this() };
|
||||
// When the animation is completed, undo the trickiness from before, to
|
||||
// restore the controls to the behavior they'd usually have.
|
||||
animation.Completed([weakThis, isFirstChild, splitWidth](auto&&, auto&&) {
|
||||
if (auto pane{ weakThis.lock() })
|
||||
{
|
||||
auto child = isFirstChild ? pane->_firstChild : pane->_secondChild;
|
||||
auto childGrid = child->_root;
|
||||
if (auto control = child->_control)
|
||||
{
|
||||
if (splitWidth)
|
||||
{
|
||||
control.Width(NAN);
|
||||
childGrid.Width(NAN);
|
||||
childGrid.HorizontalAlignment(HorizontalAlignment::Stretch);
|
||||
control.HorizontalAlignment(HorizontalAlignment::Stretch);
|
||||
}
|
||||
else
|
||||
{
|
||||
control.Height(NAN);
|
||||
childGrid.Height(NAN);
|
||||
childGrid.VerticalAlignment(VerticalAlignment::Stretch);
|
||||
control.VerticalAlignment(VerticalAlignment::Stretch);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// TODO: GH#7365 - animating the first child right now doesn't _really_ do
|
||||
// anything. We could do better though.
|
||||
setupAnimation(firstSize, true);
|
||||
setupAnimation(secondSize, false);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether the pane can be split
|
||||
// Arguments:
|
||||
@@ -1457,8 +1153,6 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitState
|
||||
// revoke our handler - the child will take care of the control now.
|
||||
_control.ConnectionStateChanged(_connectionStateChangedToken);
|
||||
_connectionStateChangedToken.value = 0;
|
||||
_control.WarningBell(_warningBellToken);
|
||||
_warningBellToken.value = 0;
|
||||
|
||||
// Remove our old GotFocus handler from the control. We don't what the
|
||||
// control telling us that it's now focused, we want it telling its new
|
||||
@@ -1493,8 +1187,6 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitState
|
||||
|
||||
_lastActive = false;
|
||||
|
||||
_SetupEntranceAnimation();
|
||||
|
||||
return { _firstChild, _secondChild };
|
||||
}
|
||||
|
||||
@@ -2030,8 +1722,8 @@ int Pane::GetLeafPaneCount() const noexcept
|
||||
// - nullopt if `target` is not this pane or a child of this pane, otherwise the
|
||||
// SplitState that `target` would use for an `Automatic` split given
|
||||
// `availableSpace`
|
||||
std::optional<SplitState> Pane::PreCalculateAutoSplit(const std::shared_ptr<Pane> target,
|
||||
const winrt::Windows::Foundation::Size availableSpace) const
|
||||
std::optional<winrt::TerminalApp::SplitState> Pane::PreCalculateAutoSplit(const std::shared_ptr<Pane> target,
|
||||
const winrt::Windows::Foundation::Size availableSpace) const
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
|
||||
@@ -55,17 +55,17 @@ public:
|
||||
const GUID& profile);
|
||||
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
|
||||
void Relayout();
|
||||
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
|
||||
bool NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
|
||||
bool ResizePane(const winrt::TerminalApp::Direction& direction);
|
||||
bool NavigateFocus(const winrt::TerminalApp::Direction& direction);
|
||||
|
||||
bool CanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType);
|
||||
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
|
||||
bool CanSplit(winrt::TerminalApp::SplitState splitType);
|
||||
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::TerminalApp::SplitState splitType,
|
||||
const GUID& profile,
|
||||
const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitState> PreCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
||||
std::optional<winrt::TerminalApp::SplitState> PreCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
||||
std::optional<bool> PreCalculateCanSplit(const std::shared_ptr<Pane> target,
|
||||
winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
|
||||
winrt::TerminalApp::SplitState splitType,
|
||||
const winrt::Windows::Foundation::Size availableSpace) const;
|
||||
void Shutdown();
|
||||
void Close();
|
||||
@@ -91,7 +91,7 @@ private:
|
||||
|
||||
std::shared_ptr<Pane> _firstChild{ nullptr };
|
||||
std::shared_ptr<Pane> _secondChild{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::SplitState _splitState{ winrt::Microsoft::Terminal::Settings::Model::SplitState::None };
|
||||
winrt::TerminalApp::SplitState _splitState{ winrt::TerminalApp::SplitState::None };
|
||||
float _desiredSplitPosition;
|
||||
|
||||
bool _lastActive{ false };
|
||||
@@ -99,7 +99,6 @@ private:
|
||||
winrt::event_token _connectionStateChangedToken{ 0 };
|
||||
winrt::event_token _firstClosedToken{ 0 };
|
||||
winrt::event_token _secondClosedToken{ 0 };
|
||||
winrt::event_token _warningBellToken{ 0 };
|
||||
|
||||
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
|
||||
|
||||
@@ -113,26 +112,23 @@ private:
|
||||
bool _HasFocusedChild() const noexcept;
|
||||
void _SetupChildCloseHandlers();
|
||||
|
||||
bool _CanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType);
|
||||
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> _Split(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
|
||||
bool _CanSplit(winrt::TerminalApp::SplitState splitType);
|
||||
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> _Split(winrt::TerminalApp::SplitState splitType,
|
||||
const GUID& profile,
|
||||
const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
|
||||
void _CreateRowColDefinitions();
|
||||
void _ApplySplitDefinitions();
|
||||
void _SetupEntranceAnimation();
|
||||
void _UpdateBorders();
|
||||
|
||||
bool _Resize(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
|
||||
bool _NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
|
||||
bool _Resize(const winrt::TerminalApp::Direction& direction);
|
||||
bool _NavigateFocus(const winrt::TerminalApp::Direction& direction);
|
||||
|
||||
void _CloseChild(const bool closeFirst);
|
||||
winrt::fire_and_forget _CloseChildRoutine(const bool closeFirst);
|
||||
|
||||
void _FocusFirstChild();
|
||||
void _ControlConnectionStateChangedHandler(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _ControlWarningBellHandler(winrt::Windows::Foundation::IInspectable const& sender,
|
||||
winrt::Windows::Foundation::IInspectable const& e);
|
||||
void _ControlGotFocusHandler(winrt::Windows::Foundation::IInspectable const& sender,
|
||||
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
|
||||
@@ -145,9 +141,9 @@ private:
|
||||
LayoutSizeNode _CreateMinSizeTree(const bool widthOrHeight) const;
|
||||
float _ClampSplitPosition(const bool widthOrHeight, const float requestedValue, const float totalSize) const;
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::SplitState _convertAutomaticSplitState(const winrt::Microsoft::Terminal::Settings::Model::SplitState& splitType) const;
|
||||
winrt::TerminalApp::SplitState _convertAutomaticSplitState(const winrt::TerminalApp::SplitState& splitType) const;
|
||||
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitState> _preCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
||||
std::optional<winrt::TerminalApp::SplitState> _preCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
|
||||
|
||||
// Function Description:
|
||||
// - Returns true if the given direction can be used with the given split
|
||||
@@ -163,22 +159,22 @@ private:
|
||||
// Return Value:
|
||||
// - true iff the direction is perpendicular to the splitType. False for
|
||||
// winrt::TerminalApp::SplitState::None.
|
||||
static constexpr bool DirectionMatchesSplit(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::SplitState& splitType)
|
||||
static constexpr bool DirectionMatchesSplit(const winrt::TerminalApp::Direction& direction,
|
||||
const winrt::TerminalApp::SplitState& splitType)
|
||||
{
|
||||
if (splitType == winrt::Microsoft::Terminal::Settings::Model::SplitState::None)
|
||||
if (splitType == winrt::TerminalApp::SplitState::None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (splitType == winrt::Microsoft::Terminal::Settings::Model::SplitState::Horizontal)
|
||||
else if (splitType == winrt::TerminalApp::SplitState::Horizontal)
|
||||
{
|
||||
return direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Up ||
|
||||
direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Down;
|
||||
return direction == winrt::TerminalApp::Direction::Up ||
|
||||
direction == winrt::TerminalApp::Direction::Down;
|
||||
}
|
||||
else if (splitType == winrt::Microsoft::Terminal::Settings::Model::SplitState::Vertical)
|
||||
else if (splitType == winrt::TerminalApp::SplitState::Vertical)
|
||||
{
|
||||
return direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Left ||
|
||||
direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Right;
|
||||
return direction == winrt::TerminalApp::Direction::Left ||
|
||||
direction == winrt::TerminalApp::Direction::Right;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -135,8 +135,8 @@ namespace
|
||||
};
|
||||
}
|
||||
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::TerminalApp;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
// Function Description:
|
||||
// - Finds all powershell instances with the traditional layout under a directory.
|
||||
@@ -313,7 +313,7 @@ std::vector<Profile> PowershellCoreProfileGenerator::GenerateProfiles()
|
||||
profile.StartingDirectory(DEFAULT_STARTING_DIRECTORY);
|
||||
profile.ColorSchemeName(L"Campbell");
|
||||
|
||||
profile.Icon(WI_IsFlagSet(psI.flags, PowerShellFlags::Preview) ? POWERSHELL_PREVIEW_ICON : POWERSHELL_ICON);
|
||||
profile.IconPath(WI_IsFlagSet(psI.flags, PowerShellFlags::Preview) ? POWERSHELL_PREVIEW_ICON : POWERSHELL_ICON);
|
||||
profiles.emplace_back(std::move(profile));
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ Author(s):
|
||||
|
||||
#include "IDynamicProfileGenerator.h"
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
class PowershellCoreProfileGenerator : public Microsoft::Terminal::Settings::Model::IDynamicProfileGenerator
|
||||
class PowershellCoreProfileGenerator : public TerminalApp::IDynamicProfileGenerator
|
||||
{
|
||||
public:
|
||||
static const std::wstring_view GetPreferredPowershellProfileName();
|
||||
@@ -29,6 +29,6 @@ namespace Microsoft::Terminal::Settings::Model
|
||||
~PowershellCoreProfileGenerator() = default;
|
||||
std::wstring_view GetNamespace() override;
|
||||
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::Profile> GenerateProfiles() override;
|
||||
std::vector<winrt::TerminalApp::Profile> GenerateProfiles() override;
|
||||
};
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "Profile.h"
|
||||
#include "Utils.h"
|
||||
#include "JsonUtils.h"
|
||||
#include "../../types/inc/Utils.hpp"
|
||||
#include <DefaultSettings.h>
|
||||
@@ -12,8 +13,8 @@
|
||||
|
||||
#include "Profile.g.cpp"
|
||||
|
||||
using namespace Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::TerminalApp::implementation;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Windows::UI;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@@ -57,9 +58,6 @@ static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageA
|
||||
static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" };
|
||||
static constexpr std::string_view AntialiasingModeKey{ "antialiasingMode" };
|
||||
static constexpr std::string_view TabColorKey{ "tabColor" };
|
||||
static constexpr std::string_view BellStyleKey{ "bellStyle" };
|
||||
|
||||
static const winrt::hstring DesktopWallpaperEnum{ L"DesktopWallpaper" };
|
||||
|
||||
Profile::Profile()
|
||||
{
|
||||
@@ -70,49 +68,6 @@ Profile::Profile(guid guid) :
|
||||
{
|
||||
}
|
||||
|
||||
winrt::com_ptr<Profile> Profile::Copy() const
|
||||
{
|
||||
auto profile{ winrt::make_self<Profile>() };
|
||||
profile->_Name = _Name;
|
||||
profile->_Source = _Source;
|
||||
profile->_Hidden = _Hidden;
|
||||
profile->_Icon = _Icon;
|
||||
profile->_CloseOnExit = _CloseOnExit;
|
||||
profile->_TabTitle = _TabTitle;
|
||||
profile->_TabColor = _TabColor;
|
||||
profile->_SuppressApplicationTitle = _SuppressApplicationTitle;
|
||||
profile->_UseAcrylic = _UseAcrylic;
|
||||
profile->_AcrylicOpacity = _AcrylicOpacity;
|
||||
profile->_ScrollState = _ScrollState;
|
||||
profile->_FontFace = _FontFace;
|
||||
profile->_FontSize = _FontSize;
|
||||
profile->_FontWeight = _FontWeight;
|
||||
profile->_Padding = _Padding;
|
||||
profile->_Commandline = _Commandline;
|
||||
profile->_StartingDirectory = _StartingDirectory;
|
||||
profile->_BackgroundImagePath = _BackgroundImagePath;
|
||||
profile->_BackgroundImageOpacity = _BackgroundImageOpacity;
|
||||
profile->_BackgroundImageStretchMode = _BackgroundImageStretchMode;
|
||||
profile->_AntialiasingMode = _AntialiasingMode;
|
||||
profile->_RetroTerminalEffect = _RetroTerminalEffect;
|
||||
profile->_ForceFullRepaintRendering = _ForceFullRepaintRendering;
|
||||
profile->_SoftwareRendering = _SoftwareRendering;
|
||||
profile->_ColorSchemeName = _ColorSchemeName;
|
||||
profile->_Foreground = _Foreground;
|
||||
profile->_Background = _Background;
|
||||
profile->_SelectionBackground = _SelectionBackground;
|
||||
profile->_CursorColor = _CursorColor;
|
||||
profile->_HistorySize = _HistorySize;
|
||||
profile->_SnapOnInput = _SnapOnInput;
|
||||
profile->_AltGrAliasing = _AltGrAliasing;
|
||||
profile->_CursorShape = _CursorShape;
|
||||
profile->_CursorHeight = _CursorHeight;
|
||||
profile->_Guid = _Guid;
|
||||
profile->_ConnectionType = _ConnectionType;
|
||||
profile->_BackgroundImageAlignment = _BackgroundImageAlignment;
|
||||
return profile;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Generates a Json::Value which is a "stub" of this profile. This stub will
|
||||
// have enough information that it could be layered with this profile.
|
||||
@@ -152,7 +107,7 @@ Json::Value Profile::GenerateStub() const
|
||||
// - json: an object which should be a serialization of a Profile object.
|
||||
// Return Value:
|
||||
// - a new Profile instance created from the values in `json`
|
||||
winrt::com_ptr<winrt::Microsoft::Terminal::Settings::Model::implementation::Profile> Profile::FromJson(const Json::Value& json)
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::Profile> Profile::FromJson(const Json::Value& json)
|
||||
{
|
||||
auto result = winrt::make_self<Profile>();
|
||||
result->LayerJson(json);
|
||||
@@ -278,7 +233,7 @@ void Profile::LayerJson(const Json::Value& json)
|
||||
|
||||
JsonUtils::GetValueForKey(json, ScrollbarStateKey, _ScrollState);
|
||||
JsonUtils::GetValueForKey(json, StartingDirectoryKey, _StartingDirectory);
|
||||
JsonUtils::GetValueForKey(json, IconKey, _Icon);
|
||||
JsonUtils::GetValueForKey(json, IconKey, _IconPath);
|
||||
JsonUtils::GetValueForKey(json, BackgroundImageKey, _BackgroundImagePath);
|
||||
JsonUtils::GetValueForKey(json, BackgroundImageOpacityKey, _BackgroundImageOpacity);
|
||||
JsonUtils::GetValueForKey(json, BackgroundImageStretchModeKey, _BackgroundImageStretchMode);
|
||||
@@ -287,43 +242,36 @@ void Profile::LayerJson(const Json::Value& json)
|
||||
JsonUtils::GetValueForKey(json, AntialiasingModeKey, _AntialiasingMode);
|
||||
|
||||
JsonUtils::GetValueForKey(json, TabColorKey, _TabColor);
|
||||
|
||||
JsonUtils::GetValueForKey(json, BellStyleKey, _BellStyle);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Either Returns this profile's background image path, if one is set, expanding
|
||||
// - Returns this profile's icon path, if one is set. Otherwise returns the
|
||||
// empty string. This method will expand any environment variables in the
|
||||
// path, if there are any.
|
||||
// Return Value:
|
||||
// - this profile's icon path, if one is set. Otherwise returns the empty string.
|
||||
winrt::hstring Profile::ExpandedIconPath() const
|
||||
{
|
||||
if (_IconPath.empty())
|
||||
{
|
||||
return _IconPath;
|
||||
}
|
||||
winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW<std::wstring>(_IconPath.c_str()) };
|
||||
return envExpandedPath;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns this profile's background image path, if one is set, expanding
|
||||
// any environment variables in the path, if there are any.
|
||||
// - Or if "DesktopWallpaper" is set, then gets the path to the desktops wallpaper.
|
||||
// Return Value:
|
||||
// - This profile's expanded background image path / desktops's wallpaper path /the empty string.
|
||||
// - This profile's expanded background image path / the empty string.
|
||||
winrt::hstring Profile::ExpandedBackgroundImagePath() const
|
||||
{
|
||||
if (_BackgroundImagePath.empty())
|
||||
{
|
||||
return _BackgroundImagePath;
|
||||
}
|
||||
// checks if the user would like to copy their desktop wallpaper
|
||||
// if so, replaces the path with the desktop wallpaper's path
|
||||
else if (_BackgroundImagePath == to_hstring(DesktopWallpaperEnum))
|
||||
{
|
||||
WCHAR desktopWallpaper[MAX_PATH];
|
||||
|
||||
// "The returned string will not exceed MAX_PATH characters" as of 2020
|
||||
if (SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, desktopWallpaper, SPIF_UPDATEINIFILE))
|
||||
{
|
||||
return winrt::hstring{ (desktopWallpaper) };
|
||||
}
|
||||
else
|
||||
{
|
||||
return winrt::hstring{ L"" };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return winrt::hstring{ wil::ExpandEnvironmentStringsW<std::wstring>(_BackgroundImagePath.c_str()) };
|
||||
}
|
||||
return winrt::hstring{ wil::ExpandEnvironmentStringsW<std::wstring>(_BackgroundImagePath.c_str()) };
|
||||
}
|
||||
|
||||
winrt::hstring Profile::EvaluatedStartingDirectory() const
|
||||
@@ -375,7 +323,7 @@ void Profile::GenerateGuidIfNecessary() noexcept
|
||||
_Guid = Profile::_GenerateGuidForProfile(_Name, _Source);
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hSettingsModelProvider,
|
||||
g_hTerminalAppProvider,
|
||||
"SynthesizedGuidForProfile",
|
||||
TraceLoggingDescription("Event emitted when a profile is deserialized without a GUID"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
@@ -37,14 +37,13 @@ namespace TerminalAppUnitTests
|
||||
// GUID specified manually.
|
||||
constexpr GUID RUNTIME_GENERATED_PROFILE_NAMESPACE_GUID = { 0xf65ddb7e, 0x706b, 0x4499, { 0x8a, 0x50, 0x40, 0x31, 0x3c, 0xaf, 0x51, 0x0a } };
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct Profile : ProfileT<Profile>
|
||||
{
|
||||
public:
|
||||
Profile();
|
||||
Profile(guid guid);
|
||||
com_ptr<Profile> Copy() const;
|
||||
|
||||
Json::Value GenerateStub() const;
|
||||
static com_ptr<Profile> FromJson(const Json::Value& json);
|
||||
@@ -53,6 +52,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static bool IsDynamicProfileObject(const Json::Value& json);
|
||||
|
||||
hstring EvaluatedStartingDirectory() const;
|
||||
hstring ExpandedIconPath() const;
|
||||
hstring ExpandedBackgroundImagePath() const;
|
||||
void GenerateGuidIfNecessary() noexcept;
|
||||
static guid GetGuidOrGenerateForJson(const Json::Value& json) noexcept;
|
||||
@@ -75,7 +75,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
GETSET_PROPERTY(hstring, Source);
|
||||
GETSET_PROPERTY(bool, Hidden, false);
|
||||
|
||||
GETSET_PROPERTY(hstring, Icon);
|
||||
GETSET_PROPERTY(hstring, IconPath);
|
||||
|
||||
GETSET_PROPERTY(CloseOnExitMode, CloseOnExit, CloseOnExitMode::Graceful);
|
||||
GETSET_PROPERTY(hstring, TabTitle);
|
||||
@@ -96,7 +96,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
GETSET_PROPERTY(hstring, BackgroundImagePath);
|
||||
GETSET_PROPERTY(double, BackgroundImageOpacity, 1.0);
|
||||
GETSET_PROPERTY(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::Fill);
|
||||
GETSET_PROPERTY(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::UniformToFill);
|
||||
|
||||
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::TerminalControl::TextAntialiasingMode::Grayscale);
|
||||
GETSET_PROPERTY(bool, RetroTerminalEffect, false);
|
||||
@@ -116,8 +116,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::CursorStyle, CursorShape, Microsoft::Terminal::TerminalControl::CursorStyle::Bar);
|
||||
GETSET_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
|
||||
|
||||
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::Model::BellStyle, BellStyle, winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible);
|
||||
|
||||
private:
|
||||
std::optional<winrt::guid> _Guid{ std::nullopt };
|
||||
std::optional<winrt::guid> _ConnectionType{ std::nullopt };
|
||||
@@ -137,7 +135,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Profile);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
namespace TerminalApp
|
||||
{
|
||||
enum CloseOnExitMode
|
||||
{
|
||||
@@ -10,12 +10,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Always
|
||||
};
|
||||
|
||||
enum BellStyle
|
||||
{
|
||||
None,
|
||||
Audible
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass Profile {
|
||||
Profile();
|
||||
Profile(Guid guid);
|
||||
@@ -28,7 +22,8 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Guid ConnectionType;
|
||||
Boolean Hidden;
|
||||
|
||||
String Icon;
|
||||
String IconPath;
|
||||
String ExpandedIconPath { get; };
|
||||
|
||||
CloseOnExitMode CloseOnExit;
|
||||
String TabTitle;
|
||||
@@ -72,7 +67,5 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
Microsoft.Terminal.TerminalControl.CursorStyle CursorShape;
|
||||
UInt32 CursorHeight;
|
||||
|
||||
BellStyle BellStyle;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,36 +26,36 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
@@ -149,6 +149,16 @@
|
||||
<data name="SettingsValidateErrorTitle" xml:space="preserve">
|
||||
<value>Encountered errors while loading user settings</value>
|
||||
</data>
|
||||
<data name="KeyboardServiceDisabledDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name="KeyboardServiceDisabledDialog.Title" xml:space="preserve">
|
||||
<value>Warning:</value>
|
||||
</data>
|
||||
<data name="KeyboardServiceWarningText" xml:space="preserve">
|
||||
<value>The "{0}" isn't running on your machine. This can prevent the Terminal from receiving keyboard input.</value>
|
||||
<comment>{0} will be replaced with the OS-localized name of the TabletInputService</comment>
|
||||
</data>
|
||||
<data name="Ok" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
@@ -177,17 +187,8 @@
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Do you want to close all tabs?</value>
|
||||
</data>
|
||||
<data name="TabCloseSubMenu" xml:space="preserve">
|
||||
<value>Close...</value>
|
||||
</data>
|
||||
<data name="TabCloseAfter" xml:space="preserve">
|
||||
<value>Close Tabs to the Right</value>
|
||||
</data>
|
||||
<data name="TabCloseOther" xml:space="preserve">
|
||||
<value>Close Other Tabs</value>
|
||||
</data>
|
||||
<data name="TabClose" xml:space="preserve">
|
||||
<value>Close Tab</value>
|
||||
<value>Close</value>
|
||||
</data>
|
||||
<data name="TabColorChoose" xml:space="preserve">
|
||||
<value>Color...</value>
|
||||
@@ -294,9 +295,6 @@
|
||||
<data name="CmdFullscreenDesc" xml:space="preserve">
|
||||
<value>Launch the window in fullscreen mode</value>
|
||||
</data>
|
||||
<data name="CmdFocusDesc" xml:space="preserve">
|
||||
<value>Launch the window in focus mode</value>
|
||||
</data>
|
||||
<data name="NewTabSplitButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.HelpText" xml:space="preserve">
|
||||
<value>Press the button to open a new terminal tab with your default profile. Open the flyout to select which profile you want to open.</value>
|
||||
</data>
|
||||
@@ -357,6 +355,14 @@
|
||||
<value>Third-Party Notices</value>
|
||||
<comment>A hyperlink name for the Terminal's third-party notices</comment>
|
||||
</data>
|
||||
<data name="ApplicationDisplayNameUnpackaged" xml:space="preserve">
|
||||
<value>Windows Terminal (Unpackaged)</value>
|
||||
<comment>This display name is used when the application's name cannot be determined</comment>
|
||||
</data>
|
||||
<data name="ApplicationVersionUnknown" xml:space="preserve">
|
||||
<value>Unknown</value>
|
||||
<comment>This is displayed when the version of the application cannot be determined</comment>
|
||||
</data>
|
||||
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
@@ -366,6 +372,10 @@
|
||||
<data name="CloseAllDialog.Title" xml:space="preserve">
|
||||
<value>Do you want to close all tabs?</value>
|
||||
</data>
|
||||
<data name="CommandPromptDisplayName" xml:space="preserve">
|
||||
<value>Command Prompt</value>
|
||||
<comment>This is the name of "Command Prompt", as localized in Windows. The localization here should match the one in the Windows product for "Command Prompt"</comment>
|
||||
</data>
|
||||
<data name="LargePasteDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
@@ -396,9 +406,198 @@
|
||||
<data name="CommandPalette_NoMatchesText.Text" xml:space="preserve">
|
||||
<value>No matching commands</value>
|
||||
</data>
|
||||
<data name="CloseWindowCommandKey" xml:space="preserve">
|
||||
<value>Close window</value>
|
||||
</data>
|
||||
<data name="ToggleFocusModeCommandKey" xml:space="preserve">
|
||||
<value>Toggle focus mode</value>
|
||||
<comment>"Focus mode" is a mode with minimal UI elements, for a distraction-free experience</comment>
|
||||
</data>
|
||||
<data name="ToggleFullscreenCommandKey" xml:space="preserve">
|
||||
<value>Toggle fullscreen</value>
|
||||
</data>
|
||||
<data name="ToggleAlwaysOnTopCommandKey" xml:space="preserve">
|
||||
<value>Toggle always on top mode</value>
|
||||
</data>
|
||||
<data name="OpenNewTabDropdownCommandKey" xml:space="preserve">
|
||||
<value>Open new tab dropdown</value>
|
||||
</data>
|
||||
<data name="OpenSettingsCommandKey" xml:space="preserve">
|
||||
<value>Open settings file</value>
|
||||
</data>
|
||||
<data name="OpenDefaultSettingsCommandKey" xml:space="preserve">
|
||||
<value>Open default settings file</value>
|
||||
</data>
|
||||
<data name="OpenBothSettingsFilesCommandKey" xml:space="preserve">
|
||||
<value>Open both settings and default settings files</value>
|
||||
</data>
|
||||
<data name="FindCommandKey" xml:space="preserve">
|
||||
<value>Find</value>
|
||||
</data>
|
||||
<data name="ResizePaneCommandKey" xml:space="preserve">
|
||||
<value>Resize pane</value>
|
||||
</data>
|
||||
<data name="MoveFocusCommandKey" xml:space="preserve">
|
||||
<value>Move focus</value>
|
||||
</data>
|
||||
<data name="MoveFocusWithArgCommandKey" xml:space="preserve">
|
||||
<value>Move focus {0}</value>
|
||||
<comment>{0} will be replaced with one of the four directions "DirectionLeft", "DirectionRight", "DirectionUp", or "DirectionDown"</comment>
|
||||
</data>
|
||||
<data name="ResizePaneWithArgCommandKey" xml:space="preserve">
|
||||
<value>Resize pane {0}</value>
|
||||
<comment>{0} will be replaced with one of the four directions "DirectionLeft", "DirectionRight", "DirectionUp", or "DirectionDown"</comment>
|
||||
</data>
|
||||
<data name="DirectionLeft" xml:space="preserve">
|
||||
<value>left</value>
|
||||
</data>
|
||||
<data name="DirectionRight" xml:space="preserve">
|
||||
<value>right</value>
|
||||
</data>
|
||||
<data name="DirectionUp" xml:space="preserve">
|
||||
<value>up</value>
|
||||
</data>
|
||||
<data name="DirectionDown" xml:space="preserve">
|
||||
<value>down</value>
|
||||
</data>
|
||||
<data name="SwitchToTabCommandKey" xml:space="preserve">
|
||||
<value>Switch to tab</value>
|
||||
</data>
|
||||
<data name="NewTabCommandKey" xml:space="preserve">
|
||||
<value>New tab</value>
|
||||
</data>
|
||||
<data name="SendInputCommandKey" xml:space="preserve">
|
||||
<value>Send Input: "{0}"</value>
|
||||
<comment>{0} will be replaced with a string of input as defined by the user</comment>
|
||||
</data>
|
||||
<data name="SplitPaneCommandKey" xml:space="preserve">
|
||||
<value>Split pane</value>
|
||||
</data>
|
||||
<data name="TogglePaneZoomCommandKey" xml:space="preserve">
|
||||
<value>Toggle pane zoom</value>
|
||||
</data>
|
||||
<data name="NewWindowCommandKey" xml:space="preserve">
|
||||
<value>New window</value>
|
||||
</data>
|
||||
<data name="DuplicateTabCommandKey" xml:space="preserve">
|
||||
<value>Duplicate tab</value>
|
||||
</data>
|
||||
<data name="DuplicatePaneCommandKey" xml:space="preserve">
|
||||
<value>Duplicate pane</value>
|
||||
</data>
|
||||
<data name="NextTabCommandKey" xml:space="preserve">
|
||||
<value>Next tab</value>
|
||||
</data>
|
||||
<data name="PrevTabCommandKey" xml:space="preserve">
|
||||
<value>Previous tab</value>
|
||||
</data>
|
||||
<data name="ClosePaneCommandKey" xml:space="preserve">
|
||||
<value>Close pane</value>
|
||||
</data>
|
||||
<data name="CloseTabCommandKey" xml:space="preserve">
|
||||
<value>Close tab</value>
|
||||
</data>
|
||||
<data name="SplitHorizontalCommandKey" xml:space="preserve">
|
||||
<value>Split pane horizontally</value>
|
||||
</data>
|
||||
<data name="SplitVerticalCommandKey" xml:space="preserve">
|
||||
<value>Split pane vertically</value>
|
||||
</data>
|
||||
<data name="CopyTextCommandKey" xml:space="preserve">
|
||||
<value>Copy text</value>
|
||||
</data>
|
||||
<data name="CopyTextAsSingleLineCommandKey" xml:space="preserve">
|
||||
<value>Copy text as a single line</value>
|
||||
</data>
|
||||
<data name="PasteTextCommandKey" xml:space="preserve">
|
||||
<value>Paste</value>
|
||||
</data>
|
||||
<data name="ScrollDownCommandKey" xml:space="preserve">
|
||||
<value>Scroll down one line</value>
|
||||
</data>
|
||||
<data name="ScrollDownPageCommandKey" xml:space="preserve">
|
||||
<value>Scroll down one page</value>
|
||||
</data>
|
||||
<data name="ScrollUpCommandKey" xml:space="preserve">
|
||||
<value>Scroll up one line</value>
|
||||
</data>
|
||||
<data name="ScrollUpPageCommandKey" xml:space="preserve">
|
||||
<value>Scroll up one page</value>
|
||||
</data>
|
||||
<data name="AdjustFontSizeCommandKey" xml:space="preserve">
|
||||
<value>Adjust font size</value>
|
||||
</data>
|
||||
<data name="IncreaseFontSizeCommandKey" xml:space="preserve">
|
||||
<value>Increase font size</value>
|
||||
</data>
|
||||
<data name="DecreaseFontSizeCommandKey" xml:space="preserve">
|
||||
<value>Decrease font size</value>
|
||||
</data>
|
||||
<data name="IncreaseFontSizeWithAmountCommandKey" xml:space="preserve">
|
||||
<value>Increase font size, amount: {0}</value>
|
||||
<comment>{0} will be replaced with a positive number</comment>
|
||||
</data>
|
||||
<data name="DecreaseFontSizeWithAmountCommandKey" xml:space="preserve">
|
||||
<value>Decrease font size, amount: {0}</value>
|
||||
<comment>{0} will be replaced with a positive number</comment>
|
||||
</data>
|
||||
<data name="ResetFontSizeCommandKey" xml:space="preserve">
|
||||
<value>Reset font size</value>
|
||||
</data>
|
||||
<data name="ToggleRetroEffectCommandKey" xml:space="preserve">
|
||||
<value>Toggle retro terminal effect</value>
|
||||
</data>
|
||||
<data name="ToggleCommandPaletteCommandKey" xml:space="preserve">
|
||||
<value>Toggle command palette</value>
|
||||
</data>
|
||||
<data name="CommandPaletteControlName" xml:space="preserve">
|
||||
<value>Command Palette</value>
|
||||
</data>
|
||||
<data name="SetColorSchemeCommandKey" xml:space="preserve">
|
||||
<value>Set color scheme to {0}</value>
|
||||
<comment>{0} will be replaced with the name of a color scheme as defined by the user.</comment>
|
||||
</data>
|
||||
<data name="SetTabColorCommandKey" xml:space="preserve">
|
||||
<value>Set tab color to {0}</value>
|
||||
<comment>{0} will be replaced with a color, displayed in hexadecimal (#RRGGBB) notation.</comment>
|
||||
</data>
|
||||
<data name="ResetTabColorCommandKey" xml:space="preserve">
|
||||
<value>Reset tab color</value>
|
||||
</data>
|
||||
<data name="OpenTabColorPickerCommandKey" xml:space="preserve">
|
||||
<value>Set the tab color...</value>
|
||||
</data>
|
||||
<data name="RenameTabCommandKey" xml:space="preserve">
|
||||
<value>Rename tab to "{0}"</value>
|
||||
<comment>{0} will be replaced with a user-defined string</comment>
|
||||
</data>
|
||||
<data name="ResetTabNameCommandKey" xml:space="preserve">
|
||||
<value>Reset tab title</value>
|
||||
</data>
|
||||
<data name="ExecuteCommandlineCommandKey" xml:space="preserve">
|
||||
<value>Run commandline "{0}" in this window</value>
|
||||
<comment>{0} will be replaced with a user-defined commandline</comment>
|
||||
</data>
|
||||
<data name="CloseOtherTabsCommandKey" xml:space="preserve">
|
||||
<value>Close tabs other than index {0}</value>
|
||||
<comment>{0} will be replaced with a number</comment>
|
||||
</data>
|
||||
<data name="CloseTabsAfterCommandKey" xml:space="preserve">
|
||||
<value>Close tabs after index {0}</value>
|
||||
<comment>{0} will be replaced with a number</comment>
|
||||
</data>
|
||||
<data name="SetColorSchemeParentCommandName" xml:space="preserve">
|
||||
<value>Select color scheme...</value>
|
||||
</data>
|
||||
<data name="TabSearchCommandKey" xml:space="preserve">
|
||||
<value>Search for tab...</value>
|
||||
</data>
|
||||
<data name="NewTabParentCommandName" xml:space="preserve">
|
||||
<value>New Tab...</value>
|
||||
</data>
|
||||
<data name="SplitPaneParentCommandName" xml:space="preserve">
|
||||
<value>Split Pane...</value>
|
||||
</data>
|
||||
<data name="TabSwitcherControlName" xml:space="preserve">
|
||||
<value>Tab Switcher</value>
|
||||
</data>
|
||||
@@ -460,6 +659,12 @@
|
||||
<data name="DarkGrayColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Dark Gray</value>
|
||||
</data>
|
||||
<data name="CloseOtherTabsDefaultCommandKey" xml:space="preserve">
|
||||
<value>Close all other tabs</value>
|
||||
</data>
|
||||
<data name="CloseTabsAfterDefaultCommandKey" xml:space="preserve">
|
||||
<value>Close all tabs after the current tab</value>
|
||||
</data>
|
||||
<data name="InvalidUriText" xml:space="preserve">
|
||||
<value>This link is invalid:</value>
|
||||
</data>
|
||||
@@ -469,7 +674,7 @@
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
<data name="FailedToWriteToSettings" xml:space="preserve">
|
||||
<value>We could not write to your settings file. Check the permissions on that file to ensure that the read-only flag is not set and that write access is granted.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include <LibraryResources.h>
|
||||
#include "SettingsTab.h"
|
||||
#include "SettingsTab.g.cpp"
|
||||
#include "Utils.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Windows::System;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
SettingsTab::SettingsTab(winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings settings)
|
||||
{
|
||||
Content(winrt::Microsoft::Terminal::Settings::Editor::MainPage(settings));
|
||||
|
||||
_MakeTabViewItem();
|
||||
_CreateContextMenu();
|
||||
_CreateIcon();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes a TabViewItem for this Tab instance.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void SettingsTab::_MakeTabViewItem()
|
||||
{
|
||||
TabViewItem(::winrt::MUX::Controls::TabViewItem{});
|
||||
Title(RS_(L"SettingsTab"));
|
||||
TabViewItem().Header(winrt::box_value(Title()));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Focus the settings UI
|
||||
// Arguments:
|
||||
// - focusState: The FocusState mode by which focus is to be obtained.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void SettingsTab::Focus(WUX::FocusState focusState)
|
||||
{
|
||||
_focusState = focusState;
|
||||
|
||||
if (_focusState != FocusState::Unfocused)
|
||||
{
|
||||
Content().Focus(focusState);
|
||||
}
|
||||
}
|
||||
|
||||
WUX::FocusState SettingsTab::FocusState() const noexcept
|
||||
{
|
||||
return _focusState;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Set the icon on the TabViewItem for this tab.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget SettingsTab::_CreateIcon()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
co_await winrt::resume_foreground(TabViewItem().Dispatcher());
|
||||
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
auto fontFamily = winrt::WUX::Media::FontFamily(L"Segoe MDL2 Assets");
|
||||
auto glyph = L"\xE713"; // This is the Setting icon (looks like a gear)
|
||||
|
||||
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
||||
Icon(glyph);
|
||||
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(glyph));
|
||||
|
||||
// Update SwitchToTab command's icon
|
||||
SwitchToTabCommand().Icon(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Prepares this tab for being removed from the UI hierarchy
|
||||
void SettingsTab::Shutdown()
|
||||
{
|
||||
// TODO: Does/Will the settings UI need some shutdown procedures?
|
||||
Content(nullptr);
|
||||
_ClosedHandlers(nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a context menu attached to the tab.
|
||||
// Currently contains elements allowing the user to close the selected tab
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void SettingsTab::_CreateContextMenu()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Close
|
||||
Controls::MenuFlyoutItem closeTabMenuItem;
|
||||
Controls::FontIcon closeSymbol;
|
||||
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
|
||||
closeSymbol.Glyph(L"\xE8BB");
|
||||
|
||||
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_ClosedHandlers(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
closeTabMenuItem.Text(RS_(L"TabClose"));
|
||||
closeTabMenuItem.Icon(closeSymbol);
|
||||
|
||||
// Build the menu
|
||||
Controls::MenuFlyout newTabFlyout;
|
||||
newTabFlyout.Items().Append(_CreateCloseSubMenu());
|
||||
newTabFlyout.Items().Append(closeTabMenuItem);
|
||||
TabViewItem().ContextFlyout(newTabFlyout);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a sub-menu containing menu items to close multiple tabs
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the created MenuFlyoutSubItem
|
||||
Controls::MenuFlyoutSubItem SettingsTab::_CreateCloseSubMenu()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Close tabs after
|
||||
_closeTabsAfterMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_CloseTabsAfter();
|
||||
}
|
||||
});
|
||||
_closeTabsAfterMenuItem.Text(RS_(L"TabCloseAfter"));
|
||||
|
||||
// Close other tabs
|
||||
_closeOtherTabsMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_CloseOtherTabs();
|
||||
}
|
||||
});
|
||||
_closeOtherTabsMenuItem.Text(RS_(L"TabCloseOther"));
|
||||
|
||||
Controls::MenuFlyoutSubItem closeSubMenu;
|
||||
closeSubMenu.Text(RS_(L"TabCloseSubMenu"));
|
||||
closeSubMenu.Items().Append(_closeTabsAfterMenuItem);
|
||||
closeSubMenu.Items().Append(_closeOtherTabsMenuItem);
|
||||
|
||||
return closeSubMenu;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Enable the Close menu items based on tab index and total number of tabs
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void SettingsTab::_EnableCloseMenuItems()
|
||||
{
|
||||
// close other tabs is enabled only if there are other tabs
|
||||
_closeOtherTabsMenuItem.IsEnabled(TabViewNumTabs() > 1);
|
||||
// close tabs after is enabled only if there are other tabs on the right
|
||||
_closeTabsAfterMenuItem.IsEnabled(TabViewIndex() < TabViewNumTabs() - 1);
|
||||
}
|
||||
|
||||
void SettingsTab::_CloseTabsAfter()
|
||||
{
|
||||
CloseTabsAfterArgs args{ _TabViewIndex };
|
||||
ActionAndArgs closeTabsAfter{ ShortcutAction::CloseTabsAfter, args };
|
||||
|
||||
_dispatch.DoAction(closeTabsAfter);
|
||||
}
|
||||
|
||||
void SettingsTab::_CloseOtherTabs()
|
||||
{
|
||||
CloseOtherTabsArgs args{ _TabViewIndex };
|
||||
ActionAndArgs closeOtherTabs{ ShortcutAction::CloseOtherTabs, args };
|
||||
|
||||
_dispatch.DoAction(closeOtherTabs);
|
||||
}
|
||||
|
||||
void SettingsTab::SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch)
|
||||
{
|
||||
_dispatch = dispatch;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- SettingsTab.h
|
||||
|
||||
Abstract:
|
||||
- The SettingsTab is a tab whose content is a Settings UI control. They can
|
||||
coexist in a TabView with all other types of tabs, like the TerminalTab.
|
||||
There should only be at most one SettingsTab open at any given time.
|
||||
|
||||
Author(s):
|
||||
- Leon Liang - October 2020
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
#include "SettingsTab.g.h"
|
||||
#include <winrt/TerminalApp.h>
|
||||
#include <winrt/Microsoft.Terminal.Settings.Editor.h>
|
||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct SettingsTab : SettingsTabT<SettingsTab>
|
||||
{
|
||||
public:
|
||||
SettingsTab(winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings settings);
|
||||
void Focus(winrt::Windows::UI::Xaml::FocusState focusState);
|
||||
winrt::Windows::UI::Xaml::FocusState FocusState() const noexcept;
|
||||
|
||||
void Shutdown();
|
||||
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
||||
GETSET_PROPERTY(winrt::hstring, Title);
|
||||
GETSET_PROPERTY(winrt::hstring, Icon);
|
||||
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::Model::Command, SwitchToTabCommand, nullptr);
|
||||
GETSET_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewItem, TabViewItem, nullptr);
|
||||
GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::Page, Content, nullptr);
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
// This is needed since Tab is going to be managing its own SwitchToTab command.
|
||||
OBSERVABLE_GETSET_PROPERTY(uint32_t, TabViewIndex, _PropertyChangedHandlers, 0);
|
||||
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
|
||||
OBSERVABLE_GETSET_PROPERTY(uint32_t, TabViewNumTabs, _PropertyChangedHandlers, 0);
|
||||
|
||||
private:
|
||||
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
|
||||
void _MakeTabViewItem();
|
||||
void _CreateContextMenu();
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _CreateCloseSubMenu();
|
||||
void _EnableCloseMenuItems();
|
||||
winrt::fire_and_forget _CreateIcon();
|
||||
void _CloseTabsAfter();
|
||||
void _CloseOtherTabs();
|
||||
};
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "ITab.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass SettingsTab : ITab
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ Abstract:
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model
|
||||
namespace winrt::TerminalApp
|
||||
{
|
||||
enum class ExpandCommandType : uint32_t
|
||||
{
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "ShortcutActionDispatch.g.cpp"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@@ -24,99 +23,99 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
const auto& action = actionAndArgs.Action();
|
||||
const auto& args = actionAndArgs.Args();
|
||||
auto eventArgs = args ? ActionEventArgs{ args } :
|
||||
ActionEventArgs{};
|
||||
auto eventArgs = args ? winrt::make_self<ActionEventArgs>(args) :
|
||||
winrt::make_self<ActionEventArgs>();
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ShortcutAction::CopyText:
|
||||
{
|
||||
_CopyTextHandlers(*this, eventArgs);
|
||||
_CopyTextHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::PasteText:
|
||||
{
|
||||
_PasteTextHandlers(*this, eventArgs);
|
||||
_PasteTextHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenNewTabDropdown:
|
||||
{
|
||||
_OpenNewTabDropdownHandlers(*this, eventArgs);
|
||||
_OpenNewTabDropdownHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::DuplicateTab:
|
||||
{
|
||||
_DuplicateTabHandlers(*this, eventArgs);
|
||||
_DuplicateTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenSettings:
|
||||
{
|
||||
_OpenSettingsHandlers(*this, eventArgs);
|
||||
_OpenSettingsHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::NewTab:
|
||||
{
|
||||
_NewTabHandlers(*this, eventArgs);
|
||||
_NewTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::NewWindow:
|
||||
{
|
||||
_NewWindowHandlers(*this, eventArgs);
|
||||
_NewWindowHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseWindow:
|
||||
{
|
||||
_CloseWindowHandlers(*this, eventArgs);
|
||||
_CloseWindowHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseTab:
|
||||
{
|
||||
_CloseTabHandlers(*this, eventArgs);
|
||||
_CloseTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ClosePane:
|
||||
{
|
||||
_ClosePaneHandlers(*this, eventArgs);
|
||||
_ClosePaneHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::ScrollUp:
|
||||
{
|
||||
_ScrollUpHandlers(*this, eventArgs);
|
||||
_ScrollUpHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollDown:
|
||||
{
|
||||
_ScrollDownHandlers(*this, eventArgs);
|
||||
_ScrollDownHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollUpPage:
|
||||
{
|
||||
_ScrollUpPageHandlers(*this, eventArgs);
|
||||
_ScrollUpPageHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollDownPage:
|
||||
{
|
||||
_ScrollDownPageHandlers(*this, eventArgs);
|
||||
_ScrollDownPageHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::NextTab:
|
||||
{
|
||||
_NextTabHandlers(*this, eventArgs);
|
||||
_NextTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::PrevTab:
|
||||
{
|
||||
_PrevTabHandlers(*this, eventArgs);
|
||||
_PrevTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::SendInput:
|
||||
{
|
||||
_SendInputHandlers(*this, eventArgs);
|
||||
_SendInputHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -124,118 +123,118 @@ namespace winrt::TerminalApp::implementation
|
||||
case ShortcutAction::SplitHorizontal:
|
||||
case ShortcutAction::SplitPane:
|
||||
{
|
||||
_SplitPaneHandlers(*this, eventArgs);
|
||||
_SplitPaneHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::TogglePaneZoom:
|
||||
{
|
||||
_TogglePaneZoomHandlers(*this, eventArgs);
|
||||
_TogglePaneZoomHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::SwitchToTab:
|
||||
{
|
||||
_SwitchToTabHandlers(*this, eventArgs);
|
||||
_SwitchToTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::ResizePane:
|
||||
{
|
||||
_ResizePaneHandlers(*this, eventArgs);
|
||||
_ResizePaneHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::MoveFocus:
|
||||
{
|
||||
_MoveFocusHandlers(*this, eventArgs);
|
||||
_MoveFocusHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::AdjustFontSize:
|
||||
{
|
||||
_AdjustFontSizeHandlers(*this, eventArgs);
|
||||
_AdjustFontSizeHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::Find:
|
||||
{
|
||||
_FindHandlers(*this, eventArgs);
|
||||
_FindHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ResetFontSize:
|
||||
{
|
||||
_ResetFontSizeHandlers(*this, eventArgs);
|
||||
_ResetFontSizeHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleRetroEffect:
|
||||
{
|
||||
_ToggleRetroEffectHandlers(*this, eventArgs);
|
||||
_ToggleRetroEffectHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleFocusMode:
|
||||
{
|
||||
_ToggleFocusModeHandlers(*this, eventArgs);
|
||||
_ToggleFocusModeHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleFullscreen:
|
||||
{
|
||||
_ToggleFullscreenHandlers(*this, eventArgs);
|
||||
_ToggleFullscreenHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleAlwaysOnTop:
|
||||
{
|
||||
_ToggleAlwaysOnTopHandlers(*this, eventArgs);
|
||||
_ToggleAlwaysOnTopHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleCommandPalette:
|
||||
{
|
||||
_ToggleCommandPaletteHandlers(*this, eventArgs);
|
||||
_ToggleCommandPaletteHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::SetColorScheme:
|
||||
{
|
||||
_SetColorSchemeHandlers(*this, eventArgs);
|
||||
_SetColorSchemeHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::SetTabColor:
|
||||
{
|
||||
_SetTabColorHandlers(*this, eventArgs);
|
||||
_SetTabColorHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenTabColorPicker:
|
||||
{
|
||||
_OpenTabColorPickerHandlers(*this, eventArgs);
|
||||
_OpenTabColorPickerHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::RenameTab:
|
||||
{
|
||||
_RenameTabHandlers(*this, eventArgs);
|
||||
_RenameTabHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ExecuteCommandline:
|
||||
{
|
||||
_ExecuteCommandlineHandlers(*this, eventArgs);
|
||||
_ExecuteCommandlineHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseOtherTabs:
|
||||
{
|
||||
_CloseOtherTabsHandlers(*this, eventArgs);
|
||||
_CloseOtherTabsHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseTabsAfter:
|
||||
{
|
||||
_CloseTabsAfterHandlers(*this, eventArgs);
|
||||
_CloseTabsAfterHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::TabSearch:
|
||||
{
|
||||
_TabSearchHandlers(*this, eventArgs);
|
||||
_TabSearchHandlers(*this, *eventArgs);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return eventArgs.Handled();
|
||||
return eventArgs->Handled();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user