mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-07 11:00:23 -04:00
Merge branch 'main' into dev/migrie/preview-setcolorscheme
This commit is contained in:
12
.config/dotnet-tools.json
Normal file
12
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"XamlStyler.Console": {
|
||||
"version": "3.2008.4",
|
||||
"commands": [
|
||||
"xstyler"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
17
.github/actions/spelling/dictionary/apis.txt
vendored
17
.github/actions/spelling/dictionary/apis.txt
vendored
@@ -6,14 +6,19 @@ bitfields
|
||||
CLASSNOTAVAILABLE
|
||||
cmdletbinding
|
||||
COLORPROPERTY
|
||||
COMDLG
|
||||
CXICON
|
||||
CYICON
|
||||
D2DERR_SHADER_COMPILE_FAILED
|
||||
dataobject
|
||||
DERR
|
||||
dlldata
|
||||
DONTADDTORECENT
|
||||
environstrings
|
||||
EXPCMDFLAGS
|
||||
EXPCMDSTATE
|
||||
FILTERSPEC
|
||||
FORCEFILESYSTEM
|
||||
FORCEMINIMIZE
|
||||
frac
|
||||
fullkbd
|
||||
@@ -31,12 +36,13 @@ IAsync
|
||||
IBind
|
||||
IBox
|
||||
IClass
|
||||
IConnection
|
||||
IComparable
|
||||
IConnection
|
||||
ICustom
|
||||
IDialog
|
||||
IDirect
|
||||
IExplorer
|
||||
IFile
|
||||
IInheritable
|
||||
IMap
|
||||
IObject
|
||||
@@ -62,6 +68,7 @@ NCLBUTTONDBLCLK
|
||||
NCRBUTTONDBLCLK
|
||||
NOAGGREGATION
|
||||
NOASYNC
|
||||
NOCHANGEDIR
|
||||
NOPROGRESS
|
||||
NOREDIRECTIONBITMAP
|
||||
ntprivapi
|
||||
@@ -71,10 +78,11 @@ otms
|
||||
OUTLINETEXTMETRICW
|
||||
overridable
|
||||
PAGESCROLL
|
||||
PICKFOLDERS
|
||||
pmr
|
||||
REGCLS
|
||||
RETURNCMD
|
||||
REGCLS
|
||||
RETURNCMD
|
||||
rfind
|
||||
roundf
|
||||
RSHIFT
|
||||
@@ -83,6 +91,7 @@ schandle
|
||||
semver
|
||||
serializer
|
||||
shobjidl
|
||||
SINGLEUSE
|
||||
SHOWMINIMIZED
|
||||
SIZENS
|
||||
smoothstep
|
||||
@@ -93,6 +102,8 @@ spsc
|
||||
sregex
|
||||
STDCPP
|
||||
strchr
|
||||
STDMETHOD
|
||||
Stubless
|
||||
Subheader
|
||||
Subpage
|
||||
UPDATEINIFILE
|
||||
@@ -108,8 +119,10 @@ UPDATEINIFILE
|
||||
userenv
|
||||
wcsstr
|
||||
wcstoui
|
||||
winmain
|
||||
wpc
|
||||
wsregex
|
||||
wwinmain
|
||||
XDocument
|
||||
XElement
|
||||
xlocmes
|
||||
|
||||
1
.github/actions/spelling/excludes.txt
vendored
1
.github/actions/spelling/excludes.txt
vendored
@@ -64,3 +64,4 @@ SUMS$
|
||||
^\.github/actions/spelling/
|
||||
^\.gitignore$
|
||||
^doc/reference/master-sequence-list.csv$
|
||||
^\XamlStyler.json$
|
||||
|
||||
1
.github/actions/spelling/expect/alphabet.txt
vendored
1
.github/actions/spelling/expect/alphabet.txt
vendored
@@ -1,3 +1,4 @@
|
||||
AAAa
|
||||
abcd
|
||||
abcde
|
||||
abcdef
|
||||
|
||||
10
.github/actions/spelling/expect/expect.txt
vendored
10
.github/actions/spelling/expect/expect.txt
vendored
@@ -88,6 +88,7 @@ args
|
||||
argv
|
||||
ARRAYSIZE
|
||||
ARROWKEYS
|
||||
asan
|
||||
ASBRST
|
||||
ASBSET
|
||||
ASDF
|
||||
@@ -433,6 +434,7 @@ cstring
|
||||
cstyle
|
||||
csv
|
||||
CSwitch
|
||||
CTerminal
|
||||
CText
|
||||
ctime
|
||||
ctl
|
||||
@@ -571,6 +573,7 @@ defaultsettings
|
||||
DEFAULTTONEAREST
|
||||
DEFAULTTONULL
|
||||
DEFAULTTOPRIMARY
|
||||
DEFCON
|
||||
defectdefs
|
||||
DEFERERASE
|
||||
deff
|
||||
@@ -830,6 +833,7 @@ FRAMECHANGED
|
||||
fre
|
||||
freopen
|
||||
frontend
|
||||
fsanitize
|
||||
Fscreen
|
||||
FSCTL
|
||||
FSINFOCLASS
|
||||
@@ -842,6 +846,7 @@ fullwidth
|
||||
func
|
||||
FUNCTIONCALL
|
||||
fuzzer
|
||||
fuzzmain
|
||||
fuzzmap
|
||||
fuzzwrapper
|
||||
fwdecl
|
||||
@@ -1254,6 +1259,7 @@ LEFTSHIFT
|
||||
len
|
||||
lhs
|
||||
libpopcnt
|
||||
libsancov
|
||||
libtickit
|
||||
LIMITTEXT
|
||||
LINEDOWN
|
||||
@@ -1464,6 +1470,7 @@ MSIL
|
||||
msix
|
||||
msrc
|
||||
msvcrt
|
||||
msvcrtd
|
||||
MSVS
|
||||
msys
|
||||
msysgit
|
||||
@@ -2055,6 +2062,7 @@ runtests
|
||||
runtimeclass
|
||||
runuia
|
||||
runut
|
||||
runxamlformat
|
||||
rvalue
|
||||
RVERTICAL
|
||||
rxvt
|
||||
@@ -2389,6 +2397,7 @@ titlebar
|
||||
TITLEISLINKNAME
|
||||
TJson
|
||||
tl
|
||||
TLambda
|
||||
TLEN
|
||||
Tlg
|
||||
Tlgdata
|
||||
@@ -2846,6 +2855,7 @@ XResource
|
||||
xsd
|
||||
xsi
|
||||
xsize
|
||||
xstyler
|
||||
XSubstantial
|
||||
xtended
|
||||
xterm
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="vswhere" version="2.6.7" />
|
||||
</packages>
|
||||
</packages>
|
||||
|
||||
17
.vscode/tasks.json
vendored
17
.vscode/tasks.json
vendored
@@ -16,7 +16,9 @@
|
||||
"${workspaceFolder}\\OpenConsole.sln",
|
||||
"/p:Configuration=${input:configChoice}",
|
||||
"/p:Platform=${input:platformChoice}",
|
||||
"/p:AppxSymbolPackageEnabled=false", // This takes a long time, so false if we don't really need it.
|
||||
"/t:$target",
|
||||
"/m", // Parallel builds
|
||||
"/verbosity:minimal"
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
@@ -46,8 +48,7 @@
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
"kind": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -57,6 +58,18 @@
|
||||
"args": [
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
},
|
||||
{
|
||||
"type": "process",
|
||||
"label": "Run Code Format",
|
||||
"command": "powershell.exe",
|
||||
"args": [
|
||||
"-Command",
|
||||
"Import-Module ${workspaceFolder}\\tools\\OpenConsole.psm1;",
|
||||
"Set-MsBuildDevEnvironment;",
|
||||
"Invoke-CodeFormat",
|
||||
],
|
||||
"problemMatcher": ["$msCompile"],
|
||||
}
|
||||
],
|
||||
"inputs":[
|
||||
|
||||
722
OpenConsole.sln
722
OpenConsole.sln
File diff suppressed because it is too large
Load Diff
41
XamlStyler.json
Normal file
41
XamlStyler.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"AttributesTolerance": 1,
|
||||
"KeepFirstAttributeOnSameLine": true,
|
||||
"MaxAttributeCharactersPerLine": 0,
|
||||
"MaxAttributesPerLine": 1,
|
||||
"NewlineExemptionElements": "RadialGradientBrush, GradientStop, LinearGradientBrush, ScaleTransform, SkewTransform, RotateTransform, TranslateTransform, Trigger, Condition, Setter",
|
||||
"SeparateByGroups": false,
|
||||
"AttributeIndentation": 0,
|
||||
"AttributeIndentationStyle": 1,
|
||||
"RemoveDesignTimeReferences": false,
|
||||
"EnableAttributeReordering": true,
|
||||
"AttributeOrderingRuleGroups": [
|
||||
"x:Class",
|
||||
"xmlns, xmlns:x",
|
||||
"xmlns:*",
|
||||
"x:Key, Key, x:Name, Name, x:Uid, Uid, Title",
|
||||
"Grid.Row, Grid.RowSpan, Grid.Column, Grid.ColumnSpan, Canvas.Left, Canvas.Top, Canvas.Right, Canvas.Bottom",
|
||||
"Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight",
|
||||
"Margin, Padding, HorizontalAlignment, VerticalAlignment, HorizontalContentAlignment, VerticalContentAlignment, Panel.ZIndex",
|
||||
"*:*, *",
|
||||
"PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint",
|
||||
"mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText",
|
||||
"Storyboard.*, From, To, Duration"
|
||||
],
|
||||
"FirstLineAttributes": "",
|
||||
"OrderAttributesByName": true,
|
||||
"PutEndingBracketOnNewLine": false,
|
||||
"RemoveEndingTagOfEmptyElement": true,
|
||||
"SpaceBeforeClosingSlash": true,
|
||||
"RootElementLineBreakRule": 0,
|
||||
"ReorderVSM": 2,
|
||||
"ReorderGridChildren": false,
|
||||
"ReorderCanvasChildren": false,
|
||||
"ReorderSetters": 0,
|
||||
"FormatMarkupExtension": true,
|
||||
"NoNewLineMarkupExtensions": "x:Bind, Binding",
|
||||
"ThicknessSeparator": 2,
|
||||
"ThicknessAttributes": "Margin, Padding, BorderThickness, ThumbnailClipMargin",
|
||||
"FormatOnSave": true,
|
||||
"CommentPadding": 2,
|
||||
}
|
||||
@@ -19,8 +19,8 @@ New-Item -ItemType Directory -Force -Path $payloadDir
|
||||
|
||||
# Copy files from nuget packages
|
||||
Copy-Item "$nugetPackagesDir\microsoft.windows.apps.test.1.0.181203002\lib\netcoreapp2.1\*.dll" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$Platform\CoreClr\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.58.210305002\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.58.210305002\build\Binaries\$Platform\CoreClr\*" $payloadDir
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\lib\netcoreapp2.1\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\native\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="TAEF.Redist.Wlk" version="10.57.200731005-develop" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.58.210305002" targetFramework="native" />
|
||||
<package id="microsoft.windows.apps.test" version="1.0.181203002" targetFramework="native" />
|
||||
<package id="runtime.win-x86.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
<package id="runtime.win-x64.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="TAEF.Redist.Wlk" version="10.57.200731005-develop" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.58.210305002" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -12,4 +12,4 @@ steps:
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\GenerateTestProjFile.ps1
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\taef.redist.wlk.10.57.200731005-develop\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.58.210305002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
matrix: ${{ parameters.matrix }}
|
||||
variables:
|
||||
artifactsDir: $(Build.SourcesDirectory)\Artifacts
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$(buildPlatform)
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.58.210305002\build\Binaries\$(buildPlatform)
|
||||
helixCommonArgs: '/binaryLogger:$(Build.SourcesDirectory)/${{parameters.name}}.$(buildPlatform).$(buildConfiguration).binlog /p:HelixBuild=$(Build.BuildId).$(buildPlatform).$(buildConfiguration) /p:Platform=$(buildPlatform) /p:Configuration=$(buildConfiguration) /p:HelixType=${{parameters.helixType}} /p:TestSuite=${{parameters.testSuite}} /p:ProjFilesPath=$(Build.ArtifactStagingDirectory) /p:rerunPassesRequiredToAvoidFailure=${{parameters.rerunPassesRequiredToAvoidFailure}}'
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,24 @@
|
||||
# Checks for code formatting errors. Will throw exception if any are found.
|
||||
function Invoke-CheckBadCodeFormatting() {
|
||||
Import-Module ./tools/OpenConsole.psm1
|
||||
Invoke-CodeFormat
|
||||
|
||||
# Don't run the XAML formatter in this step - even if it changes nothing,
|
||||
# it'll still touch all the .xaml files.
|
||||
Invoke-CodeFormat -IgnoreXaml
|
||||
|
||||
# returns a non-zero exit code if there are any diffs in the tracked files in the repo
|
||||
git diff-index --quiet HEAD --
|
||||
if ($lastExitCode -eq 1) {
|
||||
|
||||
# Write the list of files that need updating to the log
|
||||
git diff-index --name-only HEAD
|
||||
|
||||
throw "code formatting bad, run Invoke-CodeFormat on branch"
|
||||
}
|
||||
|
||||
# Manually check the formatting of our .xaml files, without touching them.
|
||||
Verify-XamlFormat
|
||||
|
||||
}
|
||||
|
||||
Invoke-CheckBadCodeFormatting
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
".wrn",
|
||||
".rec",
|
||||
".err",
|
||||
"XamlStyler.json",
|
||||
".xlsx"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ Use the [TAEF Verify Macros for C++](https://docs.microsoft.com/en-us/windows-ha
|
||||
|
||||
### 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.
|
||||
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 `Microsoft.Taef` 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.
|
||||
> Note that you cannot easily run TAEF tests directly through Visual Studio. The `Microsoft.Taef` 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:
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ should be working just the same as before.
|
||||
Now that you have a static library project, you can start building your unittest
|
||||
dll. Start by creating a new directory for your unittest code, and creating a
|
||||
`.vcxproj` for a TAEF unittest dll. For the Terminal solution, we use the TAEF
|
||||
nuget package `Taef.Redist.Wlk`.
|
||||
nuget package `Microsoft.Taef`.
|
||||
|
||||
### Referencing your C++/WinRT static lib
|
||||
|
||||
|
||||
@@ -52,6 +52,117 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"AppearanceConfig": {
|
||||
"properties": {
|
||||
"colorScheme": {
|
||||
"description": "The name of a color scheme to use when unfocused.",
|
||||
"type": "string"
|
||||
},
|
||||
"foreground": {
|
||||
"$ref": "#/definitions/Color",
|
||||
"default": "#cccccc",
|
||||
"description": "Sets the text color when unfocused. Overrides \"foreground\" from the color scheme. Uses hex color format: \"#rrggbb\".",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"background": {
|
||||
"$ref": "#/definitions/Color",
|
||||
"default": "#0c0c0c",
|
||||
"description": "Sets the background color of the text when unfocused. Overrides \"background\" from the color scheme. Uses hex color format: \"#rrggbb\".",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"selectionBackground": {
|
||||
"oneOf": [
|
||||
{"$ref": "#/definitions/Color"},
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Sets the background color of selected text when unfocused. Overrides selectionBackground set in the color scheme. Uses hex color format: \"#rrggbb\"."
|
||||
},
|
||||
"cursorColor": {
|
||||
"oneOf": [
|
||||
{ "$ref": "#/definitions/Color" },
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "Sets the color of the cursor when unfocused. Overrides the cursor color from the color scheme. Uses hex color format: \"#rrggbb\"."
|
||||
},
|
||||
"cursorShape": {
|
||||
"default": "bar",
|
||||
"description": "Sets the shape of the cursor when unfocused. Possible values:\n -\"bar\" ( ┃, default )\n -\"doubleUnderscore\" ( ‗ )\n -\"emptyBox\" ( ▯ )\n -\"filledBox\" ( █ )\n -\"underscore\" ( ▁ )\n -\"vintage\" ( ▃ )",
|
||||
"enum": [
|
||||
"bar",
|
||||
"doubleUnderscore",
|
||||
"emptyBox",
|
||||
"filledBox",
|
||||
"underscore",
|
||||
"vintage"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"cursorHeight": {
|
||||
"description": "Sets the percentage height of the cursor (when unfocused) starting from the bottom. Only works when cursorShape is set to \"vintage\". Accepts values from 1-100.",
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
"type": ["integer","null"],
|
||||
"default": 25
|
||||
},
|
||||
"backgroundImage": {
|
||||
"description": "Sets the file location of the image to draw over the window background when unfocused.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": ["string", null]
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"desktopWallpaper"
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": [ "string", "null" ]
|
||||
},
|
||||
"backgroundImageOpacity": {
|
||||
"default": 1.0,
|
||||
"description": "Sets the transparency of the background image when unfocused. Accepts floating point values from 0-1.",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"type": "number"
|
||||
},
|
||||
"backgroundImageStretchMode": {
|
||||
"default": "uniformToFill",
|
||||
"description": "Sets how the background image is resized to fill the window when unfocused.",
|
||||
"enum": [
|
||||
"fill",
|
||||
"none",
|
||||
"uniform",
|
||||
"uniformToFill"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"backgroundImageAlignment": {
|
||||
"default": "center",
|
||||
"enum": [
|
||||
"bottom",
|
||||
"bottomLeft",
|
||||
"bottomRight",
|
||||
"center",
|
||||
"left",
|
||||
"right",
|
||||
"top",
|
||||
"topLeft",
|
||||
"topRight"
|
||||
],
|
||||
"description": "Sets how the background image aligns to the boundaries of the window when unfocused. Possible values: \"center\", \"left\", \"top\", \"right\", \"bottom\", \"topLeft\", \"topRight\", \"bottomLeft\", \"bottomRight\"",
|
||||
"type": "string"
|
||||
},
|
||||
"experimental.retroTerminalEffect": {
|
||||
"description": "When set to true, enable retro terminal effects when unfocused. This is an experimental feature, and its continued existence is not guaranteed.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"experimental.pixelShaderPath": {
|
||||
"description": "Use to set a path to a pixel shader to use with the Terminal when unfocused. Overrides `experimental.retroTerminalEffect`. This is an experimental feature, and its continued existence is not guaranteed.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"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}\\}$",
|
||||
@@ -77,6 +188,8 @@
|
||||
"duplicateTab",
|
||||
"find",
|
||||
"findMatch",
|
||||
"identifyWindow",
|
||||
"identifyWindows",
|
||||
"moveFocus",
|
||||
"moveTab",
|
||||
"newTab",
|
||||
@@ -85,12 +198,14 @@
|
||||
"openNewTabDropdown",
|
||||
"openSettings",
|
||||
"openTabColorPicker",
|
||||
"openWindowRenamer",
|
||||
"paste",
|
||||
"prevTab",
|
||||
"renameTab",
|
||||
"openTabRenamer",
|
||||
"resetFontSize",
|
||||
"resizePane",
|
||||
"renameWindow",
|
||||
"scrollDown",
|
||||
"scrollDownPage",
|
||||
"scrollUp",
|
||||
@@ -227,6 +342,10 @@
|
||||
"type": "boolean",
|
||||
"default": "false",
|
||||
"description": "When set to true, tabTitle overrides the default title of the tab and any title change messages from the application will be suppressed. When set to false, tabTitle behaves as normal"
|
||||
},
|
||||
"colorScheme": {
|
||||
"description": "The name of a color scheme to use, instead of the one specified by the profile",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
@@ -647,6 +766,38 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"RenameTabAction": {
|
||||
"description": "Arguments corresponding to a renameTab Action",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/ShortcutAction" },
|
||||
{
|
||||
"properties": {
|
||||
"action": { "type": "string", "pattern": "renameTab" },
|
||||
"title": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "A title to assign to the tab. If omitted or null, this action will restore the tab's title to the original value."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"RenameWindowAction": {
|
||||
"description": "Arguments corresponding to a renameWindow Action",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/ShortcutAction" },
|
||||
{
|
||||
"properties": {
|
||||
"action": { "type": "string", "pattern": "renameWindow" },
|
||||
"name": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "A name to assign to the window."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Keybinding": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -675,6 +826,8 @@
|
||||
{ "$ref": "#/definitions/NewWindowAction" },
|
||||
{ "$ref": "#/definitions/NextTabAction" },
|
||||
{ "$ref": "#/definitions/PrevTabAction" },
|
||||
{ "$ref": "#/definitions/RenameTabAction" },
|
||||
{ "$ref": "#/definitions/RenameWindowAction" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
},
|
||||
@@ -958,6 +1111,11 @@
|
||||
"description": "Sets the background color of the text. Overrides \"background\" from the color scheme. Uses hex color format: \"#rrggbb\".",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"unfocusedAppearance": {
|
||||
"$ref": "#/definitions/AppearanceConfig",
|
||||
"description": "Sets the appearance of the terminal when it is unfocused.",
|
||||
"type": ["object", "null"]
|
||||
},
|
||||
"backgroundImage": {
|
||||
"description": "Sets the file location of the image to draw over the window background.",
|
||||
"oneOf": [
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<Application x:Class="GUIConsole.Wpf.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
<Application x:Class="GUIConsole.Wpf.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources />
|
||||
</Application>
|
||||
|
||||
@@ -1,84 +1,100 @@
|
||||
<Window x:Class="GUIConsole.Wpf.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="MainWindow" Height="450" Width="800"
|
||||
Background="#C7000000"
|
||||
AllowsTransparency="True"
|
||||
WindowStyle="None"
|
||||
MouseDown="Window_MouseDown"
|
||||
BorderThickness="1"
|
||||
BorderBrush="LightSlateGray"
|
||||
|
||||
KeyDown="Window_KeyDown"
|
||||
Loaded="Window_Loaded">
|
||||
<Window.Resources>
|
||||
<Style x:Key="TitleBarButtonStyle" TargetType="{x:Type Button}">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Width" Value="46"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource TitleBarButtonStyle}">
|
||||
<Setter Property="Content" Value=""/>
|
||||
<!--Remove the default Button template's Triggers, otherwise they'll override our trigger below.-->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border Background="{TemplateBinding Background}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Button.Background" Value="Red"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Name="TitleBarTitle" Grid.Column="0" VerticalAlignment="Center" Padding="10 0" Foreground="White">
|
||||
GUIConsole
|
||||
</TextBlock>
|
||||
<StackPanel x:Name="TitleBarButtons" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Top">
|
||||
<Button x:Name="MinimizeButton"
|
||||
Click="MinimizeButton_Click"
|
||||
Content=""
|
||||
Style="{StaticResource TitleBarButtonStyle}"/>
|
||||
<Button x:Name="MaximizeRestoreButton"
|
||||
Click="MaximizeRestoreButton_Click"
|
||||
Content=""
|
||||
FontSize="12"
|
||||
Style="{StaticResource TitleBarButtonStyle}"/>
|
||||
<Button x:Name="CloseButton"
|
||||
Click="CloseButton_Click"
|
||||
FontSize="12"
|
||||
Style="{StaticResource CloseButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<ScrollViewer x:Name="TerminalHistoryViewer" Grid.Row="1" ScrollChanged="ScrollViewer_ScrollChanged">
|
||||
<TextBlock x:Name="TerminalHistoryBlock" FontFamily="Consolas" TextWrapping="Wrap" Foreground="White"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Window>
|
||||
<Window x:Class="GUIConsole.Wpf.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Title="MainWindow"
|
||||
Width="800"
|
||||
Height="450"
|
||||
AllowsTransparency="True"
|
||||
Background="#C7000000"
|
||||
BorderBrush="LightSlateGray"
|
||||
BorderThickness="1"
|
||||
KeyDown="Window_KeyDown"
|
||||
Loaded="Window_Loaded"
|
||||
MouseDown="Window_MouseDown"
|
||||
WindowStyle="None"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
<Style x:Key="TitleBarButtonStyle"
|
||||
TargetType="{x:Type Button}">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Width" Value="46" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CloseButtonStyle"
|
||||
BasedOn="{StaticResource TitleBarButtonStyle}"
|
||||
TargetType="{x:Type Button}">
|
||||
<Setter Property="Content" Value="" />
|
||||
<!-- Remove the default Button template's Triggers, otherwise they'll override our trigger below. -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border Background="{TemplateBinding Background}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Button.Background" Value="Red" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Name="TitleBarTitle"
|
||||
Grid.Column="0"
|
||||
Padding="10,0"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="White">
|
||||
GUIConsole
|
||||
</TextBlock>
|
||||
<StackPanel x:Name="TitleBarButtons"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Horizontal">
|
||||
<Button x:Name="MinimizeButton"
|
||||
Click="MinimizeButton_Click"
|
||||
Content=""
|
||||
Style="{StaticResource TitleBarButtonStyle}" />
|
||||
<Button x:Name="MaximizeRestoreButton"
|
||||
Click="MaximizeRestoreButton_Click"
|
||||
Content=""
|
||||
FontSize="12"
|
||||
Style="{StaticResource TitleBarButtonStyle}" />
|
||||
<Button x:Name="CloseButton"
|
||||
Click="CloseButton_Click"
|
||||
FontSize="12"
|
||||
Style="{StaticResource CloseButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<ScrollViewer x:Name="TerminalHistoryViewer"
|
||||
Grid.Row="1"
|
||||
ScrollChanged="ScrollViewer_ScrollChanged">
|
||||
<TextBlock x:Name="TerminalHistoryBlock"
|
||||
FontFamily="Consolas"
|
||||
Foreground="White"
|
||||
TextWrapping="Wrap" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
66
samples/PixelShaders/Outlines.hlsl
Normal file
66
samples/PixelShaders/Outlines.hlsl
Normal file
@@ -0,0 +1,66 @@
|
||||
// A minimal pixel shader that outlines text
|
||||
|
||||
// The terminal graphics as a texture
|
||||
Texture2D shaderTexture;
|
||||
SamplerState samplerState;
|
||||
|
||||
// Terminal settings such as the resolution of the texture
|
||||
cbuffer PixelShaderSettings {
|
||||
// The number of seconds since the pixel shader was enabled
|
||||
float Time;
|
||||
// UI Scale
|
||||
float Scale;
|
||||
// Resolution of the shaderTexture
|
||||
float2 Resolution;
|
||||
// Background color as rgba
|
||||
float4 Background;
|
||||
};
|
||||
|
||||
// A pixel shader is a program that given a texture coordinate (tex) produces a color.
|
||||
// tex is an x,y tuple that ranges from 0,0 (top left) to 1,1 (bottom right).
|
||||
// Just ignore the pos parameter.
|
||||
float4 main(float4 pos : SV_POSITION, float2 tex : TEXCOORD) : SV_TARGET
|
||||
{
|
||||
// Read the color value at the current texture coordinate (tex)
|
||||
// float4 is tuple of 4 floats, rgba
|
||||
float4 color = shaderTexture.Sample(samplerState, tex);
|
||||
|
||||
// Read the color value at some offset, will be used as shadow. For the best
|
||||
// effect, read the colors offset on the left, right, top, bottom of this
|
||||
// fragment, as well as on the corners of this fragment.
|
||||
//
|
||||
// You could get away with fewer samples, but the resulting outlines will be
|
||||
// blurrier.
|
||||
|
||||
//left, right, top, bottom:
|
||||
float4 leftColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2( 1.0, 0.0)/Resolution.y);
|
||||
float4 rightColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2(-1.0, 0.0)/Resolution.y);
|
||||
float4 topColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2( 0.0, 1.0)/Resolution.y);
|
||||
float4 bottomColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2( 0.0, -1.0)/Resolution.y);
|
||||
|
||||
// Corners
|
||||
float4 topLeftColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2( 1.0, 1.0)/Resolution.y);
|
||||
float4 topRightColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2(-1.0, 1.0)/Resolution.y);
|
||||
float4 bottomLeftColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2( 1.0, -1.0)/Resolution.y);
|
||||
float4 bottomRightColor = shaderTexture.Sample(samplerState, tex+1.0*Scale*float2(-1.0, -1.0)/Resolution.y);
|
||||
|
||||
|
||||
// Now, if any of those adjacent cells has text in it, then the *color vec4
|
||||
// will have a non-zero .w (which is used for alpha). Use that alpha value
|
||||
// to add some black to the current fragment.
|
||||
//
|
||||
// This will result in only coloring fragments adjacent to text, but leaving
|
||||
// background images (for example) untouched.
|
||||
float3 outlineColor = float3(0, 0, 0);
|
||||
float4 result = color;
|
||||
result = result + float4(outlineColor, leftColor.w);
|
||||
result = result + float4(outlineColor, rightColor.w);
|
||||
result = result + float4(outlineColor, topColor.w);
|
||||
result = result + float4(outlineColor, bottomColor.w);
|
||||
|
||||
result = result + float4(outlineColor, topLeftColor.w);
|
||||
result = result + float4(outlineColor, topRightColor.w);
|
||||
result = result + float4(outlineColor, bottomLeftColor.w);
|
||||
result = result + float4(outlineColor, bottomRightColor.w);
|
||||
return result;
|
||||
}
|
||||
32
src/Terminal.wprp
Normal file
32
src/Terminal.wprp
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<WindowsPerformanceRecorder Version="1.0" Author="Microsoft Corporation" Copyright="Microsoft Corporation" Company="Microsoft Corporation">
|
||||
<Profiles>
|
||||
<EventCollector Id="EventCollector_Terminal" Name="Terminal">
|
||||
<BufferSize Value="64" />
|
||||
<Buffers Value="4" />
|
||||
</EventCollector>
|
||||
<EventProvider Id="EventProvider_TerminalControl" Name="28c82e50-57af-5a86-c25b-e39cd990032b" />
|
||||
<EventProvider Id="EventProvider_TerminalConnection" Name="e912fe7b-eeb6-52a5-c628-abe388e5f792" />
|
||||
<EventProvider Id="EventProvider_TerminalSettingsModel" Name="be579944-4d33-5202-e5d6-a7a57f1935cb" />
|
||||
<EventProvider Id="EventProvider_TerminalApp" Name="24a1622f-7da7-5c77-3303-d850bd1ab2ed" />
|
||||
<EventProvider Id="EventProvider_TerminalWin32Host" Name="56c06166-2e2e-5f4d-7ff3-74f4b78c87d6" />
|
||||
<EventProvider Id="EventProvider_TerminalRemoting" Name="d6f04aad-629f-539a-77c1-73f5c3e4aa7b" />
|
||||
<Profile Id="Terminal.Verbose.File" Name="Terminal" Description="Terminal" LoggingMode="File" DetailLevel="Verbose">
|
||||
<Collectors>
|
||||
<EventCollectorId Value="EventCollector_Terminal">
|
||||
<EventProviders>
|
||||
<EventProviderId Value="EventProvider_TerminalControl" />
|
||||
<EventProviderId Value="EventProvider_TerminalConnection" />
|
||||
<EventProviderId Value="EventProvider_TerminalSettingsModel" />
|
||||
<EventProviderId Value="EventProvider_TerminalApp" />
|
||||
<EventProviderId Value="EventProvider_TerminalWin32Host" />
|
||||
<EventProviderId Value="EventProvider_TerminalRemoting" />
|
||||
</EventProviders>
|
||||
</EventCollectorId>
|
||||
</Collectors>
|
||||
</Profile>
|
||||
<Profile Id="Terminal.Light.File" Name="Terminal" Description="Terminal" Base="Terminal.Verbose.File" LoggingMode="File" DetailLevel="Light" />
|
||||
<Profile Id="Terminal.Verbose.Memory" Name="Terminal" Description="Terminal" Base="Terminal.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose" />
|
||||
<Profile Id="Terminal.Light.Memory" Name="Terminal" Description="Terminal" Base="Terminal.Verbose.File" LoggingMode="Memory" DetailLevel="Light" />
|
||||
</Profiles>
|
||||
</WindowsPerformanceRecorder>
|
||||
@@ -70,6 +70,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
|
||||
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
|
||||
<ProjectReference Include="..\..\host\proxy\Host.Proxy.vcxproj" />
|
||||
<ProjectReference Include="..\TerminalAzBridge\TerminalAzBridge.vcxproj" />
|
||||
<ProjectReference Include="..\ShellExtension\WindowsTerminalShellExt.vcxproj" />
|
||||
<ProjectReference Include="..\wt\wt.vcxproj" />
|
||||
|
||||
@@ -74,9 +74,43 @@
|
||||
<uap3:Name>com.microsoft.windows.terminal.settings</uap3:Name>
|
||||
</uap3:AppExtensionHost>
|
||||
</uap3:Extension>
|
||||
|
||||
<uap3:Extension Category="windows.appExtension">
|
||||
<uap3:AppExtension Name="com.microsoft.windows.console.host"
|
||||
Id="OpenConsole-Dev"
|
||||
DisplayName="OpenConsole Dev"
|
||||
Description="Console host built from microsoft/terminal open source repository"
|
||||
PublicFolder="Public">
|
||||
<uap3:Properties>
|
||||
<Clsid>{1F9F2BF5-5BC3-4F17-B0E6-912413F1F451}</Clsid>
|
||||
</uap3:Properties>
|
||||
</uap3:AppExtension>
|
||||
</uap3:Extension>
|
||||
<uap3:Extension Category="windows.appExtension">
|
||||
<uap3:AppExtension Name="com.microsoft.windows.terminal.host"
|
||||
Id="Terminal-Dev"
|
||||
DisplayName="Windows Terminal Dev"
|
||||
Description="Terminal host built from microsoft/terminal open source repository"
|
||||
PublicFolder="Public">
|
||||
<uap3:Properties>
|
||||
<Clsid>{051F34EE-C1FD-4B19-AF75-9BA54648434C}</Clsid>
|
||||
</uap3:Properties>
|
||||
</uap3:AppExtension>
|
||||
</uap3:Extension>
|
||||
<com:Extension Category="windows.comInterface">
|
||||
<com:ComInterface>
|
||||
<com:ProxyStub Id="DEC4804D-56D1-4F73-9FBE-6828E7C85C56" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="2B607BC1-43EB-40C3-95AE-2856ADDB7F23" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
<com:Interface Id="FA1E3AB4-9AEC-4A3C-96CA-E6078C30BD74" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:ExeServer DisplayName="OpenConsole" Executable="OpenConsole.exe">
|
||||
<com:Class Id="1F9F2BF5-5BC3-4F17-B0E6-912413F1F451"/>
|
||||
</com:ExeServer>
|
||||
<com:ExeServer DisplayName="WindowsTerminal" Executable="WindowsTerminal.exe">
|
||||
<com:Class Id="051F34EE-C1FD-4B19-AF75-9BA54648434C"/>
|
||||
</com:ExeServer>
|
||||
<com:SurrogateServer DisplayName="WindowsTerminalShellExt">
|
||||
<com:Class Id="52065414-e077-47ec-a3ac-1cc5455e1b54" Path="WindowsTerminalShellExt.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
|
||||
@@ -75,8 +75,43 @@
|
||||
Enabled="false"
|
||||
DisplayName="ms-resource:AppNamePre" />
|
||||
</uap5:Extension>
|
||||
<uap3:Extension Category="windows.appExtension">
|
||||
<uap3:AppExtension Name="com.microsoft.windows.console.host"
|
||||
Id="OpenConsole-Pre"
|
||||
DisplayName="OpenConsole Preview"
|
||||
Description="Console host built from microsoft/terminal open source repository"
|
||||
PublicFolder="Public">
|
||||
<uap3:Properties>
|
||||
<Clsid>{06EC847C-C0A5-46B8-92CB-7C92F6E35CD5}</Clsid>
|
||||
</uap3:Properties>
|
||||
</uap3:AppExtension>
|
||||
</uap3:Extension>
|
||||
<uap3:Extension Category="windows.appExtension">
|
||||
<uap3:AppExtension Name="com.microsoft.windows.terminal.host"
|
||||
Id="Terminal-Pre"
|
||||
DisplayName="Windows Terminal Preview"
|
||||
Description="Terminal host built from microsoft/terminal open source repository"
|
||||
PublicFolder="Public">
|
||||
<uap3:Properties>
|
||||
<Clsid>{86633F1F-6454-40EC-89CE-DA4EBA977EE2}</Clsid>
|
||||
</uap3:Properties>
|
||||
</uap3:AppExtension>
|
||||
</uap3:Extension>
|
||||
<com:Extension Category="windows.comInterface">
|
||||
<com:ComInterface>
|
||||
<com:ProxyStub Id="1833E661-CC81-4DD0-87C6-C2F74BD39EFA" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="2B607BC1-43EB-40C3-95AE-2856ADDB7F23" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
<com:Interface Id="FA1E3AB4-9AEC-4A3C-96CA-E6078C30BD74" ProxyStubClsid="1833E661-CC81-4DD0-87C6-C2F74BD39EFA"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:ExeServer DisplayName="OpenConsole" Executable="OpenConsole.exe">
|
||||
<com:Class Id="06EC847C-C0A5-46B8-92CB-7C92F6E35CD5"/>
|
||||
</com:ExeServer>
|
||||
<com:ExeServer DisplayName="WindowsTerminal" Executable="WindowsTerminal.exe">
|
||||
<com:Class Id="86633F1F-6454-40EC-89CE-DA4EBA977EE2"/>
|
||||
</com:ExeServer>
|
||||
<com:SurrogateServer DisplayName="WindowsTerminalShellExt">
|
||||
<com:Class Id="02db545a-3e20-46de-83a5-1329b1e88b6b" Path="WindowsTerminalShellExt.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
|
||||
@@ -75,9 +75,43 @@
|
||||
Enabled="false"
|
||||
DisplayName="ms-resource:AppName" />
|
||||
</uap5:Extension>
|
||||
|
||||
<!-- <uap3:Extension Category="windows.appExtension">
|
||||
<uap3:AppExtension Name="com.microsoft.windows.console.host"
|
||||
Id="OpenConsole"
|
||||
DisplayName="OpenConsole"
|
||||
Description="Console host built from microsoft/terminal open source repository"
|
||||
PublicFolder="Public">
|
||||
<uap3:Properties>
|
||||
<Clsid>{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}</Clsid>
|
||||
</uap3:Properties>
|
||||
</uap3:AppExtension>
|
||||
</uap3:Extension>
|
||||
<uap3:Extension Category="windows.appExtension">
|
||||
<uap3:AppExtension Name="com.microsoft.windows.terminal.host"
|
||||
Id="Terminal"
|
||||
DisplayName="Windows Terminal"
|
||||
Description="Terminal host built from microsoft/terminal open source repository"
|
||||
PublicFolder="Public">
|
||||
<uap3:Properties>
|
||||
<Clsid>{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}</Clsid>
|
||||
</uap3:Properties>
|
||||
</uap3:AppExtension>
|
||||
</uap3:Extension>
|
||||
<com:Extension Category="windows.comInterface">
|
||||
<com:ComInterface>
|
||||
<com:ProxyStub Id="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
|
||||
<com:Interface Id="2B607BC1-43EB-40C3-95AE-2856ADDB7F23" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
<com:Interface Id="FA1E3AB4-9AEC-4A3C-96CA-E6078C30BD74" ProxyStubClsid="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F"/>
|
||||
</com:ComInterface>
|
||||
</com:Extension> -->
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<!-- <com:ExeServer DisplayName="OpenConsole" Executable="OpenConsole.exe">
|
||||
<com:Class Id="2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69"/>
|
||||
</com:ExeServer>
|
||||
<com:ExeServer DisplayName="WindowsTerminal" Executable="WindowsTerminal.exe">
|
||||
<com:Class Id="E12CFF52-A866-4C77-9A90-F570A7AA2C6B"/>
|
||||
</com:ExeServer> -->
|
||||
<com:SurrogateServer DisplayName="WindowsTerminalShellExt">
|
||||
<com:Class Id="9f156763-7844-4dc4-b2b1-901f640f5155" Path="WindowsTerminalShellExt.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
|
||||
@@ -56,6 +56,8 @@ Author(s):
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
|
||||
#include <winrt/Microsoft.Terminal.Core.h>
|
||||
|
||||
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
||||
#include "til.h"
|
||||
|
||||
|
||||
@@ -458,6 +458,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().TabColor());
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -479,6 +480,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"cmd", myArgs.TerminalArgs().Profile());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -500,6 +502,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"c:\\Foo", myArgs.TerminalArgs().StartingDirectory());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -521,6 +524,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"powershell.exe", myArgs.TerminalArgs().Commandline());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -543,6 +547,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
auto myCommand = myArgs.TerminalArgs().Commandline();
|
||||
VERIFY_ARE_EQUAL(L"powershell.exe \"This is an arg with spaces\"", myCommand);
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -565,6 +570,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
auto myCommand = myArgs.TerminalArgs().Commandline();
|
||||
VERIFY_ARE_EQUAL(L"powershell.exe \"This is an arg with spaces\" another-arg \"more spaces in this one\"", myCommand);
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -586,6 +592,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"Windows PowerShell", myArgs.TerminalArgs().Profile());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -606,6 +613,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -628,6 +636,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline());
|
||||
VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -651,6 +660,31 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(til::color(myArgs.TerminalArgs().TabColor().Value()), expectedColor);
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", subcommand, L"--colorScheme", L"Vintage" };
|
||||
const winrt::hstring expectedScheme{ L"Vintage" };
|
||||
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, appArgs._startupActions.size());
|
||||
|
||||
auto actionAndArgs = appArgs._startupActions.at(0);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
|
||||
VERIFY_IS_NOT_NULL(actionAndArgs.Args());
|
||||
auto myArgs = actionAndArgs.Args().try_as<NewTabArgs>();
|
||||
VERIFY_IS_NOT_NULL(myArgs);
|
||||
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Commandline().empty());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().StartingDirectory().empty());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().TabTitle().empty());
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().TabColor());
|
||||
VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
VERIFY_ARE_EQUAL(expectedScheme, myArgs.TerminalArgs().ColorScheme());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,6 +714,7 @@ namespace TerminalAppLocalTests
|
||||
auto myArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(myArgs);
|
||||
VERIFY_ARE_EQUAL(SplitState::Automatic, myArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(SplitType::Manual, myArgs.SplitMode());
|
||||
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
|
||||
}
|
||||
{
|
||||
@@ -699,6 +734,7 @@ namespace TerminalAppLocalTests
|
||||
auto myArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(myArgs);
|
||||
VERIFY_ARE_EQUAL(SplitState::Horizontal, myArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(SplitType::Manual, myArgs.SplitMode());
|
||||
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
|
||||
}
|
||||
{
|
||||
@@ -720,6 +756,28 @@ namespace TerminalAppLocalTests
|
||||
auto myArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(myArgs);
|
||||
VERIFY_ARE_EQUAL(SplitState::Vertical, myArgs.SplitStyle());
|
||||
VERIFY_ARE_EQUAL(SplitType::Manual, myArgs.SplitMode());
|
||||
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
std::vector<const wchar_t*> rawCommands{ L"wt.exe", subcommand, L"-D" };
|
||||
auto commandlines = AppCommandlineArgs::BuildCommands(rawCommands);
|
||||
VERIFY_ARE_EQUAL(1u, commandlines.size());
|
||||
_buildCommandlinesHelper(appArgs, 1u, rawCommands);
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, appArgs._startupActions.size());
|
||||
|
||||
// The first action is going to always be a new-tab action
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::NewTab, appArgs._startupActions.at(0).Action());
|
||||
|
||||
// The one we actually want to test here is the SplitPane action we created
|
||||
auto actionAndArgs = appArgs._startupActions.at(1);
|
||||
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
|
||||
VERIFY_IS_NOT_NULL(actionAndArgs.Args());
|
||||
auto myArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
|
||||
VERIFY_IS_NOT_NULL(myArgs);
|
||||
VERIFY_ARE_EQUAL(SplitType::Duplicate, myArgs.SplitMode());
|
||||
VERIFY_IS_NOT_NULL(myArgs.TerminalArgs());
|
||||
}
|
||||
{
|
||||
@@ -749,6 +807,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline());
|
||||
VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -777,6 +836,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline());
|
||||
VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
{
|
||||
AppCommandlineArgs appArgs{};
|
||||
@@ -805,6 +865,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"wsl -d Alpine -H", myArgs.TerminalArgs().Commandline());
|
||||
VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile());
|
||||
VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@ namespace TerminalAppLocalTests
|
||||
TEST_METHOD(NextMRUTab);
|
||||
TEST_METHOD(VerifyCommandPaletteTabSwitcherOrder);
|
||||
|
||||
TEST_METHOD(TestWindowRenameSuccessful);
|
||||
TEST_METHOD(TestWindowRenameFailure);
|
||||
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
return true;
|
||||
@@ -260,6 +263,15 @@ namespace TerminalAppLocalTests
|
||||
page->Create();
|
||||
Log::Comment(L"Create()'d the page successfully");
|
||||
|
||||
// Build a NewTab action, to make sure we start with one. The real
|
||||
// Terminal will always get one from AppCommandlineArgs.
|
||||
NewTerminalArgs newTerminalArgs{};
|
||||
NewTabArgs args{ newTerminalArgs };
|
||||
ActionAndArgs newTabAction{ ShortcutAction::NewTab, args };
|
||||
// push the arg onto the front
|
||||
page->_startupActions.Append(newTabAction);
|
||||
Log::Comment(L"Added a single newTab action");
|
||||
|
||||
auto app = ::winrt::Windows::UI::Xaml::Application::Current();
|
||||
|
||||
winrt::TerminalApp::TerminalPage pp = *page;
|
||||
@@ -276,8 +288,9 @@ 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->_tabs.GetAt(0);
|
||||
auto tabImpl = page->_GetTerminalTabImpl(tab);
|
||||
page->_tabView.SelectedItem(tabImpl->TabViewItem());
|
||||
page->_UpdatedSelectedTab(0);
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -601,7 +614,6 @@ namespace TerminalAppLocalTests
|
||||
auto result = RunOnUIThread([&page]() {
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
// eventArgs.Args(args);
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
@@ -939,4 +951,57 @@ namespace TerminalAppLocalTests
|
||||
// will also dismiss itself immediately when that's called. So we can't
|
||||
// really inspect the contents of the list in this test, unfortunately.
|
||||
}
|
||||
|
||||
void TabTests::TestWindowRenameSuccessful()
|
||||
{
|
||||
auto page = _commonSetup();
|
||||
page->RenameWindowRequested([&page](auto&&, const winrt::TerminalApp::RenameWindowRequestedArgs args) {
|
||||
// In the real terminal, this would bounce up to the monarch and
|
||||
// come back down. Instead, immediately call back and set the name.
|
||||
page->WindowName(args.ProposedName());
|
||||
});
|
||||
|
||||
bool windowNameChanged = false;
|
||||
page->PropertyChanged([&page, &windowNameChanged](auto&&, const winrt::WUX::Data::PropertyChangedEventArgs& args) mutable {
|
||||
if (args.PropertyName() == L"WindowNameForDisplay")
|
||||
{
|
||||
windowNameChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
page->_RequestWindowRename(winrt::hstring{ L"Foo" });
|
||||
});
|
||||
TestOnUIThread([&]() {
|
||||
VERIFY_ARE_EQUAL(L"Foo", page->_WindowName);
|
||||
VERIFY_IS_TRUE(windowNameChanged,
|
||||
L"The window name should have changed, and we should have raised a notification that WindowNameForDisplay changed");
|
||||
});
|
||||
}
|
||||
void TabTests::TestWindowRenameFailure()
|
||||
{
|
||||
auto page = _commonSetup();
|
||||
page->RenameWindowRequested([&page](auto&&, auto&&) {
|
||||
// In the real terminal, this would bounce up to the monarch and
|
||||
// come back down. Instead, immediately call back to tell the terminal it failed.
|
||||
page->RenameFailed();
|
||||
});
|
||||
|
||||
bool windowNameChanged = false;
|
||||
|
||||
page->PropertyChanged([&page, &windowNameChanged](auto&&, const winrt::WUX::Data::PropertyChangedEventArgs& args) mutable {
|
||||
if (args.PropertyName() == L"WindowNameForDisplay")
|
||||
{
|
||||
windowNameChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
page->_RequestWindowRename(winrt::hstring{ L"Foo" });
|
||||
});
|
||||
TestOnUIThread([&]() {
|
||||
VERIFY_IS_FALSE(windowNameChanged,
|
||||
L"The window name should not have changed, we should have rejected the change.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestExecutor.WinRTCore">
|
||||
<HintPath>$(OpenConsoleDir)\packages\Taef.Redist.Wlk.10.57.200731005-develop\lib\Microsoft.VisualStudio.TestPlatform.TestExecutor.WinRTCore.winmd</HintPath>
|
||||
<HintPath>$(OpenConsoleDir)\packages\Microsoft.Taef.10.58.210305002\lib\Microsoft.VisualStudio.TestPlatform.TestExecutor.WinRTCore.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
|
||||
<!-- This path is _relative to the .winmd_ -->
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<Application
|
||||
x:Class="TestHostApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TestHostApp"
|
||||
RequestedTheme="Dark">
|
||||
|
||||
</Application>
|
||||
<Application x:Class="TestHostApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TestHostApp"
|
||||
RequestedTheme="Dark" />
|
||||
|
||||
@@ -45,6 +45,7 @@ Author(s):
|
||||
#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.Data.h>
|
||||
#include <winrt/Windows.ui.xaml.media.h>
|
||||
#include <winrt/Windows.ui.xaml.input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
<ClInclude Include="ProposeCommandlineResult.h">
|
||||
<DependentUpon>Monarch.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RenameRequestArgs.h">
|
||||
<DependentUpon>Peasant.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WindowActivatedArgs.h">
|
||||
<DependentUpon>Peasant.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -51,6 +54,9 @@
|
||||
<ClCompile Include="ProposeCommandlineResult.cpp">
|
||||
<DependentUpon>Monarch.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RenameRequestArgs.cpp">
|
||||
<DependentUpon>Peasant.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WindowActivatedArgs.cpp">
|
||||
<DependentUpon>Peasant.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
|
||||
@@ -75,6 +75,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
auto newPeasantsId = peasant.GetID();
|
||||
// Add an event listener to the peasant's WindowActivated event.
|
||||
peasant.WindowActivated({ this, &Monarch::_peasantWindowActivated });
|
||||
peasant.IdentifyWindowsRequested({ this, &Monarch::_identifyWindows });
|
||||
peasant.RenameRequested({ this, &Monarch::_renameRequested });
|
||||
|
||||
_peasants[newPeasantsId] = peasant;
|
||||
|
||||
@@ -571,4 +573,111 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
result->WindowName(targetWindowName);
|
||||
return *result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper for doing something on each and every peasant, with no regard
|
||||
// for if the peasant is living or dead.
|
||||
// - We'll try calling callback on every peasant.
|
||||
// - If any single peasant is dead, then we'll call errorCallback, and move on.
|
||||
// - We're taking an errorCallback here, because the thing we usually want
|
||||
// to do is TraceLog a message, but TraceLoggingWrite is actually a macro
|
||||
// that _requires_ the second arg to be a string literal. It can't just be
|
||||
// a variable.
|
||||
// Arguments:
|
||||
// - callback: The function to call on each peasant
|
||||
// - errorCallback: The function to call if a peasant is dead.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Monarch::_forAllPeasantsIgnoringTheDead(std::function<void(const Remoting::IPeasant&, const uint64_t)> callback,
|
||||
std::function<void(const uint64_t)> errorCallback)
|
||||
{
|
||||
for (const auto& [id, p] : _peasants)
|
||||
{
|
||||
try
|
||||
{
|
||||
callback(p, id);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
// If this fails, we don't _really_ care. Just move on to the
|
||||
// next one. Someone else will clean up the dead peasant.
|
||||
errorCallback(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This is an event handler for the IdentifyWindowsRequested event. A
|
||||
// Peasant may raise that event if they want _all_ windows to identify
|
||||
// themselves.
|
||||
// - This will tell each and every peasant to identify themselves. This will
|
||||
// eventually propagate down to TerminalPage::IdentifyWindow.
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Monarch::_identifyWindows(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||
{
|
||||
// Notify all the peasants to display their ID.
|
||||
auto callback = [](auto&& p, auto&& /*id*/) {
|
||||
p.DisplayWindowId();
|
||||
};
|
||||
auto onError = [](auto&& id) {
|
||||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Monarch_identifyWindows_Failed",
|
||||
TraceLoggingInt64(id, "peasantID", "The ID of the peasant which we could not identify"),
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||
};
|
||||
_forAllPeasantsIgnoringTheDead(callback, onError);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This is an event handler for the RenameRequested event. A
|
||||
// Peasant may raise that event when they want to be renamed to something else.
|
||||
// - We will check if there are any other windows with this name. If there
|
||||
// are, then we'll reject the rename by setting args.Succeeded=false.
|
||||
// - If there aren't any other windows with this name, then we'll set
|
||||
// args.Succeeded=true, allowing the window to keep this name.
|
||||
// Arguments:
|
||||
// - args: Contains the requested window name and a boolean (Succeeded)
|
||||
// indicating if the request was successful.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Monarch::_renameRequested(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args)
|
||||
{
|
||||
bool successfullyRenamed = false;
|
||||
|
||||
try
|
||||
{
|
||||
args.Succeeded(false);
|
||||
const auto name{ args.NewName() };
|
||||
// Try to find a peasant that currently has this name
|
||||
const auto id = _lookupPeasantIdForName(name);
|
||||
if (_getPeasant(id) == nullptr)
|
||||
{
|
||||
// If there is one, then oh no! The requestor is not allowed to
|
||||
// be renamed.
|
||||
args.Succeeded(true);
|
||||
successfullyRenamed = true;
|
||||
}
|
||||
|
||||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Monarch_renameRequested",
|
||||
TraceLoggingWideString(name.c_str(), "name", "The newly proposed name"),
|
||||
TraceLoggingInt64(successfullyRenamed, "successfullyRenamed", "true if the peasant is allowed to rename themselves to that name."),
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
// If this fails, we don't _really_ care. The peasant died, but
|
||||
// they're the only one who cares about the result.
|
||||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Monarch_renameRequested_Failed",
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,15 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
void _doHandleActivatePeasant(const winrt::com_ptr<winrt::Microsoft::Terminal::Remoting::implementation::WindowActivatedArgs>& args);
|
||||
void _clearOldMruEntries(const uint64_t peasantID);
|
||||
|
||||
void _forAllPeasantsIgnoringTheDead(std::function<void(const winrt::Microsoft::Terminal::Remoting::IPeasant&, const uint64_t)> callback,
|
||||
std::function<void(const uint64_t)> errorCallback);
|
||||
|
||||
void _identifyWindows(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
void _renameRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
|
||||
|
||||
friend class RemotingUnitTests::RemotingTests;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -117,4 +117,81 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
return _lastActivatedArgs;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell this window to display it's window ID. We'll raise a
|
||||
// DisplayWindowIdRequested event, which will get handled in the AppHost,
|
||||
// and used to tell the app to display the ID toast.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Peasant::DisplayWindowId()
|
||||
{
|
||||
// Not worried about try/catching this. The handler is in AppHost, which
|
||||
// is in-proc for us.
|
||||
_DisplayWindowIdRequestedHandlers(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Raises an event to ask that all windows be identified. This will come
|
||||
// back to us when the Monarch handles the event and calls our
|
||||
// DisplayWindowId method.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Peasant::RequestIdentifyWindows()
|
||||
{
|
||||
bool successfullyNotified = false;
|
||||
|
||||
try
|
||||
{
|
||||
// Try/catch this, because the other side of this event is handled
|
||||
// by the monarch. The monarch might have died. If they have, this
|
||||
// will throw an exception. Just eat it, the election thread will
|
||||
// handle hooking up the new one.
|
||||
_IdentifyWindowsRequestedHandlers(*this, nullptr);
|
||||
successfullyNotified = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Peasant_RequestIdentifyWindows",
|
||||
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
||||
TraceLoggingBoolean(successfullyNotified, "successfullyNotified", "true if we successfully notified the monarch"),
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||
}
|
||||
|
||||
void Peasant::RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args)
|
||||
{
|
||||
bool successfullyNotified = false;
|
||||
const auto oldName{ _WindowName };
|
||||
try
|
||||
{
|
||||
// Try/catch this, because the other side of this event is handled
|
||||
// by the monarch. The monarch might have died. If they have, this
|
||||
// will throw an exception. Just eat it, the election thread will
|
||||
// handle hooking up the new one.
|
||||
_RenameRequestedHandlers(*this, args);
|
||||
if (args.Succeeded())
|
||||
{
|
||||
_WindowName = args.NewName();
|
||||
}
|
||||
successfullyNotified = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
TraceLoggingWrite(g_hRemotingProvider,
|
||||
"Peasant_RequestRename",
|
||||
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
||||
TraceLoggingWideString(oldName.c_str(), "oldName", "Our old name"),
|
||||
TraceLoggingWideString(args.NewName().c_str(), "newName", "The proposed name"),
|
||||
TraceLoggingBoolean(args.Succeeded(), "succeeded", "true if the monarch ok'd this new name for us."),
|
||||
TraceLoggingBoolean(successfullyNotified, "successfullyNotified", "true if we successfully notified the monarch"),
|
||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "Peasant.g.h"
|
||||
#include "../cascadia/inc/cppwinrt_utils.h"
|
||||
#include "RenameRequestArgs.h"
|
||||
|
||||
namespace RemotingUnitTests
|
||||
{
|
||||
@@ -22,6 +23,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
|
||||
bool ExecuteCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args);
|
||||
void ActivateWindow(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args);
|
||||
void RequestIdentifyWindows();
|
||||
void DisplayWindowId();
|
||||
void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
|
||||
|
||||
winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs GetLastActivatedArgs();
|
||||
|
||||
@@ -30,6 +34,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
|
||||
TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs);
|
||||
TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::CommandlineArgs);
|
||||
TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||
TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||
TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs);
|
||||
|
||||
private:
|
||||
Peasant(const uint64_t testPID);
|
||||
|
||||
@@ -13,6 +13,13 @@ namespace Microsoft.Terminal.Remoting
|
||||
String CurrentDirectory();
|
||||
};
|
||||
|
||||
runtimeclass RenameRequestArgs
|
||||
{
|
||||
RenameRequestArgs(String newName);
|
||||
String NewName { get; };
|
||||
Boolean Succeeded;
|
||||
};
|
||||
|
||||
runtimeclass WindowActivatedArgs
|
||||
{
|
||||
WindowActivatedArgs(UInt64 peasantID, Guid desktopID, Windows.Foundation.DateTime activatedTime);
|
||||
@@ -34,9 +41,16 @@ namespace Microsoft.Terminal.Remoting
|
||||
void ActivateWindow(WindowActivatedArgs args);
|
||||
WindowActivatedArgs GetLastActivatedArgs();
|
||||
String WindowName { get; };
|
||||
void RequestIdentifyWindows(); // Tells us to raise a IdentifyWindowsRequested
|
||||
void DisplayWindowId(); // Tells us to display its own ID (which causes a DisplayWindowIdRequested to be raised)
|
||||
|
||||
void RequestRename(RenameRequestArgs args); // Tells us to raise a RenameRequested
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowActivatedArgs> WindowActivated;
|
||||
event Windows.Foundation.TypedEventHandler<Object, CommandlineArgs> ExecuteCommandlineRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> DisplayWindowIdRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameRequestArgs> RenameRequested;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass Peasant : IPeasant
|
||||
|
||||
5
src/cascadia/Remoting/RenameRequestArgs.cpp
Normal file
5
src/cascadia/Remoting/RenameRequestArgs.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
#include "pch.h"
|
||||
#include "RenameRequestArgs.h"
|
||||
#include "RenameRequestArgs.g.cpp"
|
||||
30
src/cascadia/Remoting/RenameRequestArgs.h
Normal file
30
src/cascadia/Remoting/RenameRequestArgs.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Class Name:
|
||||
- RenameRequestArgs.h
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "RenameRequestArgs.g.h"
|
||||
#include "../cascadia/inc/cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
{
|
||||
struct RenameRequestArgs : public RenameRequestArgsT<RenameRequestArgs>
|
||||
{
|
||||
WINRT_PROPERTY(winrt::hstring, NewName);
|
||||
WINRT_PROPERTY(bool, Succeeded, false);
|
||||
|
||||
public:
|
||||
RenameRequestArgs(winrt::hstring newName) :
|
||||
_NewName{ newName } {};
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(RenameRequestArgs);
|
||||
}
|
||||
@@ -49,7 +49,6 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)\build\rules\Branding.targets" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<!-- Override GetPackagingOutputs to roll up our DLL.
|
||||
|
||||
@@ -1,52 +1,63 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<Toolkit:XamlApplication
|
||||
x:Class="TerminalApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost"
|
||||
xmlns:TA="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<!-- If you want to prove this works, then add `RequestedTheme="Light"` to
|
||||
the properties on the XamlApplication -->
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<Toolkit:XamlApplication x:Class="TerminalApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:TA="using:TerminalApp"
|
||||
xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<!--
|
||||
If you want to prove this works, then add `RequestedTheme="Light"` to
|
||||
the properties on the XamlApplication
|
||||
-->
|
||||
<Toolkit:XamlApplication.Resources>
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<!-- Include the MUX Controls resources -->
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
|
||||
<!-- Include the MUX Controls resources -->
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<ResourceDictionary>
|
||||
|
||||
<!-- We're going to apply this style to the root Grid acting
|
||||
as the tab row, because we need to be able to set its
|
||||
`Background` property to "{ThemeResource
|
||||
ApplicationPageBackgroundThemeBrush}" so it will be colored
|
||||
appropriately for the theme, regardless of what we set the
|
||||
RequestedTheme to -->
|
||||
<Style x:Name="BackgroundGridThemeStyle" TargetType="Grid">
|
||||
<!--
|
||||
We're going to apply this style to the root Grid acting
|
||||
as the tab row, because we need to be able to set its
|
||||
`Background` property to "{ThemeResource
|
||||
ApplicationPageBackgroundThemeBrush}" so it will be colored
|
||||
appropriately for the theme, regardless of what we set the
|
||||
RequestedTheme to
|
||||
-->
|
||||
<Style x:Name="BackgroundGridThemeStyle"
|
||||
TargetType="Grid">
|
||||
<Setter Property="Background" Value="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- We need to manually create the error text brush as a
|
||||
theme-dependent brush. SystemControlErrorTextForegroundBrush
|
||||
is unfortunately static. -->
|
||||
<SolidColorBrush x:Name="ErrorTextBrush" Color="{ThemeResource SystemErrorTextColor}" />
|
||||
<!--
|
||||
We need to manually create the error text brush as a
|
||||
theme-dependent brush. SystemControlErrorTextForegroundBrush
|
||||
is unfortunately static.
|
||||
-->
|
||||
<SolidColorBrush x:Name="ErrorTextBrush"
|
||||
Color="{ThemeResource SystemErrorTextColor}" />
|
||||
|
||||
<!-- Suppress all padding except left around the tabs. The TabView looks far better like this. -->
|
||||
<Thickness x:Key="TabViewHeaderPadding">8,0,0,0</Thickness>
|
||||
<!-- Suppress top padding -->
|
||||
<Thickness x:Key="TabViewHeaderPadding">8,0,8,0</Thickness>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- Define resources for Dark mode here -->
|
||||
<SolidColorBrush x:Key="TabViewBackground" Color="#FF333333" />
|
||||
<!-- Define resources for Dark mode here -->
|
||||
<SolidColorBrush x:Key="TabViewBackground"
|
||||
Color="#FF333333" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- Define resources for Light mode here -->
|
||||
<SolidColorBrush x:Key="TabViewBackground" Color="#FFCCCCCC" />
|
||||
<!-- Define resources for Light mode here -->
|
||||
<SolidColorBrush x:Key="TabViewBackground"
|
||||
Color="#FFCCCCCC" />
|
||||
</ResourceDictionary>
|
||||
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
@@ -252,8 +252,8 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SwitchToTabArgs>())
|
||||
{
|
||||
const auto handled = _SelectTab({ realArgs.TabIndex() });
|
||||
args.Handled(handled);
|
||||
_SelectTab({ realArgs.TabIndex() });
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,7 +517,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
// Since _RemoveTab is asynchronous, create a snapshot of the tabs we want to remove
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
if (index > 0)
|
||||
{
|
||||
@@ -556,7 +556,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
// Since _RemoveTab is asynchronous, create a snapshot of the tabs we want to remove
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
std::copy(begin(_tabs) + index + 1, end(_tabs), std::back_inserter(tabsToRemove));
|
||||
_RemoveTabs(tabsToRemove);
|
||||
@@ -571,8 +571,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenTabSearch(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
void TerminalPage::_HandleTabSearch(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
CommandPalette().SetTabs(_tabs, _mruTabs);
|
||||
CommandPalette().EnableTabSearchMode();
|
||||
@@ -694,4 +694,81 @@ namespace winrt::TerminalApp::implementation
|
||||
actionArgs.Handled(true);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Raise a IdentifyWindowsRequested event. This will bubble up to the
|
||||
// AppLogic, to the AppHost, to the Peasant, to the Monarch, then get
|
||||
// distributed down to _all_ the Peasants, as to display info about the
|
||||
// window in _every_ Peasant window.
|
||||
// - This action is also buggy right now, because TeachingTips behave
|
||||
// weird in XAML Islands. See microsoft-ui-xaml#4382
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_HandleIdentifyWindows(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
_IdentifyWindowsRequestedHandlers(*this, nullptr);
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Display the "Toast" with the name and ID of this window.
|
||||
// - Unlike _HandleIdentifyWindow**s**, this event just displays the window
|
||||
// ID and name in the current window. It does not involve any bubbling
|
||||
// up/down the page/logic/host/manager/peasant/monarch.
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_HandleIdentifyWindow(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
IdentifyWindow();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleRenameWindow(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<RenameWindowArgs>())
|
||||
{
|
||||
const auto newName = realArgs.Name();
|
||||
const auto request = winrt::make_self<implementation::RenameWindowRequestedArgs>(newName);
|
||||
_RenameWindowRequestedHandlers(*this, *request);
|
||||
}
|
||||
}
|
||||
args.Handled(false);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenWindowRenamer(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (WindowRenamer() == nullptr)
|
||||
{
|
||||
// We need to use FindName to lazy-load this object
|
||||
if (MUX::Controls::TeachingTip tip{ FindName(L"WindowRenamer").try_as<MUX::Controls::TeachingTip>() })
|
||||
{
|
||||
tip.Closed({ get_weak(), &TerminalPage::_FocusActiveControl });
|
||||
}
|
||||
}
|
||||
|
||||
_UpdateTeachingTipTheme(WindowRenamer().try_as<winrt::Windows::UI::Xaml::FrameworkElement>());
|
||||
WindowRenamer().IsOpen(true);
|
||||
|
||||
// PAIN: We can't immediately focus the textbox in the TeachingTip. It's
|
||||
// not technically focusable until it is opened. However, it doesn't
|
||||
// provide an event to tell us when it is opened. That's tracked in
|
||||
// microsoft/microsoft-ui-xaml#1607. So for now, the user _needs_ to
|
||||
// click on the text box manually.
|
||||
//
|
||||
// We're also not using a ContentDialog for this, because in Xaml
|
||||
// Islands a text box in a ContentDialog won't receive _any_ keypresses.
|
||||
// Fun!
|
||||
// WindowRenamerTextBox().Focus(FocusState::Programmatic);
|
||||
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +255,10 @@ void AppCommandlineArgs::_buildSplitPaneParser()
|
||||
auto* sizeOpt = subcommand.subcommand->add_option("-s,--size",
|
||||
_splitPaneSize,
|
||||
RS_A(L"CmdSplitPaneSizeArgDesc"));
|
||||
|
||||
subcommand._duplicateOption = subcommand.subcommand->add_flag("-D,--duplicate",
|
||||
_splitDuplicate,
|
||||
RS_A(L"CmdSplitPaneDuplicateArgDesc"));
|
||||
sizeOpt->check(CLI::Range(0.01f, 0.99f));
|
||||
|
||||
// When ParseCommand is called, if this subcommand was provided, this
|
||||
@@ -283,7 +287,8 @@ void AppCommandlineArgs::_buildSplitPaneParser()
|
||||
style = SplitState::Vertical;
|
||||
}
|
||||
}
|
||||
SplitPaneArgs args{ style, _splitPaneSize, terminalArgs };
|
||||
const auto splitMode{ subcommand._duplicateOption && _splitDuplicate ? SplitType::Duplicate : SplitType::Manual };
|
||||
SplitPaneArgs args{ splitMode, style, _splitPaneSize, terminalArgs };
|
||||
splitPaneActionAndArgs.Args(args);
|
||||
_startupActions.push_back(splitPaneActionAndArgs);
|
||||
});
|
||||
@@ -422,6 +427,9 @@ void AppCommandlineArgs::_addNewTerminalArgs(AppCommandlineArgs::NewTerminalSubc
|
||||
_suppressApplicationTitle,
|
||||
RS_A(L"CmdSuppressApplicationTitleDesc"));
|
||||
|
||||
subcommand.colorSchemeOption = subcommand.subcommand->add_option("--colorScheme",
|
||||
_startingColorScheme,
|
||||
RS_A(L"CmdColorSchemeArgDesc"));
|
||||
// Using positionals_at_end allows us to support "wt new-tab -d wsl -d Ubuntu"
|
||||
// without CLI11 thinking that we've specified -d twice.
|
||||
// There's an alternate construction where we make all subcommands "prefix commands",
|
||||
@@ -494,6 +502,11 @@ NewTerminalArgs AppCommandlineArgs::_getNewTerminalArgs(AppCommandlineArgs::NewT
|
||||
args.SuppressApplicationTitle(_suppressApplicationTitle);
|
||||
}
|
||||
|
||||
if (*subcommand.colorSchemeOption)
|
||||
{
|
||||
args.ColorScheme(winrt::to_hstring(_startingColorScheme));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -537,6 +550,7 @@ void AppCommandlineArgs::_resetStateToDefault()
|
||||
_splitVertical = false;
|
||||
_splitHorizontal = false;
|
||||
_splitPaneSize = 0.5f;
|
||||
_splitDuplicate = false;
|
||||
|
||||
_focusTabIndex = -1;
|
||||
_focusNextTab = false;
|
||||
@@ -684,6 +698,18 @@ std::vector<ActionAndArgs>& AppCommandlineArgs::GetStartupActions()
|
||||
return _startupActions;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns whether we should start listening for inbound PTY connections
|
||||
// coming from the operating system default application feature.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - True if the listener should be started. False otherwise.
|
||||
bool AppCommandlineArgs::IsHandoffListener() const noexcept
|
||||
{
|
||||
return _isHandoffListener;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the string of text that should be displayed to the user on exit. This
|
||||
// is usually helpful for cases where the user entered some sort of invalid
|
||||
@@ -726,17 +752,23 @@ bool AppCommandlineArgs::ShouldExitEarly() const noexcept
|
||||
// - <none>
|
||||
void AppCommandlineArgs::ValidateStartupCommands()
|
||||
{
|
||||
// If we parsed no commands, or the first command we've parsed is not a new
|
||||
// tab action, prepend a new-tab command to the front of the list.
|
||||
if (_startupActions.empty() ||
|
||||
_startupActions.front().Action() != ShortcutAction::NewTab)
|
||||
// Only check over the actions list for the potential to add a new-tab
|
||||
// command if we are not starting for the purposes of receiving an inbound
|
||||
// handoff connection from the operating system.
|
||||
if (!_isHandoffListener)
|
||||
{
|
||||
// Build the NewTab action from the values we've parsed on the commandline.
|
||||
NewTerminalArgs newTerminalArgs{};
|
||||
NewTabArgs args{ newTerminalArgs };
|
||||
ActionAndArgs newTabAction{ ShortcutAction::NewTab, args };
|
||||
// push the arg onto the front
|
||||
_startupActions.insert(_startupActions.begin(), 1, newTabAction);
|
||||
// If we parsed no commands, or the first command we've parsed is not a new
|
||||
// tab action, prepend a new-tab command to the front of the list.
|
||||
if (_startupActions.empty() ||
|
||||
_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 };
|
||||
// push the arg onto the front
|
||||
_startupActions.insert(_startupActions.begin(), 1, newTabAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,6 +792,15 @@ std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> AppComman
|
||||
// - 0 if the commandline was successfully parsed
|
||||
int AppCommandlineArgs::ParseArgs(winrt::array_view<const winrt::hstring>& args)
|
||||
{
|
||||
for (const auto& arg : args)
|
||||
{
|
||||
if (arg == L"-Embedding")
|
||||
{
|
||||
_isHandoffListener = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);
|
||||
|
||||
for (auto& cmdBlob : commands)
|
||||
@@ -864,6 +905,7 @@ void AppCommandlineArgs::FullResetState()
|
||||
_startupActions.clear();
|
||||
_exitMessage = "";
|
||||
_shouldExitEarly = false;
|
||||
_isHandoffListener = false;
|
||||
|
||||
_windowTarget = {};
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
|
||||
void ValidateStartupCommands();
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>& GetStartupActions();
|
||||
bool IsHandoffListener() const noexcept;
|
||||
const std::string& GetExitMessage();
|
||||
bool ShouldExitEarly() const noexcept;
|
||||
|
||||
@@ -62,12 +63,14 @@ private:
|
||||
CLI::Option* titleOption;
|
||||
CLI::Option* tabColorOption;
|
||||
CLI::Option* suppressApplicationTitleOption;
|
||||
CLI::Option* colorSchemeOption;
|
||||
};
|
||||
|
||||
struct NewPaneSubcommand : public NewTerminalSubcommand
|
||||
{
|
||||
CLI::Option* _horizontalOption;
|
||||
CLI::Option* _verticalOption;
|
||||
CLI::Option* _duplicateOption;
|
||||
};
|
||||
|
||||
// --- Subcommands ---
|
||||
@@ -86,6 +89,7 @@ private:
|
||||
std::string _startingDirectory;
|
||||
std::string _startingTitle;
|
||||
std::string _startingTabColor;
|
||||
std::string _startingColorScheme;
|
||||
bool _suppressApplicationTitle{ false };
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::FocusDirection _moveFocusDirection{ winrt::Microsoft::Terminal::Settings::Model::FocusDirection::None };
|
||||
@@ -95,6 +99,7 @@ private:
|
||||
|
||||
bool _splitVertical{ false };
|
||||
bool _splitHorizontal{ false };
|
||||
bool _splitDuplicate{ false };
|
||||
float _splitPaneSize{ 0.5f };
|
||||
|
||||
int _focusTabIndex{ -1 };
|
||||
@@ -104,6 +109,7 @@ private:
|
||||
|
||||
const Commandline* _currentCommandline{ nullptr };
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> _launchMode{ std::nullopt };
|
||||
bool _isHandoffListener{ false };
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs> _startupActions;
|
||||
std::string _exitMessage;
|
||||
bool _shouldExitEarly{ false };
|
||||
|
||||
@@ -1166,6 +1166,17 @@ namespace winrt::TerminalApp::implementation
|
||||
_hasCommandLineArguments = args.size() > 1;
|
||||
_appArgs.ValidateStartupCommands();
|
||||
_root->SetStartupActions(_appArgs.GetStartupActions());
|
||||
|
||||
// Check if we were started as a COM server for inbound connections of console sessions
|
||||
// coming out of the operating system default application feature. If so,
|
||||
// tell TerminalPage to start the listener as we have to make sure it has the chance
|
||||
// to register a handler to hear about the requests first and is all ready to receive
|
||||
// them before the COM server registers itself. Otherwise, the request might come
|
||||
// in and be routed to an event with no handlers or a non-ready Page.
|
||||
if (_appArgs.IsHandoffListener())
|
||||
{
|
||||
_root->SetInboundListener();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1369,4 +1380,43 @@ namespace winrt::TerminalApp::implementation
|
||||
return _root ? _root->AlwaysOnTop() : false;
|
||||
}
|
||||
|
||||
void AppLogic::IdentifyWindow()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
_root->IdentifyWindow();
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring AppLogic::WindowName()
|
||||
{
|
||||
return _root ? _root->WindowName() : L"";
|
||||
}
|
||||
void AppLogic::WindowName(const winrt::hstring& name)
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
_root->WindowName(name);
|
||||
}
|
||||
}
|
||||
uint64_t AppLogic::WindowId()
|
||||
{
|
||||
return _root ? _root->WindowId() : 0;
|
||||
}
|
||||
void AppLogic::WindowId(const uint64_t& id)
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
_root->WindowId(id);
|
||||
}
|
||||
}
|
||||
|
||||
void AppLogic::RenameFailed()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
_root->RenameFailed();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,6 +60,13 @@ namespace winrt::TerminalApp::implementation
|
||||
bool Fullscreen() const;
|
||||
bool AlwaysOnTop() const;
|
||||
|
||||
void IdentifyWindow();
|
||||
void RenameFailed();
|
||||
winrt::hstring WindowName();
|
||||
void WindowName(const winrt::hstring& name);
|
||||
uint64_t WindowId();
|
||||
void WindowId(const uint64_t& id);
|
||||
|
||||
Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi);
|
||||
bool CenterOnLaunch();
|
||||
TerminalApp::InitialPosition GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY);
|
||||
@@ -149,6 +156,8 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged);
|
||||
FORWARDED_TYPED_EVENT(RaiseVisualBell, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, RaiseVisualBell);
|
||||
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
|
||||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class TerminalAppLocalTests::CommandlineTest;
|
||||
|
||||
@@ -48,6 +48,11 @@ namespace TerminalApp
|
||||
Boolean Fullscreen { get; };
|
||||
Boolean AlwaysOnTop { get; };
|
||||
|
||||
void IdentifyWindow();
|
||||
String WindowName;
|
||||
UInt64 WindowId;
|
||||
void RenameFailed();
|
||||
|
||||
Windows.Foundation.Size GetLaunchDimensions(UInt32 dpi);
|
||||
Boolean CenterOnLaunch { get; };
|
||||
|
||||
@@ -78,5 +83,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RaiseVisualBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,146 +1,193 @@
|
||||
<Flyout
|
||||
x:Class="TerminalApp.ColorPickupFlyout"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Flyout x:Class="TerminalApp.ColorPickupFlyout"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Flyout.FlyoutPresenterStyle>
|
||||
<Style TargetType="FlyoutPresenter">
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="0" />
|
||||
</Style>
|
||||
</Flyout.FlyoutPresenterStyle>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel XYFocusKeyboardNavigation="Enabled">
|
||||
<VariableSizedWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="4" HorizontalAlignment="Center" Margin="0, 3, 0, 0">
|
||||
<VariableSizedWrapGrid Margin="0,3,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
MaximumRowsOrColumns="4"
|
||||
Orientation="Horizontal">
|
||||
<VariableSizedWrapGrid.Resources>
|
||||
<Style TargetType="Rectangle">
|
||||
<Setter Property="Width" Value="30"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
<Setter Property="Width" Value="30" />
|
||||
<Setter Property="Height" Value="30" />
|
||||
</Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="2"/>
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="2" />
|
||||
</Style>
|
||||
</VariableSizedWrapGrid.Resources>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Crimson" x:Uid="CrimsonColorButton">
|
||||
<Button x:Uid="CrimsonColorButton"
|
||||
AutomationProperties.Name="Crimson"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Crimson"/>
|
||||
<Rectangle Fill="Crimson" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SteelBlue" x:Uid="SteelBlueColorButton">
|
||||
<Button x:Uid="SteelBlueColorButton"
|
||||
AutomationProperties.Name="SteelBlue"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="SteelBlue"/>
|
||||
<Rectangle Fill="SteelBlue" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumSeaGreen" x:Uid="MediumSeaGreenColorButton">
|
||||
<Button x:Uid="MediumSeaGreenColorButton"
|
||||
AutomationProperties.Name="MediumSeaGreen"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="MediumSeaGreen"/>
|
||||
<Rectangle Fill="MediumSeaGreen" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkOrange" x:Uid="DarkOrangeColorButton">
|
||||
<Button x:Uid="DarkOrangeColorButton"
|
||||
AutomationProperties.Name="DarkOrange"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="DarkOrange"/>
|
||||
<Rectangle Fill="DarkOrange" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="MediumVioletRed" x:Uid="MediumVioletRedColorButton">
|
||||
<Button x:Uid="MediumVioletRedColorButton"
|
||||
AutomationProperties.Name="MediumVioletRed"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="MediumVioletRed"/>
|
||||
<Rectangle Fill="MediumVioletRed" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DodgerBlue" x:Uid="DodgerBlueColorButton">
|
||||
<Button x:Uid="DodgerBlueColorButton"
|
||||
AutomationProperties.Name="DodgerBlue"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="DodgerBlue"/>
|
||||
<Rectangle Fill="DodgerBlue" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="LimeGreen" x:Uid="LimeGreenColorButton">
|
||||
<Button x:Uid="LimeGreenColorButton"
|
||||
AutomationProperties.Name="LimeGreen"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="LimeGreen"/>
|
||||
<Rectangle Fill="LimeGreen" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Yellow" x:Uid="YellowColorButton">
|
||||
<Button x:Uid="YellowColorButton"
|
||||
AutomationProperties.Name="Yellow"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Yellow"/>
|
||||
<Rectangle Fill="Yellow" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="BlueViolet" x:Uid="BlueVioletColorButton">
|
||||
<Button x:Uid="BlueVioletColorButton"
|
||||
AutomationProperties.Name="BlueViolet"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="BlueViolet"/>
|
||||
<Rectangle Fill="BlueViolet" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SlateBlue" x:Uid="SlateBlueColorButton">
|
||||
<Button x:Uid="SlateBlueColorButton"
|
||||
AutomationProperties.Name="SlateBlue"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="SlateBlue"/>
|
||||
<Rectangle Fill="SlateBlue" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Lime" x:Uid="LimeColorButton">
|
||||
<Button x:Uid="LimeColorButton"
|
||||
AutomationProperties.Name="Lime"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Lime"/>
|
||||
<Rectangle Fill="Lime" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Tan" x:Uid="TanColorButton">
|
||||
<Button x:Uid="TanColorButton"
|
||||
AutomationProperties.Name="Tan"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Tan"/>
|
||||
<Rectangle Fill="Tan" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Magenta" x:Uid="MagentaColorButton">
|
||||
<Button x:Uid="MagentaColorButton"
|
||||
AutomationProperties.Name="Magenta"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Magenta"/>
|
||||
<Rectangle Fill="Magenta" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="Cyan" x:Uid="CyanColorButton">
|
||||
<Button x:Uid="CyanColorButton"
|
||||
AutomationProperties.Name="Cyan"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="Cyan"/>
|
||||
<Rectangle Fill="Cyan" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="SkyBlue" x:Uid="SkyBlueColorButton">
|
||||
<Button x:Uid="SkyBlueColorButton"
|
||||
AutomationProperties.Name="SkyBlue"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="SkyBlue"/>
|
||||
<Rectangle Fill="SkyBlue" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Click="ColorButton_Click" AutomationProperties.Name="DarkGray" x:Uid="DarkGrayColorButton">
|
||||
<Button x:Uid="DarkGrayColorButton"
|
||||
AutomationProperties.Name="DarkGray"
|
||||
Click="ColorButton_Click">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="DarkGray"/>
|
||||
<Rectangle Fill="DarkGray" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</VariableSizedWrapGrid>
|
||||
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Margin" Value="2" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
<Button Padding="5"
|
||||
Click="ClearColorButton_Click"
|
||||
x:Name="ClearColorButton" x:Uid="TabColorClearButton" CornerRadius="2" Content="Reset">
|
||||
</Button>
|
||||
<Button Padding="5"
|
||||
Click="ShowColorPickerButton_Click"
|
||||
x:Name="CustomColorButton" x:Uid="TabColorCustomButton" CornerRadius="2" Content="Custom...">
|
||||
</Button>
|
||||
<Button x:Name="ClearColorButton"
|
||||
x:Uid="TabColorClearButton"
|
||||
Padding="5"
|
||||
Click="ClearColorButton_Click"
|
||||
Content="Reset"
|
||||
CornerRadius="2" />
|
||||
<Button x:Name="CustomColorButton"
|
||||
x:Uid="TabColorCustomButton"
|
||||
Padding="5"
|
||||
Click="ShowColorPickerButton_Click"
|
||||
Content="Custom..."
|
||||
CornerRadius="2" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Grid Visibility="Collapsed" x:Name="customColorPanel" Margin="5">
|
||||
<Grid x:Name="customColorPanel"
|
||||
Margin="5"
|
||||
Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ColorPicker x:Name="customColorPicker"
|
||||
IsMoreButtonVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsAlphaEnabled="False"
|
||||
IsAlphaSliderVisible="False"
|
||||
IsAlphaTextInputVisible="False"
|
||||
FontSize="10"
|
||||
Grid.Row="0"
|
||||
ColorChanged="ColorPicker_ColorChanged"
|
||||
>
|
||||
</ColorPicker>
|
||||
<Button x:Name="OkButton" Click="CustomColorButton_Click" Grid.Row="1" HorizontalAlignment="Center" MinWidth="130" MinHeight="12" Margin="0, 5, 0, 0" x:Uid="OkButton" Content="**OK**"/>
|
||||
Grid.Row="0"
|
||||
ColorChanged="ColorPicker_ColorChanged"
|
||||
FontSize="10"
|
||||
IsAlphaEnabled="False"
|
||||
IsAlphaSliderVisible="False"
|
||||
IsAlphaTextInputVisible="False"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True" />
|
||||
<Button x:Name="OkButton"
|
||||
x:Uid="OkButton"
|
||||
Grid.Row="1"
|
||||
MinWidth="130"
|
||||
MinHeight="12"
|
||||
Margin="0,5,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Click="CustomColorButton_Click"
|
||||
Content="**OK**" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
|
||||
@@ -1,490 +1,500 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<UserControl
|
||||
x:Class="TerminalApp.CommandPalette"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
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"
|
||||
PointerPressed="_rootPointerPressed"
|
||||
PreviewKeyDown="_previewKeyDownHandler"
|
||||
PreviewKeyUp="_keyUpHandler"
|
||||
LostFocus="_lostFocusHandler"
|
||||
mc:Ignorable="d"
|
||||
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<!-- ThemeShadow is only on 18362. This "Windows10version1903" bit
|
||||
adds it conditionally -->
|
||||
<Windows10version1903:ThemeShadow x:Name="CommandPaletteShadow" />
|
||||
|
||||
<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
|
||||
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter"/>
|
||||
<local:EmptyStringVisibilityConverter x:Key="ParsedCommandLineTextVisibilityConverter"/>
|
||||
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter"/>
|
||||
<model:IconPathConverter x:Key="IconSourceConverter"/>
|
||||
|
||||
<DataTemplate x:Key="ListItemTemplate" x:DataType="local:FilteredCommand">
|
||||
<ListViewItem HorizontalContentAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind Item.Name, Mode=OneWay}"
|
||||
AutomationProperties.AcceleratorKey="{x:Bind Item.KeyChordText, Mode=OneWay}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="GeneralItemTemplate" x:DataType="local:FilteredCommand">
|
||||
<Grid HorizontalAlignment="Stretch" ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<!-- command label -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="16"/>
|
||||
<!-- gutter for scrollbar -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Item.Icon,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource IconSourceConverter}}"/>
|
||||
|
||||
<local:HighlightedTextControl
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}"/>
|
||||
|
||||
<!-- The block for the key chord is only visible
|
||||
when there's actual text set as the label. See
|
||||
CommandKeyChordVisibilityConverter for details.
|
||||
We're setting the accessibility view on the
|
||||
border and text block to Raw because otherwise,
|
||||
Narrator will read out the key chord. Problem is,
|
||||
it already did that because it was the list item's
|
||||
"AcceleratorKey". It's redundant. -->
|
||||
<Border
|
||||
Grid.Column="2"
|
||||
Visibility="{x:Bind Item.KeyChordText,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource CommandKeyChordVisibilityConverter}}"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
|
||||
<TextBlock
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
FontSize="12"
|
||||
Text="{x:Bind Item.KeyChordText, Mode=OneWay}"
|
||||
AutomationProperties.AccessibilityView="Raw" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="NestedItemTemplate" x:DataType="local:FilteredCommand">
|
||||
<Grid HorizontalAlignment="Stretch" ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<!-- command label -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="16"/>
|
||||
<!-- gutter for scrollbar -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Item.Icon,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource IconSourceConverter}}"/>
|
||||
|
||||
<local:HighlightedTextControl
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}"/>
|
||||
|
||||
<!-- The block for the key chord is only visible
|
||||
when there's actual text set as the label. See
|
||||
CommandKeyChordVisibilityConverter for details.
|
||||
We're setting the accessibility view on the
|
||||
border and text block to Raw because otherwise,
|
||||
Narrator will read out the key chord. Problem is,
|
||||
it already did that because it was the list item's
|
||||
"AcceleratorKey". It's redundant. -->
|
||||
<Border
|
||||
Grid.Column="2"
|
||||
Visibility="{x:Bind Item.KeyChordText,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource CommandKeyChordVisibilityConverter}}"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
|
||||
<TextBlock
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
FontSize="12"
|
||||
Text="{x:Bind Item.KeyChordText, Mode=OneWay}"
|
||||
AutomationProperties.AccessibilityView="Raw" />
|
||||
</Border>
|
||||
|
||||
<!-- xE70E is ChevronUp. Rotated 90 degrees, it's _ChevronRight_ -->
|
||||
<FontIcon
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
HorizontalAlignment="Right"
|
||||
Grid.Column="2">
|
||||
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform CenterX="0.5" CenterY="0.5" Angle="90"/>
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TabItemTemplate" x:DataType="local:FilteredCommand">
|
||||
<Grid HorizontalAlignment="Stretch" ColumnSpacing="8" AutomationProperties.Name="{x:Bind Item.Name, Mode=OneWay}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<!-- icon / progress -->
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<!-- command label -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- gutter for indicators -->
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<!-- Indicators -->
|
||||
<ColumnDefinition Width="16"/>
|
||||
<!-- gutter for scrollbar -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<mux:ProgressRing
|
||||
Grid.Column="0"
|
||||
IsActive="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsProgressRingActive, Mode=OneWay}"
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsProgressRingActive, Mode=OneWay}"
|
||||
IsIndeterminate="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsProgressRingIndeterminate, Mode=OneWay}"
|
||||
Value="{x:Bind Item.(local:TabPaletteItem.TabStatus).ProgressValue, Mode=OneWay}"
|
||||
MinHeight="0"
|
||||
MinWidth="0"
|
||||
Height="15"
|
||||
Width="15"/>
|
||||
|
||||
<IconSourceElement
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Item.Icon,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource IconSourceConverter}}"/>
|
||||
|
||||
<local:HighlightedTextControl
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}"/>
|
||||
|
||||
<StackPanel
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<FontIcon
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).BellIndicator, Mode=OneWay}"
|
||||
Glyph=""
|
||||
FontSize="12"
|
||||
Margin="0,0,8,0"/>
|
||||
|
||||
<FontIcon
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsPaneZoomed, Mode=OneWay}"
|
||||
Glyph=""
|
||||
FontSize="12"
|
||||
Margin="0,0,8,0"/>
|
||||
|
||||
<FontIcon x:Name="HeaderLockIcon"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsReadOnlyActive, Mode=OneWay}"
|
||||
Glyph=""
|
||||
FontSize="12"
|
||||
Margin="0,0,8,0"/>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<local:PaletteItemTemplateSelector x:Key="PaletteItemTemplateSelector"
|
||||
TabItemTemplate="{StaticResource TabItemTemplate}"
|
||||
GeneralItemTemplate="{StaticResource GeneralItemTemplate}"
|
||||
NestedItemTemplate="{StaticResource NestedItemTemplate}"/>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
|
||||
<Setter Property="Background" Value="#333333" />
|
||||
</Style>
|
||||
<!-- TextBox colors !-->
|
||||
<SolidColorBrush x:Key="TextControlBackground" Color="#333333"/>
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#B5B5B5"/>
|
||||
<SolidColorBrush x:Key="TextControlForeground" Color="#B5B5B5"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground" Color="#B5B5B5"/>
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver" Color="#FF4343"/>
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused" Color="#333333"/>
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed" Color="#FF4343"/>
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle" TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle" TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
|
||||
<Setter Property="Background" Value="#CCCCCC" />
|
||||
</Style>
|
||||
<!-- TextBox colors !-->
|
||||
<SolidColorBrush x:Key="TextControlBackground" Color="#CCCCCC"/>
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground" Color="#636363"/>
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver" Color="#DADADA"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver" Color="#FF4343"/>
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused" Color="#CCCCCC"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed" Color="#FF4343"/>
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle" TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle" TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
|
||||
<Setter Property="Background" Value="{ThemeResource SystemColorWindowColor}" />
|
||||
</Style>
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle" TargetType="Border"/>
|
||||
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock"/>
|
||||
|
||||
<!-- ParsedCommandLineText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle" TargetType="Border"/>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle" TargetType="TextBlock"/>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="6*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="8*"/>
|
||||
<RowDefinition Height="2*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Setting the row/col span of this shadow backdrop is a bit of a hack. In
|
||||
order to receive pointer events, an element needs to be _not_ transparent.
|
||||
However, we want to be able to eat all the clicks outside the immediate
|
||||
bounds of the command palette, and we don't want a semi-transparent overlay
|
||||
over all of the UI. Fortunately, if we make this _shadowBackdrop the size of
|
||||
the entire page, then it can be mostly transparent, and cause the root grid
|
||||
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">
|
||||
</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">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</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="">
|
||||
</TextBox>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
x:Name="_prefixCharacter"
|
||||
Margin="16,16,0,-8"
|
||||
FontSize="14"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{x:Bind PrefixCharacter,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource ParentCommandVisibilityConverter}}"
|
||||
Text="{x:Bind PrefixCharacter, Mode=OneWay}"
|
||||
>
|
||||
</TextBlock>
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Padding="16, 0, 16, 4"
|
||||
Grid.Row="1"
|
||||
Visibility="{x:Bind ParentCommandName,
|
||||
Mode=OneWay,
|
||||
Converter={StaticResource ParentCommandVisibilityConverter}}">
|
||||
|
||||
<Button
|
||||
Background="Transparent"
|
||||
x:Name="_parentCommandBackButton"
|
||||
x:Uid="ParentCommandBackButton"
|
||||
Click="_moveBackButtonClicked"
|
||||
ClickMode="Press"
|
||||
VerticalAlignment="Center">
|
||||
<FontIcon
|
||||
FontSize="12"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="">
|
||||
</FontIcon>
|
||||
</Button>
|
||||
|
||||
<TextBlock
|
||||
Padding="16, 0, 16, 4"
|
||||
x:Name="_parentCommandText"
|
||||
FontStyle="Italic"
|
||||
Grid.Row="1"
|
||||
Text="{x:Bind ParentCommandName, Mode=OneWay}"
|
||||
VerticalAlignment="Center">
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Padding="16"
|
||||
x:Name="_noMatchesText"
|
||||
FontStyle="Italic"
|
||||
Visibility="Collapsed"
|
||||
Grid.Row="1"
|
||||
Text="{x:Bind NoMatchesText, Mode=OneWay}">
|
||||
</TextBlock>
|
||||
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Visibility="{x:Bind ParsedCommandLineText, Mode=OneWay, Converter={StaticResource ParsedCommandLineTextVisibilityConverter}}"
|
||||
Style="{ThemeResource ParsedCommandLineBorderStyle}"
|
||||
Padding="16"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center">
|
||||
|
||||
<ScrollViewer MaxHeight="200" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock
|
||||
FontStyle="Italic"
|
||||
TextWrapping="Wrap"
|
||||
Text="{x:Bind ParsedCommandLineText, Mode=OneWay}"/>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<ListView
|
||||
Grid.Row="2"
|
||||
x:Name="_filteredActionsView"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
SelectionMode="Single"
|
||||
CanReorderItems="False"
|
||||
AllowDrop="False"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="_listItemClicked"
|
||||
ChoosingItemContainer="_choosingItemContainer"
|
||||
ContainerContentChanging="_containerContentChanging"
|
||||
ItemsSource="{x:Bind FilteredActions}">
|
||||
</ListView>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<UserControl x:Class="TerminalApp.CommandPalette"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:SettingsModel="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:Windows10version1903="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 8)"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
AllowFocusOnInteraction="True"
|
||||
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
|
||||
IsTabStop="True"
|
||||
LostFocus="_lostFocusHandler"
|
||||
PointerPressed="_rootPointerPressed"
|
||||
PreviewKeyDown="_previewKeyDownHandler"
|
||||
PreviewKeyUp="_keyUpHandler"
|
||||
TabNavigation="Cycle"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<!--
|
||||
ThemeShadow is only on 18362. This "Windows10version1903" bit
|
||||
adds it conditionally
|
||||
-->
|
||||
<Windows10version1903:ThemeShadow x:Name="CommandPaletteShadow" />
|
||||
|
||||
<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
|
||||
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter" />
|
||||
<local:EmptyStringVisibilityConverter x:Key="ParsedCommandLineTextVisibilityConverter" />
|
||||
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter" />
|
||||
<model:IconPathConverter x:Key="IconSourceConverter" />
|
||||
|
||||
<DataTemplate x:Key="ListItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<ListViewItem HorizontalContentAlignment="Stretch"
|
||||
AutomationProperties.AcceleratorKey="{x:Bind Item.KeyChordText, Mode=OneWay}"
|
||||
AutomationProperties.Name="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="GeneralItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- command label -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- gutter for scrollbar -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Item.Icon, Mode=OneWay, Converter={StaticResource IconSourceConverter}}" />
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
|
||||
<!--
|
||||
The block for the key chord is only visible
|
||||
when there's actual text set as the label. See
|
||||
CommandKeyChordVisibilityConverter for details.
|
||||
We're setting the accessibility view on the
|
||||
border and text block to Raw because otherwise,
|
||||
Narrator will read out the key chord. Problem is,
|
||||
it already did that because it was the list item's
|
||||
"AcceleratorKey". It's redundant.
|
||||
-->
|
||||
<Border Grid.Column="2"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
|
||||
|
||||
<TextBlock AutomationProperties.AccessibilityView="Raw"
|
||||
FontSize="12"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind Item.KeyChordText, Mode=OneWay}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="NestedItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- command label -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- gutter for scrollbar -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Item.Icon, Mode=OneWay, Converter={StaticResource IconSourceConverter}}" />
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
|
||||
<!--
|
||||
The block for the key chord is only visible
|
||||
when there's actual text set as the label. See
|
||||
CommandKeyChordVisibilityConverter for details.
|
||||
We're setting the accessibility view on the
|
||||
border and text block to Raw because otherwise,
|
||||
Narrator will read out the key chord. Problem is,
|
||||
it already did that because it was the list item's
|
||||
"AcceleratorKey". It's redundant.
|
||||
-->
|
||||
<Border Grid.Column="2"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
|
||||
|
||||
<TextBlock AutomationProperties.AccessibilityView="Raw"
|
||||
FontSize="12"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind Item.KeyChordText, Mode=OneWay}" />
|
||||
</Border>
|
||||
|
||||
<!-- xE70E is ChevronUp. Rotated 90 degrees, it's _ChevronRight_ -->
|
||||
<FontIcon Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="">
|
||||
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="90" CenterX="0.5" CenterY="0.5" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TabItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind Item.Name, Mode=OneWay}"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- icon / progress -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- command label -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- gutter for indicators -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Indicators -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- gutter for scrollbar -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<mux:ProgressRing Grid.Column="0"
|
||||
Width="15"
|
||||
Height="15"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
IsActive="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsProgressRingActive, Mode=OneWay}"
|
||||
IsIndeterminate="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsProgressRingIndeterminate, Mode=OneWay}"
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsProgressRingActive, Mode=OneWay}"
|
||||
Value="{x:Bind Item.(local:TabPaletteItem.TabStatus).ProgressValue, Mode=OneWay}" />
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind Item.Icon, Mode=OneWay, Converter={StaticResource IconSourceConverter}}" />
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
|
||||
<StackPanel Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<FontIcon Margin="0,0,8,0"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).BellIndicator, Mode=OneWay}" />
|
||||
|
||||
<FontIcon Margin="0,0,8,0"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsPaneZoomed, Mode=OneWay}" />
|
||||
|
||||
<FontIcon x:Name="HeaderLockIcon"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsReadOnlyActive, Mode=OneWay}" />
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<local:PaletteItemTemplateSelector x:Key="PaletteItemTemplateSelector"
|
||||
GeneralItemTemplate="{StaticResource GeneralItemTemplate}"
|
||||
NestedItemTemplate="{StaticResource NestedItemTemplate}"
|
||||
TabItemTemplate="{StaticResource TabItemTemplate}" />
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Style x:Key="CommandPaletteBackground"
|
||||
TargetType="Grid">
|
||||
<Setter Property="Background" Value="#333333" />
|
||||
</Style>
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlForeground"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#B5B5B5" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Style x:Key="CommandPaletteBackground"
|
||||
TargetType="Grid">
|
||||
<Setter Property="Background" Value="#CCCCCC" />
|
||||
</Style>
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#636363" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ParsedCommandLineText styles -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="CommandPaletteBackground"
|
||||
TargetType="Grid">
|
||||
<Setter Property="Background" Value="{ThemeResource SystemColorWindowColor}" />
|
||||
</Style>
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
|
||||
<!-- ParsedCommandLineText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="ParsedCommandLineBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="ParsedCommandLineTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="6*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="8*" />
|
||||
<RowDefinition Height="2*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!--
|
||||
Setting the row/col span of this shadow backdrop is a bit of a hack. In
|
||||
order to receive pointer events, an element needs to be _not_ transparent.
|
||||
However, we want to be able to eat all the clicks outside the immediate
|
||||
bounds of the command palette, and we don't want a semi-transparent overlay
|
||||
over all of the UI. Fortunately, if we make this _shadowBackdrop the size of
|
||||
the entire page, then it can be mostly transparent, and cause the root grid
|
||||
to receive clicks _anywhere_ in its bounds.
|
||||
-->
|
||||
|
||||
<Grid x:Name="_shadowBackdrop"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent" />
|
||||
|
||||
<Grid x:Name="_backdrop"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Windows10version1903:Shadow="{StaticResource CommandPaletteShadow}"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}"
|
||||
PointerPressed="_backdropPointerPressed"
|
||||
Style="{ThemeResource CommandPaletteBackground}">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox x:Name="_searchBox"
|
||||
Grid.Row="0"
|
||||
Margin="8"
|
||||
Padding="18,8,8,8"
|
||||
IsSpellCheckEnabled="False"
|
||||
PlaceholderText="{x:Bind SearchBoxPlaceholderText, Mode=OneWay}"
|
||||
Text=""
|
||||
TextChanged="_filterTextChanged" />
|
||||
|
||||
<TextBlock x:Name="_prefixCharacter"
|
||||
Grid.Row="0"
|
||||
Margin="16,16,0,-8"
|
||||
HorizontalAlignment="Left"
|
||||
FontSize="14"
|
||||
Text="{x:Bind PrefixCharacter, Mode=OneWay}"
|
||||
Visibility="{x:Bind PrefixCharacter, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}" />
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Padding="16,0,16,4"
|
||||
Orientation="Horizontal"
|
||||
Visibility="{x:Bind ParentCommandName, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}">
|
||||
|
||||
<Button x:Name="_parentCommandBackButton"
|
||||
x:Uid="ParentCommandBackButton"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
Click="_moveBackButtonClicked"
|
||||
ClickMode="Press">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<TextBlock x:Name="_parentCommandText"
|
||||
Grid.Row="1"
|
||||
Padding="16,0,16,4"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic"
|
||||
Text="{x:Bind ParentCommandName, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock x:Name="_noMatchesText"
|
||||
Grid.Row="1"
|
||||
Padding="16"
|
||||
FontStyle="Italic"
|
||||
Text="{x:Bind NoMatchesText, Mode=OneWay}"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<Border Grid.Row="1"
|
||||
Padding="16"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Style="{ThemeResource ParsedCommandLineBorderStyle}"
|
||||
Visibility="{x:Bind ParsedCommandLineText, Mode=OneWay, Converter={StaticResource ParsedCommandLineTextVisibilityConverter}}">
|
||||
|
||||
<ScrollViewer MaxHeight="200"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock FontStyle="Italic"
|
||||
Text="{x:Bind ParsedCommandLineText, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<ListView x:Name="_filteredActionsView"
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
AllowDrop="False"
|
||||
CanReorderItems="False"
|
||||
ChoosingItemContainer="_choosingItemContainer"
|
||||
ContainerContentChanging="_containerContentChanging"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="_listItemClicked"
|
||||
ItemsSource="{x:Bind FilteredActions}"
|
||||
SelectionMode="Single" />
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<UserControl
|
||||
x:Class="TerminalApp.HighlightedTextControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="Transparent">
|
||||
<UserControl x:Class="TerminalApp.HighlightedTextControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<TextBlock
|
||||
x:Name="_textView"/>
|
||||
<TextBlock x:Name="_textView" />
|
||||
</UserControl>
|
||||
|
||||
@@ -1,86 +1,135 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<StackPanel
|
||||
x:Class="TerminalApp.MinMaxCloseControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="Transparent"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Horizontal"
|
||||
d:DesignHeight="36"
|
||||
d:DesignWidth="400">
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<StackPanel x:Class="TerminalApp.MinMaxCloseControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
d:DesignHeight="36"
|
||||
d:DesignWidth="400"
|
||||
Background="Transparent"
|
||||
Orientation="Horizontal"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<x:Double x:Key="CaptionButtonStrokeWidth">1.0</x:Double>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokeColor" ResourceKey="SystemBaseHighColor"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver"
|
||||
ResourceKey="SystemControlBackgroundBaseLowBrush" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed"
|
||||
ResourceKey="SystemControlBackgroundBaseMediumLowBrush" />
|
||||
<StaticResource x:Key="CaptionButtonStroke"
|
||||
ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<StaticResource x:Key="CaptionButtonStrokeColor"
|
||||
ResourceKey="SystemBaseHighColor" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver"
|
||||
ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed"
|
||||
ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground"
|
||||
Color="Transparent" />
|
||||
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="#e81123"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed" Color="Black"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver"
|
||||
Color="#e81123" />
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver"
|
||||
Color="White" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed"
|
||||
Color="#f1707a" />
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed"
|
||||
Color="Black" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackground"
|
||||
Color="#00e81123" />
|
||||
<Color x:Key="CloseButtonBackgroundColor">#00e81123</Color>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<x:Double x:Key="CaptionButtonStrokeWidth">1.0</x:Double>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokeColor" ResourceKey="SystemBaseHighColor"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver"
|
||||
ResourceKey="SystemControlBackgroundBaseLowBrush" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed"
|
||||
ResourceKey="SystemControlBackgroundBaseMediumLowBrush" />
|
||||
<StaticResource x:Key="CaptionButtonStroke"
|
||||
ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<StaticResource x:Key="CaptionButtonStrokeColor"
|
||||
ResourceKey="SystemBaseHighColor" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver"
|
||||
ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed"
|
||||
ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground"
|
||||
Color="Transparent" />
|
||||
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="#e81123"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed" Color="Black"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver"
|
||||
Color="#e81123" />
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver"
|
||||
Color="White" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed"
|
||||
Color="#f1707a" />
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed"
|
||||
Color="Black" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackground"
|
||||
Color="#00e81123" />
|
||||
<Color x:Key="CloseButtonBackgroundColor">#00e81123</Color>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<x:Double x:Key="CaptionButtonStrokeWidth">3.0</x:Double>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground" Color="{ThemeResource SystemColorButtonFaceColor}"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundColor" ResourceKey="SystemColorButtonFaceColor"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPointerOver" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPressed" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonStroke" Color="{ThemeResource SystemColorButtonTextColor}"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokeColor" ResourceKey="SystemColorButtonTextColor"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonStrokePointerOver" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonStrokePressed" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground"
|
||||
Color="{ThemeResource SystemColorButtonFaceColor}" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundColor"
|
||||
ResourceKey="SystemColorButtonFaceColor" />
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPointerOver"
|
||||
Color="{ThemeResource SystemColorHighlightColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPressed"
|
||||
Color="{ThemeResource SystemColorHighlightColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonStroke"
|
||||
Color="{ThemeResource SystemColorButtonTextColor}" />
|
||||
<StaticResource x:Key="CaptionButtonStrokeColor"
|
||||
ResourceKey="SystemColorButtonTextColor" />
|
||||
<SolidColorBrush x:Key="CaptionButtonStrokePointerOver"
|
||||
Color="{ThemeResource SystemColorHighlightTextColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonStrokePressed"
|
||||
Color="{ThemeResource SystemColorHighlightTextColor}" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver"
|
||||
Color="{ThemeResource SystemColorHighlightColor}" />
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver"
|
||||
Color="{ThemeResource SystemColorHighlightTextColor}" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed"
|
||||
Color="{ThemeResource SystemColorHighlightColor}" />
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed"
|
||||
Color="{ThemeResource SystemColorHighlightTextColor}" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<x:String x:Key="CaptionButtonPath"></x:String>
|
||||
<x:String x:Key="CaptionButtonPathWindowMaximized"></x:String>
|
||||
<!--
|
||||
These strings need to be initialized to something, so they're
|
||||
just initialized to the path for the close button. Each specific
|
||||
button should override them as needed.
|
||||
-->
|
||||
<x:String x:Key="CaptionButtonPath">M 0 0 L 10 10 M 10 0 L 0 10</x:String>
|
||||
<x:String x:Key="CaptionButtonPathWindowMaximized">M 0 0 L 10 10 M 10 0 L 0 10</x:String>
|
||||
|
||||
<!-- "CaptionButtonHeightWindowed" and
|
||||
"CaptionButtonHeightMaximized" define the size we should use
|
||||
for the caption buttons height for the windowed and maximized
|
||||
states, respectively.
|
||||
|
||||
32 was chosen for the Maximized height to match the height of
|
||||
the TabRowControl. This way, when the window is maximized, the
|
||||
tabs will be flush with the top of the window. See GH#2541 for
|
||||
details.-->
|
||||
<!--
|
||||
"CaptionButtonHeightWindowed" and
|
||||
"CaptionButtonHeightMaximized" define the size we should use
|
||||
for the caption buttons height for the windowed and maximized
|
||||
states, respectively.
|
||||
|
||||
32 was chosen for the Maximized height to match the height of
|
||||
the TabRowControl. This way, when the window is maximized, the
|
||||
tabs will be flush with the top of the window. See GH#2541 for
|
||||
details.
|
||||
-->
|
||||
<x:Double x:Key="CaptionButtonHeightWindowed">36.0</x:Double>
|
||||
<x:Double x:Key="CaptionButtonHeightMaximized">32.0</x:Double>
|
||||
|
||||
<Style x:Key="CaptionButton" TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Style x:Key="CaptionButton"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Background" Value="{ThemeResource CaptionButtonBackground}" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Template">
|
||||
@@ -88,21 +137,38 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
<ControlTemplate TargetType="Button">
|
||||
|
||||
<Border x:Name="ButtonBaseElement"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
Padding="{TemplateBinding Padding}"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Path x:Name="Path"
|
||||
Width="10"
|
||||
Height="10"
|
||||
Data="{ThemeResource CaptionButtonPath}"
|
||||
Stretch="Fill"
|
||||
Stroke="{ThemeResource CaptionButtonStroke}"
|
||||
StrokeEndLineCap="Square"
|
||||
StrokeStartLineCap="Square"
|
||||
StrokeThickness="{ThemeResource CaptionButtonStrokeWidth}"
|
||||
UseLayoutRounding="True" />
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualStateGroup.Transitions>
|
||||
<VisualTransition From="PointerOver" To="Normal">
|
||||
<VisualTransition From="PointerOver"
|
||||
To="Normal">
|
||||
<Storyboard>
|
||||
<ColorAnimation Storyboard.TargetName="ButtonBaseElement" Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)" To="{ThemeResource CaptionButtonBackgroundColor}" Duration="0:0:0.2"/>
|
||||
<ColorAnimation Storyboard.TargetName="Path" Storyboard.TargetProperty="(UIElement.Stroke).(SolidColorBrush.Color)" To="{ThemeResource CaptionButtonStrokeColor}" Duration="0:0:0.1"/>
|
||||
<ColorAnimation Storyboard.TargetName="ButtonBaseElement"
|
||||
Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)"
|
||||
To="{ThemeResource CaptionButtonBackgroundColor}"
|
||||
Duration="0:0:0.2" />
|
||||
<ColorAnimation Storyboard.TargetName="Path"
|
||||
Storyboard.TargetProperty="(UIElement.Stroke).(SolidColorBrush.Color)"
|
||||
To="{ThemeResource CaptionButtonStrokeColor}"
|
||||
Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</VisualTransition>
|
||||
</VisualStateGroup.Transitions>
|
||||
@@ -142,18 +208,6 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Path
|
||||
x:Name="Path"
|
||||
StrokeThickness="{ThemeResource CaptionButtonStrokeWidth}"
|
||||
Stroke="{ThemeResource CaptionButtonStroke}"
|
||||
Data="{ThemeResource CaptionButtonPath}"
|
||||
Stretch="Fill"
|
||||
UseLayoutRounding="True"
|
||||
Width="10"
|
||||
Height="10"
|
||||
StrokeEndLineCap="Square"
|
||||
StrokeStartLineCap="Square" />
|
||||
</Border>
|
||||
|
||||
</ControlTemplate>
|
||||
@@ -164,24 +218,28 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</ResourceDictionary>
|
||||
</StackPanel.Resources>
|
||||
|
||||
<Button Height="{StaticResource CaptionButtonHeightWindowed}" MinWidth="46.0" Width="46.0"
|
||||
x:Name="MinimizeButton"
|
||||
<Button x:Name="MinimizeButton"
|
||||
x:Uid="WindowMinimizeButton"
|
||||
Style="{StaticResource CaptionButton}"
|
||||
Width="46.0"
|
||||
Height="{StaticResource CaptionButtonHeightWindowed}"
|
||||
MinWidth="46.0"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Click="_MinimizeClick"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
Style="{StaticResource CaptionButton}">
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<x:String x:Key="CaptionButtonPath">M 0 0 H 10</x:String>
|
||||
</ResourceDictionary>
|
||||
</Button.Resources>
|
||||
</Button>
|
||||
<Button Height="{StaticResource CaptionButtonHeightWindowed}" MinWidth="46.0" Width="46.0"
|
||||
x:Name="MaximizeButton"
|
||||
<Button x:Name="MaximizeButton"
|
||||
x:Uid="WindowMaximizeButton"
|
||||
Style="{StaticResource CaptionButton}"
|
||||
Width="46.0"
|
||||
Height="{StaticResource CaptionButtonHeightWindowed}"
|
||||
MinWidth="46.0"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Click="_MaximizeClick"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
Style="{StaticResource CaptionButton}">
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<x:String x:Key="CaptionButtonPath">M 0 0 H 10 V 10 H 0 V 0</x:String>
|
||||
@@ -191,37 +249,59 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip>
|
||||
<TextBlock>
|
||||
<Run x:Name="MaximizeToolTip"/>
|
||||
<Run x:Name="MaximizeToolTip" />
|
||||
</TextBlock>
|
||||
</ToolTip>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Height="{StaticResource CaptionButtonHeightWindowed}" MinWidth="46.0" Width="46.0"
|
||||
x:Name="CloseButton"
|
||||
<Button x:Name="CloseButton"
|
||||
x:Uid="WindowCloseButton"
|
||||
Style="{StaticResource CaptionButton}"
|
||||
Width="46.0"
|
||||
Height="{StaticResource CaptionButtonHeightWindowed}"
|
||||
MinWidth="46.0"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Click="_CloseClick"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
Style="{StaticResource CaptionButton}">
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="CloseButtonBackgroundPointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="CloseButtonBackgroundPressed"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="CloseButtonStrokePointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="CloseButtonStrokePressed"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver"
|
||||
ResourceKey="CloseButtonBackgroundPointerOver" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed"
|
||||
ResourceKey="CloseButtonBackgroundPressed" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver"
|
||||
ResourceKey="CloseButtonStrokePointerOver" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed"
|
||||
ResourceKey="CloseButtonStrokePressed" />
|
||||
<StaticResource x:Key="CaptionButtonBackground"
|
||||
ResourceKey="CloseButtonBackground" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundColor"
|
||||
ResourceKey="CloseButtonBackgroundColor" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="CloseButtonBackgroundPointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="CloseButtonBackgroundPressed"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="CloseButtonStrokePointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="CloseButtonStrokePressed"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver"
|
||||
ResourceKey="CloseButtonBackgroundPointerOver" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed"
|
||||
ResourceKey="CloseButtonBackgroundPressed" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver"
|
||||
ResourceKey="CloseButtonStrokePointerOver" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed"
|
||||
ResourceKey="CloseButtonStrokePressed" />
|
||||
<StaticResource x:Key="CaptionButtonBackground"
|
||||
ResourceKey="CloseButtonBackground" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundColor"
|
||||
ResourceKey="CloseButtonBackgroundColor" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="CloseButtonBackgroundPointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="CloseButtonBackgroundPressed"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="CloseButtonStrokePointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="CloseButtonStrokePressed"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver"
|
||||
ResourceKey="CloseButtonBackgroundPointerOver" />
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed"
|
||||
ResourceKey="CloseButtonBackgroundPressed" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver"
|
||||
ResourceKey="CloseButtonStrokePointerOver" />
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed"
|
||||
ResourceKey="CloseButtonStrokePressed" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
|
||||
@@ -416,11 +416,8 @@ void Pane::_ControlLostFocusHandler(winrt::Windows::Foundation::IInspectable con
|
||||
// - <none>
|
||||
void Pane::Close()
|
||||
{
|
||||
if (!_isClosing.exchange(true))
|
||||
{
|
||||
// Fire our Closed event to tell our parent that we should be removed.
|
||||
_ClosedHandlers(nullptr, nullptr);
|
||||
}
|
||||
// Fire our Closed event to tell our parent that we should be removed.
|
||||
_ClosedHandlers(nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -631,7 +628,7 @@ void Pane::_FocusFirstChild()
|
||||
// - profile: The GUID of the profile these settings should apply to.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Pane::UpdateSettings(const TerminalSettingsStruct& settings, const GUID& profile)
|
||||
void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const GUID& profile)
|
||||
{
|
||||
if (!_IsLeaf())
|
||||
{
|
||||
@@ -642,19 +639,20 @@ void Pane::UpdateSettings(const TerminalSettingsStruct& settings, const GUID& pr
|
||||
{
|
||||
if (profile == _profile)
|
||||
{
|
||||
auto controlSettings = _control.Settings().as<TerminalSettings>();
|
||||
// Update the parent of the control's settings object (and not the object itself) so
|
||||
// that any overrides made by the control don't get affected by the reload
|
||||
_control.Settings().as<TerminalSettings>().SetParent(settings.DefaultSettings());
|
||||
if (settings.UnfocusedSettings())
|
||||
controlSettings.SetParent(settings.DefaultSettings());
|
||||
auto unfocusedSettings{ settings.UnfocusedSettings() };
|
||||
if (unfocusedSettings)
|
||||
{
|
||||
// Update the control's unfocused appearance, and make sure to maintain the parentage
|
||||
_control.UnfocusedAppearance(settings.UnfocusedSettings());
|
||||
_control.UnfocusedAppearance().as<TerminalSettings>().SetParent(_control.Settings().as<TerminalSettings>());
|
||||
}
|
||||
else
|
||||
{
|
||||
_control.UnfocusedAppearance(nullptr);
|
||||
// Note: the unfocused settings needs to be entirely unchanged _except_ we need to
|
||||
// set its parent to the settings object that lives in the control. This is because
|
||||
// the overrides made by the control live in that settings object, so we want to make
|
||||
// sure the unfocused settings inherit from that.
|
||||
unfocusedSettings.SetParent(controlSettings);
|
||||
}
|
||||
_control.UnfocusedAppearance(unfocusedSettings);
|
||||
_control.UpdateSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
void ClearActive();
|
||||
void SetActive();
|
||||
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsStruct& settings,
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||
const GUID& profile);
|
||||
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
|
||||
void Relayout();
|
||||
@@ -120,8 +120,6 @@ private:
|
||||
|
||||
Borders _borders{ Borders::None };
|
||||
|
||||
std::atomic<bool> _isClosing{ false };
|
||||
|
||||
bool _zoomed{ false };
|
||||
|
||||
bool _IsLeaf() const noexcept;
|
||||
|
||||
@@ -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.
|
||||
-->
|
||||
@@ -308,6 +308,9 @@
|
||||
<data name="CmdSplitPaneVerticalArgDesc" xml:space="preserve">
|
||||
<value>Create the new pane as a vertical split (think [|])</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDuplicateArgDesc" xml:space="preserve">
|
||||
<value>Create the new pane by duplicating the profile of the focused pane</value>
|
||||
</data>
|
||||
<data name="CmdStartingDirArgDesc" xml:space="preserve">
|
||||
<value>Open in the given directory instead of the profile's set "startingDirectory"</value>
|
||||
<comment>{Locked="\"startingDirectory\""}</comment>
|
||||
@@ -323,6 +326,10 @@
|
||||
<value>Open the tab with tabTitle overriding default title and suppressing title change messages from the application</value>
|
||||
<comment>{Locked="\"tabTitle\""}</comment>
|
||||
</data>
|
||||
<data name="CmdColorSchemeArgDesc" xml:space="preserve">
|
||||
<value>Open the tab with the specified color scheme, instead of the profile's set "colorScheme"</value>
|
||||
<comment>{Locked="\"colorScheme\""}</comment>
|
||||
</data>
|
||||
<data name="CmdVersionDesc" xml:space="preserve">
|
||||
<value>Display the application version</value>
|
||||
</data>
|
||||
@@ -588,10 +595,33 @@
|
||||
<data name="CommandPalette_MoreOptions.[using:Windows.UI.Xaml.Automation]AutomationProperties.HelpText" xml:space="preserve">
|
||||
<value>More options</value>
|
||||
</data>
|
||||
<data name="WindowIdLabel" xml:space="preserve">
|
||||
<value>Window</value>
|
||||
<comment>This is displayed as a label for a number, like "Window: 10"</comment>
|
||||
</data>
|
||||
<data name="UnnamedWindowName" xml:space="preserve">
|
||||
<value>unnamed window</value>
|
||||
<comment>text used to identify when a window hasn't been assigned a name by the user</comment>
|
||||
</data>
|
||||
<data name="WindowRenamer.Subtitle" xml:space="preserve">
|
||||
<value>Enter a new name:</value>
|
||||
</data>
|
||||
<data name="WindowRenamer.ActionButtonContent" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name="WindowRenamer.CloseButtonContent" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="RenameFailedToast.Title" xml:space="preserve">
|
||||
<value>Failed to rename window</value>
|
||||
</data>
|
||||
<data name="RenameFailedToast.Subtitle" xml:space="preserve">
|
||||
<value>Another window with that name already exists</value>
|
||||
</data>
|
||||
<data name="WindowMaximizeButtonToolTip" xml:space="preserve">
|
||||
<value>Maximize</value>
|
||||
</data>
|
||||
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
|
||||
<value>Restore Down</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
@@ -10,6 +10,13 @@ using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
#define ACTION_CASE(action) \
|
||||
case ShortcutAction::action: \
|
||||
{ \
|
||||
_##action##Handlers(*this, eventArgs); \
|
||||
break; \
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Method Description:
|
||||
@@ -34,242 +41,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ShortcutAction::CopyText:
|
||||
{
|
||||
_CopyTextHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::PasteText:
|
||||
{
|
||||
_PasteTextHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenNewTabDropdown:
|
||||
{
|
||||
_OpenNewTabDropdownHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::DuplicateTab:
|
||||
{
|
||||
_DuplicateTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenSettings:
|
||||
{
|
||||
_OpenSettingsHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::NewTab:
|
||||
{
|
||||
_NewTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseWindow:
|
||||
{
|
||||
_CloseWindowHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseTab:
|
||||
{
|
||||
_CloseTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ClosePane:
|
||||
{
|
||||
_ClosePaneHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::ScrollUp:
|
||||
{
|
||||
_ScrollUpHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollDown:
|
||||
{
|
||||
_ScrollDownHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollUpPage:
|
||||
{
|
||||
_ScrollUpPageHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollDownPage:
|
||||
{
|
||||
_ScrollDownPageHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollToTop:
|
||||
{
|
||||
_ScrollToTopHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ScrollToBottom:
|
||||
{
|
||||
_ScrollToBottomHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::NextTab:
|
||||
{
|
||||
_NextTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::PrevTab:
|
||||
{
|
||||
_PrevTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::SendInput:
|
||||
{
|
||||
_SendInputHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::SplitVertical:
|
||||
case ShortcutAction::SplitHorizontal:
|
||||
case ShortcutAction::SplitPane:
|
||||
{
|
||||
_SplitPaneHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::TogglePaneZoom:
|
||||
{
|
||||
_TogglePaneZoomHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::SwitchToTab:
|
||||
{
|
||||
_SwitchToTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::ResizePane:
|
||||
{
|
||||
_ResizePaneHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::MoveFocus:
|
||||
{
|
||||
_MoveFocusHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShortcutAction::AdjustFontSize:
|
||||
{
|
||||
_AdjustFontSizeHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::Find:
|
||||
{
|
||||
_FindHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ResetFontSize:
|
||||
{
|
||||
_ResetFontSizeHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleShaderEffects:
|
||||
{
|
||||
_ToggleShaderEffectsHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleFocusMode:
|
||||
{
|
||||
_ToggleFocusModeHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleFullscreen:
|
||||
{
|
||||
_ToggleFullscreenHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleAlwaysOnTop:
|
||||
{
|
||||
_ToggleAlwaysOnTopHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ToggleCommandPalette:
|
||||
{
|
||||
_ToggleCommandPaletteHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::SetColorScheme:
|
||||
{
|
||||
_SetColorSchemeHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::SetTabColor:
|
||||
{
|
||||
_SetTabColorHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenTabColorPicker:
|
||||
{
|
||||
_OpenTabColorPickerHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::RenameTab:
|
||||
{
|
||||
_RenameTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::OpenTabRenamer:
|
||||
{
|
||||
_OpenTabRenamerHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::ExecuteCommandline:
|
||||
{
|
||||
_ExecuteCommandlineHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseOtherTabs:
|
||||
{
|
||||
_CloseOtherTabsHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::CloseTabsAfter:
|
||||
{
|
||||
_CloseTabsAfterHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::MoveTab:
|
||||
{
|
||||
_MoveTabHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::TabSearch:
|
||||
{
|
||||
_TabSearchHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::BreakIntoDebugger:
|
||||
{
|
||||
_BreakIntoDebuggerHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::FindMatch:
|
||||
{
|
||||
_FindMatchHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::TogglePaneReadOnly:
|
||||
{
|
||||
_TogglePaneReadOnlyHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
case ShortcutAction::NewWindow:
|
||||
{
|
||||
_NewWindowHandlers(*this, eventArgs);
|
||||
break;
|
||||
}
|
||||
#define ON_ALL_ACTIONS(id) ACTION_CASE(id);
|
||||
ALL_SHORTCUT_ACTIONS
|
||||
#undef ON_ALL_ACTIONS
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "ShortcutActionDispatch.g.h"
|
||||
#include "../inc/cppwinrt_utils.h"
|
||||
#include "../TerminalSettingsModel/AllShortcutActions.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
@@ -13,6 +14,8 @@ namespace TerminalAppLocalTests
|
||||
class KeyBindingsTests;
|
||||
}
|
||||
|
||||
#define DECLARE_ACTION(action) TYPED_EVENT(action, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct ShortcutActionDispatch : ShortcutActionDispatchT<ShortcutActionDispatch>
|
||||
@@ -21,53 +24,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool DoAction(const Microsoft::Terminal::Settings::Model::ActionAndArgs& actionAndArgs);
|
||||
|
||||
// clang-format off
|
||||
TYPED_EVENT(CopyText, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(PasteText, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(OpenNewTabDropdown, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(DuplicateTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(NewTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(CloseWindow, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(CloseTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ClosePane, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(SwitchToTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(NextTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(PrevTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(SendInput, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(SplitPane, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(TogglePaneZoom, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(AdjustFontSize, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ResetFontSize, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ScrollUp, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ScrollDown, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ScrollUpPage, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ScrollDownPage, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ScrollToTop, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ScrollToBottom, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(OpenSettings, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ResizePane, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(Find, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(MoveFocus, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleShaderEffects, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleFocusMode, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleFullscreen, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleAlwaysOnTop, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ToggleCommandPalette, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(SetColorScheme, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(SetTabColor, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(OpenTabColorPicker, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(RenameTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(OpenTabRenamer, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(ExecuteCommandline, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(CloseOtherTabs, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(CloseTabsAfter, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(TabSearch, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(MoveTab, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(BreakIntoDebugger, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(FindMatch, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(TogglePaneReadOnly, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
TYPED_EVENT(NewWindow, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs);
|
||||
// clang-format on
|
||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION(action);
|
||||
ALL_SHORTCUT_ACTIONS
|
||||
#undef ON_ALL_ACTIONS
|
||||
|
||||
private:
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
#include "../TerminalSettingsModel/AllShortcutActions.h"
|
||||
|
||||
#define ACTION_EVENT(name) event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> name
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
@@ -8,50 +11,10 @@ namespace TerminalApp
|
||||
|
||||
Boolean DoAction(Microsoft.Terminal.Settings.Model.ActionAndArgs actionAndArgs);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> CopyText;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> PasteText;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> NewTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> OpenNewTabDropdown;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> DuplicateTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> CloseWindow;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> CloseTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ClosePane;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> SwitchToTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> NextTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> PrevTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> SendInput;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> SplitPane;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> TogglePaneZoom;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> AdjustFontSize;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ResetFontSize;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ScrollUp;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ScrollDown;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ScrollUpPage;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ScrollDownPage;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ScrollToTop;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ScrollToBottom;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> OpenSettings;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ResizePane;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> Find;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> MoveFocus;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ToggleShaderEffects;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ToggleFocusMode;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ToggleFullscreen;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ToggleAlwaysOnTop;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ToggleCommandPalette;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> SetColorScheme;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> SetTabColor;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> OpenTabColorPicker;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> RenameTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> OpenTabRenamer;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> ExecuteCommandline;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> CloseOtherTabs;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> CloseTabsAfter;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> TabSearch;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> MoveTab;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> BreakIntoDebugger;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> FindMatch;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> TogglePaneReadOnly;
|
||||
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, Microsoft.Terminal.Settings.Model.ActionEventArgs> NewWindow;
|
||||
// When adding a new action, add them to AllShortcutActions.h!
|
||||
#define ON_ALL_ACTIONS(action) ACTION_EVENT(action);
|
||||
ALL_SHORTCUT_ACTIONS
|
||||
#undef ON_ALL_ACTIONS
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace winrt::TerminalApp::implementation
|
||||
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_ClosedHandlers(nullptr, nullptr);
|
||||
tab->_CloseRequestedHandlers(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
closeTabMenuItem.Text(RS_(L"TabClose"));
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void SetKeyMap(const Microsoft::Terminal::Settings::Model::KeyMapping& keymap);
|
||||
|
||||
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
||||
WINRT_CALLBACK(CloseRequested, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
|
||||
@@ -18,8 +18,18 @@ namespace winrt::TerminalApp::implementation
|
||||
// We'll only process the KeyUp event if we received an initial KeyDown event first.
|
||||
// Avoids issue immediately closing the tab rename when we see the enter KeyUp event that was
|
||||
// sent to the command palette to trigger the openTabRenamer action in the first place.
|
||||
HeaderRenamerTextBox().KeyDown([&](auto&&, auto&&) {
|
||||
HeaderRenamerTextBox().KeyDown([&](auto&&, auto&& e) {
|
||||
_receivedKeyDown = true;
|
||||
|
||||
// GH#9632 - mark navigation buttons as handled.
|
||||
// This should prevent the tab view to use this key for navigation between tabs
|
||||
if (e.OriginalKey() == Windows::System::VirtualKey::Down ||
|
||||
e.OriginalKey() == Windows::System::VirtualKey::Up ||
|
||||
e.OriginalKey() == Windows::System::VirtualKey::Left ||
|
||||
e.OriginalKey() == Windows::System::VirtualKey::Right)
|
||||
{
|
||||
e.Handled(true);
|
||||
}
|
||||
});
|
||||
|
||||
// NOTE: (Preview)KeyDown does not work here. If you use that, we'll
|
||||
|
||||
@@ -1,78 +1,81 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
|
||||
<UserControl
|
||||
x:Class="TerminalApp.TabHeaderControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
MinHeight="16">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,1</Thickness>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,1</Thickness>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,1</Thickness>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel x:Name="HeaderStackPanel"
|
||||
Orientation="Horizontal">
|
||||
<mux:ProgressRing x:Name="HeaderProgressRing"
|
||||
IsActive="{x:Bind TabStatus.IsProgressRingActive, Mode=OneWay}"
|
||||
Visibility="{x:Bind TabStatus.IsProgressRingActive, Mode=OneWay}"
|
||||
IsIndeterminate="{x:Bind TabStatus.IsProgressRingIndeterminate, Mode=OneWay}"
|
||||
Value="{x:Bind TabStatus.ProgressValue, Mode=OneWay}"
|
||||
MinHeight="0"
|
||||
MinWidth="0"
|
||||
Height="15"
|
||||
Width="15"
|
||||
Margin="-7.5,0,8,0"/>
|
||||
<!--We want the progress ring to 'replace' the tab icon, but we don't have control
|
||||
over the tab icon here (the tab view item does) - so we hide the tab icon there
|
||||
and use a negative margin for the progress ring here to put it where the icon would be-->
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
|
||||
<UserControl x:Class="TerminalApp.TabHeaderControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
MinHeight="16"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,1</Thickness>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,1</Thickness>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,1</Thickness>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel x:Name="HeaderStackPanel"
|
||||
Orientation="Horizontal">
|
||||
<mux:ProgressRing x:Name="HeaderProgressRing"
|
||||
Width="15"
|
||||
Height="15"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Margin="-7.5,0,8,0"
|
||||
IsActive="{x:Bind TabStatus.IsProgressRingActive, Mode=OneWay}"
|
||||
IsIndeterminate="{x:Bind TabStatus.IsProgressRingIndeterminate, Mode=OneWay}"
|
||||
Visibility="{x:Bind TabStatus.IsProgressRingActive, Mode=OneWay}"
|
||||
Value="{x:Bind TabStatus.ProgressValue, Mode=OneWay}" />
|
||||
<!--
|
||||
We want the progress ring to 'replace' the tab icon, but we don't have control
|
||||
over the tab icon here (the tab view item does) - so we hide the tab icon there
|
||||
and use a negative margin for the progress ring here to put it where the icon would be
|
||||
-->
|
||||
<FontIcon x:Name="HeaderBellIndicator"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}"
|
||||
Glyph=""
|
||||
FontSize="12"
|
||||
Margin="0,0,8,0"/>
|
||||
<FontIcon x:Name="HeaderZoomIcon"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Visibility="{x:Bind TabStatus.IsPaneZoomed, Mode=OneWay}"
|
||||
Glyph=""
|
||||
FontSize="12"
|
||||
Margin="0,0,8,0"/>
|
||||
<FontIcon x:Name="HeaderLockIcon"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Visibility="{x:Bind TabStatus.IsReadOnlyActive, Mode=OneWay}"
|
||||
Glyph=""
|
||||
FontSize="12"
|
||||
Margin="0,0,8,0"/>
|
||||
<TextBlock x:Name="HeaderTextBlock"
|
||||
Visibility="Visible"
|
||||
Text="{x:Bind Title, Mode=OneWay}"/>
|
||||
<TextBox x:Name="HeaderRenamerTextBox"
|
||||
Visibility="Collapsed"
|
||||
MinHeight="0"
|
||||
Padding="4,0,4,0"
|
||||
MaxLength="1024"
|
||||
LostFocus="RenameBoxLostFocusHandler"
|
||||
Height="16"
|
||||
FontSize="12"
|
||||
IsSpellCheckEnabled="False"
|
||||
MaxWidth="{x:Bind RenamerMaxWidth, Mode=OneWay}"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderZoomIcon"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.IsPaneZoomed, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderLockIcon"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.IsReadOnlyActive, Mode=OneWay}" />
|
||||
<TextBlock x:Name="HeaderTextBlock"
|
||||
Text="{x:Bind Title, Mode=OneWay}"
|
||||
Visibility="Visible" />
|
||||
<TextBox x:Name="HeaderRenamerTextBox"
|
||||
Height="16"
|
||||
MinHeight="0"
|
||||
MaxWidth="{x:Bind RenamerMaxWidth, Mode=OneWay}"
|
||||
Padding="4,0,4,0"
|
||||
FontSize="12"
|
||||
IsSpellCheckEnabled="False"
|
||||
LostFocus="RenameBoxLostFocusHandler"
|
||||
MaxLength="1024"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
920
src/cascadia/TerminalApp/TabManagement.cpp
Normal file
920
src/cascadia/TerminalApp/TabManagement.cpp
Normal file
@@ -0,0 +1,920 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// This file contains much of the code related to tab management for the
|
||||
// TerminalPage. Things like opening new tabs, selecting different tabs,
|
||||
// switching tabs, should all be handled in this file. Hypothetically, in the
|
||||
// future, the contents of this file could be moved to a separate class
|
||||
// entirely.
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalPage.h"
|
||||
#include "Utils.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "TabRowControl.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "SettingsTab.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
||||
using namespace winrt::Windows::UI::Text;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::TerminalApp;
|
||||
using namespace ::Microsoft::Console;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
using IInspectable = Windows::Foundation::IInspectable;
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Method Description:
|
||||
// - Open a new tab. This will create the TerminalControl hosting the
|
||||
// terminal, and add a new Tab to our list of tabs. The method can
|
||||
// optionally be provided a NewTerminalArgs, which will be used to create
|
||||
// a tab using the values in that object.
|
||||
// Arguments:
|
||||
// - newTerminalArgs: An object that may contain a blob of parameters to
|
||||
// control which profile is created and with possible other
|
||||
// configurations. See TerminalSettings::CreateWithNewTerminalArgs for more details.
|
||||
// - existingConnection: An optional connection that is already established to a PTY
|
||||
// for this tab to host instead of creating one.
|
||||
// If not defined, the tab will create the connection.
|
||||
void TerminalPage::_OpenNewTab(const NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection)
|
||||
try
|
||||
{
|
||||
const auto profileGuid{ _settings.GetProfileForArgs(newTerminalArgs) };
|
||||
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
|
||||
|
||||
_CreateNewTabFromSettings(profileGuid, settings, existingConnection);
|
||||
|
||||
const uint32_t tabCount = _tabs.Size();
|
||||
const bool usedManualProfile = (newTerminalArgs != nullptr) &&
|
||||
(newTerminalArgs.ProfileIndex() != nullptr ||
|
||||
newTerminalArgs.Profile().empty());
|
||||
|
||||
// Lookup the name of the color scheme used by this profile.
|
||||
const auto scheme = _settings.GetColorSchemeForProfile(profileGuid);
|
||||
// If they explicitly specified `null` as the scheme (indicating _no_ scheme), log
|
||||
// that as the empty string.
|
||||
const auto schemeName = scheme ? scheme.Name() : L"\0";
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||
"TabInformation",
|
||||
TraceLoggingDescription("Event emitted upon new tab creation in TerminalApp"),
|
||||
TraceLoggingUInt32(1u, "EventVer", "Version of this event"),
|
||||
TraceLoggingUInt32(tabCount, "TabCount", "Count of tabs currently opened in TerminalApp"),
|
||||
TraceLoggingBool(usedManualProfile, "ProfileSpecified", "Whether the new tab specified a profile explicitly"),
|
||||
TraceLoggingGuid(profileGuid, "ProfileGuid", "The GUID of the profile spawned in the new tab"),
|
||||
TraceLoggingBool(settings.DefaultSettings().UseAcrylic(), "UseAcrylic", "The acrylic preference from the settings"),
|
||||
TraceLoggingFloat64(settings.DefaultSettings().TintOpacity(), "TintOpacity", "Opacity preference from the settings"),
|
||||
TraceLoggingWideString(settings.DefaultSettings().FontFace().c_str(), "FontFace", "Font face chosen in the settings"),
|
||||
TraceLoggingWideString(schemeName.data(), "SchemeName", "Color scheme set in the settings"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// Method Description:
|
||||
// - Creates a new tab with the given settings. If the tab bar is not being
|
||||
// currently displayed, it will be shown.
|
||||
// Arguments:
|
||||
// - profileGuid: ID to use to lookup profile settings for this connection
|
||||
// - settings: the TerminalSettings object to use to create the TerminalControl with.
|
||||
// - existingConnection: optionally receives a connection from the outside world instead of attempting to create one
|
||||
void TerminalPage::_CreateNewTabFromSettings(GUID profileGuid, const TerminalSettingsCreateResult& settings, TerminalConnection::ITerminalConnection existingConnection)
|
||||
{
|
||||
// Initialize the new tab
|
||||
// Create a connection based on the values in our settings object if we weren't given one.
|
||||
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profileGuid, settings.DefaultSettings());
|
||||
|
||||
TerminalConnection::ITerminalConnection debugConnection{ nullptr };
|
||||
if (_settings.GlobalSettings().DebugFeaturesEnabled())
|
||||
{
|
||||
const CoreWindow window = CoreWindow::GetForCurrentThread();
|
||||
const auto rAltState = window.GetKeyState(VirtualKey::RightMenu);
|
||||
const auto lAltState = window.GetKeyState(VirtualKey::LeftMenu);
|
||||
const bool bothAltsPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) &&
|
||||
WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down);
|
||||
if (bothAltsPressed)
|
||||
{
|
||||
std::tie(connection, debugConnection) = OpenDebugTapConnection(connection);
|
||||
}
|
||||
}
|
||||
|
||||
// Give term control a child of the settings so that any overrides go in the child
|
||||
// This way, when we do a settings reload we just update the parent and the overrides remain
|
||||
auto term = _InitControl(settings, connection);
|
||||
|
||||
auto newTabImpl = winrt::make_self<TerminalTab>(profileGuid, term);
|
||||
|
||||
// Add the new tab to the list of our tabs.
|
||||
_tabs.Append(*newTabImpl);
|
||||
_mruTabs.Append(*newTabImpl);
|
||||
|
||||
newTabImpl->SetDispatch(*_actionDispatch);
|
||||
newTabImpl->SetKeyMap(_settings.KeyMap());
|
||||
|
||||
// Give the tab its index in the _tabs vector so it can manage its own SwitchToTab command.
|
||||
_UpdateTabIndices();
|
||||
|
||||
// Hookup our event handlers to the new terminal
|
||||
_RegisterTerminalEvents(term, *newTabImpl);
|
||||
|
||||
// Don't capture a strong ref to the tab. If the tab is removed as this
|
||||
// is called, we don't really care anymore about handling the event.
|
||||
auto weakTab = make_weak(newTabImpl);
|
||||
|
||||
// When the tab's active pane changes, we'll want to lookup a new icon
|
||||
// for it. The Title change will be propagated upwards through the tab's
|
||||
// PropertyChanged event handler.
|
||||
newTabImpl->ActivePaneChanged([weakTab, weakThis{ get_weak() }]() {
|
||||
auto page{ weakThis.get() };
|
||||
auto tab{ weakTab.get() };
|
||||
|
||||
if (page && tab)
|
||||
{
|
||||
// Possibly update the icon of the tab.
|
||||
page->_UpdateTabIcon(*tab);
|
||||
}
|
||||
});
|
||||
|
||||
// The RaiseVisualBell event has been bubbled up to here from the pane,
|
||||
// the next part of the chain is bubbling up to app logic, which will
|
||||
// forward it to app host.
|
||||
newTabImpl->TabRaiseVisualBell([weakTab, weakThis{ get_weak() }]() {
|
||||
auto page{ weakThis.get() };
|
||||
auto tab{ weakTab.get() };
|
||||
|
||||
if (page && tab)
|
||||
{
|
||||
page->_RaiseVisualBellHandlers(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
newTabImpl->DuplicateRequested([weakTab, weakThis{ get_weak() }]() {
|
||||
auto page{ weakThis.get() };
|
||||
auto tab{ weakTab.get() };
|
||||
|
||||
if (page && tab)
|
||||
{
|
||||
page->_DuplicateTab(*tab);
|
||||
}
|
||||
});
|
||||
|
||||
auto tabViewItem = newTabImpl->TabViewItem();
|
||||
_tabView.TabItems().Append(tabViewItem);
|
||||
|
||||
// Set this tab's icon to the icon from the user's profile
|
||||
const auto profile = _settings.FindProfile(profileGuid);
|
||||
if (profile != nullptr && !profile.Icon().empty())
|
||||
{
|
||||
newTabImpl->UpdateIcon(profile.Icon());
|
||||
}
|
||||
|
||||
tabViewItem.PointerPressed({ this, &TerminalPage::_OnTabClick });
|
||||
|
||||
// When the tab requests close, try to close it (prompt for approval, if required)
|
||||
newTabImpl->CloseRequested([weakTab, weakThis{ get_weak() }](auto&& /*s*/, auto&& /*e*/) {
|
||||
auto page{ weakThis.get() };
|
||||
auto tab{ weakTab.get() };
|
||||
|
||||
if (page && tab)
|
||||
{
|
||||
page->_HandleCloseTabRequested(*tab);
|
||||
}
|
||||
});
|
||||
|
||||
// When the tab is closed, remove it from our list of tabs.
|
||||
newTabImpl->Closed([tabViewItem, weakThis{ get_weak() }](auto&& /*s*/, auto&& /*e*/) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_RemoveOnCloseRoutine(tabViewItem, page);
|
||||
}
|
||||
});
|
||||
|
||||
newTabImpl->TabRenamerDeactivated([weakThis{ get_weak() }](auto&& /*s*/, auto&& /*e*/) {
|
||||
if (const auto page{ weakThis.get() })
|
||||
{
|
||||
page->_FocusCurrentTab(false);
|
||||
}
|
||||
});
|
||||
|
||||
if (debugConnection) // this will only be set if global debugging is on and tap is active
|
||||
{
|
||||
auto newControl = _InitControl(settings, debugConnection);
|
||||
_RegisterTerminalEvents(newControl, *newTabImpl);
|
||||
// Split (auto) with the debug tap.
|
||||
newTabImpl->SplitPane(SplitState::Automatic, 0.5f, profileGuid, newControl);
|
||||
}
|
||||
|
||||
// This kicks off TabView::SelectionChanged, in response to which
|
||||
// we'll attach the terminal's Xaml control to the Xaml root.
|
||||
_tabView.SelectedItem(tabViewItem);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the icon of the currently focused terminal control, and set its
|
||||
// tab's icon to that icon.
|
||||
// Arguments:
|
||||
// - tab: the Tab to update the title for.
|
||||
void TerminalPage::_UpdateTabIcon(TerminalTab& tab)
|
||||
{
|
||||
const auto lastFocusedProfileOpt = tab.GetFocusedProfile();
|
||||
if (lastFocusedProfileOpt.has_value())
|
||||
{
|
||||
const auto lastFocusedProfile = lastFocusedProfileOpt.value();
|
||||
const auto matchingProfile = _settings.FindProfile(lastFocusedProfile);
|
||||
if (matchingProfile)
|
||||
{
|
||||
tab.UpdateIcon(matchingProfile.Icon());
|
||||
}
|
||||
else
|
||||
{
|
||||
tab.UpdateIcon({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handle changes to the tab width set by the user
|
||||
void TerminalPage::_UpdateTabWidthMode()
|
||||
{
|
||||
_tabView.TabWidthMode(_settings.GlobalSettings().TabWidthMode());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handle changes in tab layout.
|
||||
void TerminalPage::_UpdateTabView()
|
||||
{
|
||||
// Never show the tab row when we're fullscreen. Otherwise:
|
||||
// Show tabs when there's more than 1, or the user has chosen to always
|
||||
// show the tab bar.
|
||||
const bool isVisible = (!_isFullscreen && !_isInFocusMode) &&
|
||||
(_settings.GlobalSettings().ShowTabsInTitlebar() ||
|
||||
(_tabs.Size() > 1) ||
|
||||
_settings.GlobalSettings().AlwaysShowTabs());
|
||||
|
||||
// collapse/show the tabs themselves
|
||||
_tabView.Visibility(isVisible ? Visibility::Visible : Visibility::Collapsed);
|
||||
|
||||
// collapse/show the row that the tabs are in.
|
||||
// NaN is the special value XAML uses for "Auto" sizing.
|
||||
_tabRow.Height(isVisible ? NAN : 0);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Duplicates the current focused tab
|
||||
void TerminalPage::_DuplicateFocusedTab()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_DuplicateTab(*terminalTab);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Duplicates specified tab
|
||||
// Arguments:
|
||||
// - tab: tab to duplicate
|
||||
void TerminalPage::_DuplicateTab(const TerminalTab& tab)
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: GH#5047 - In the future, we should get the Profile of
|
||||
// the focused pane, and use that to build a new instance of the
|
||||
// settings so we can duplicate this tab/pane.
|
||||
//
|
||||
// Currently, if the profile doesn't exist anymore in our
|
||||
// settings, we'll silently do nothing.
|
||||
//
|
||||
// In the future, it will be preferable to just duplicate the
|
||||
// current control's settings, but we can't do that currently,
|
||||
// because we won't be able to create a new instance of the
|
||||
// connection without keeping an instance of the original Profile
|
||||
// object around.
|
||||
|
||||
const auto& profileGuid = tab.GetFocusedProfile();
|
||||
if (profileGuid.has_value())
|
||||
{
|
||||
const auto settingsCreateResult{ TerminalSettings::CreateWithProfileByID(_settings, profileGuid.value(), *_bindings) };
|
||||
const auto workingDirectory = tab.GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto validWorkingDirectory = !workingDirectory.empty();
|
||||
if (validWorkingDirectory)
|
||||
{
|
||||
settingsCreateResult.DefaultSettings().StartingDirectory(workingDirectory);
|
||||
}
|
||||
|
||||
_CreateNewTabFromSettings(profileGuid.value(), settingsCreateResult);
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::TabBase tab)
|
||||
{
|
||||
if (tab.ReadOnly())
|
||||
{
|
||||
ContentDialogResult warningResult = co_await _ShowCloseReadOnlyDialog();
|
||||
|
||||
// If the user didn't explicitly click on close tab - leave
|
||||
if (warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
_RemoveTab(tab);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Removes the tab (both TerminalControl and XAML)
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
void TerminalPage::_RemoveTab(const winrt::TerminalApp::TabBase& tab)
|
||||
{
|
||||
uint32_t tabIndex{};
|
||||
if (!_tabs.IndexOf(tab, tabIndex))
|
||||
{
|
||||
// The tab is already removed
|
||||
return;
|
||||
}
|
||||
|
||||
// We use _removing flag to suppress _OnTabSelectionChanged events
|
||||
// that might get triggered while removing
|
||||
_removing = true;
|
||||
auto unsetRemoving = wil::scope_exit([&]() noexcept { _removing = false; });
|
||||
|
||||
const auto focusedTabIndex{ _GetFocusedTabIndex() };
|
||||
|
||||
// Removing the tab from the collection should destroy its control and disconnect its connection,
|
||||
// but it doesn't always do so. The UI tree may still be holding the control and preventing its destruction.
|
||||
tab.Shutdown();
|
||||
|
||||
uint32_t mruIndex{};
|
||||
if (_mruTabs.IndexOf(tab, mruIndex))
|
||||
{
|
||||
_mruTabs.RemoveAt(mruIndex);
|
||||
}
|
||||
|
||||
_tabs.RemoveAt(tabIndex);
|
||||
_tabView.TabItems().RemoveAt(tabIndex);
|
||||
_UpdateTabIndices();
|
||||
|
||||
// To close the window here, we need to close the hosting window.
|
||||
if (_tabs.Size() == 0)
|
||||
{
|
||||
_LastTabClosedHandlers(*this, nullptr);
|
||||
}
|
||||
else if (focusedTabIndex.has_value() && focusedTabIndex.value() == gsl::narrow_cast<uint32_t>(tabIndex))
|
||||
{
|
||||
// Manually select the new tab to get focus, rather than relying on TabView since:
|
||||
// 1. We want to customize this behavior (e.g., use MRU logic)
|
||||
// 2. In fullscreen (GH#5799) and focus (GH#7916) modes the _OnTabItemsChanged is not fired
|
||||
// 3. When rearranging tabs (GH#7916) _OnTabItemsChanged is suppressed
|
||||
const auto tabSwitchMode = _settings.GlobalSettings().TabSwitcherMode();
|
||||
|
||||
if (tabSwitchMode == TabSwitcherMode::MostRecentlyUsed)
|
||||
{
|
||||
const auto newSelectedTab = _mruTabs.GetAt(0);
|
||||
|
||||
uint32_t newSelectedIndex;
|
||||
if (_tabs.IndexOf(newSelectedTab, newSelectedIndex))
|
||||
{
|
||||
_UpdatedSelectedTab(newSelectedIndex);
|
||||
_tabView.SelectedItem(newSelectedTab.TabViewItem());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We can't use
|
||||
// auto selectedIndex = _tabView.SelectedIndex();
|
||||
// Because this will always return -1 in this scenario unfortunately.
|
||||
//
|
||||
// So, what we're going to try to do is move the focus to the tab
|
||||
// to the left, within the bounds of how many tabs we have.
|
||||
//
|
||||
// EX: we have 4 tabs: [A, B, C, D]. If we close:
|
||||
// * A (tabIndex=0): We'll want to focus tab B (now in index 0)
|
||||
// * B (tabIndex=1): We'll want to focus tab A (now in index 0)
|
||||
// * C (tabIndex=2): We'll want to focus tab B (now in index 1)
|
||||
// * D (tabIndex=3): We'll want to focus tab C (now in index 2)
|
||||
const auto newSelectedIndex = std::clamp<int32_t>(tabIndex - 1, 0, _tabs.Size());
|
||||
// _UpdatedSelectedTab will do the work of setting up the new tab as
|
||||
// the focused one, and unfocusing all the others.
|
||||
_UpdatedSelectedTab(newSelectedIndex);
|
||||
|
||||
// Also, we need to _manually_ set the SelectedItem of the tabView
|
||||
// here. If we don't, then the TabView will technically not have a
|
||||
// selected item at all, which can make things like ClosePane not
|
||||
// work correctly.
|
||||
auto newSelectedTab{ _tabs.GetAt(newSelectedIndex) };
|
||||
_tabView.SelectedItem(newSelectedTab.TabViewItem());
|
||||
}
|
||||
}
|
||||
|
||||
// GH#5559 - If we were in the middle of a drag/drop, end it by clearing
|
||||
// out our state.
|
||||
if (_rearranging)
|
||||
{
|
||||
_rearranging = false;
|
||||
_rearrangeFrom = std::nullopt;
|
||||
_rearrangeTo = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets focus to the tab to the right or left the currently selected tab.
|
||||
void TerminalPage::_SelectNextTab(const bool bMoveRight, const Windows::Foundation::IReference<Microsoft::Terminal::Settings::Model::TabSwitcherMode>& customTabSwitcherMode)
|
||||
{
|
||||
const auto index{ _GetFocusedTabIndex().value_or(0) };
|
||||
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _settings.GlobalSettings().TabSwitcherMode();
|
||||
if (tabSwitchMode == TabSwitcherMode::Disabled)
|
||||
{
|
||||
uint32_t tabCount = _tabs.Size();
|
||||
// Wraparound math. By adding tabCount and then calculating
|
||||
// modulo tabCount, we clamp the values to the range [0,
|
||||
// tabCount) while still supporting moving leftward from 0 to
|
||||
// tabCount - 1.
|
||||
const auto newTabIndex = ((tabCount + index + (bMoveRight ? 1 : -1)) % tabCount);
|
||||
_SelectTab(newTabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandPalette().SetTabs(_tabs, _mruTabs);
|
||||
|
||||
// Otherwise, set up the tab switcher in the selected mode, with
|
||||
// the given ordering, and make it visible.
|
||||
CommandPalette().EnableTabSwitcherMode(index, tabSwitchMode);
|
||||
CommandPalette().Visibility(Visibility::Visible);
|
||||
CommandPalette().SelectNextItem(bMoveRight);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets focus to the desired tab. Returns false if the provided tabIndex
|
||||
// is greater than the number of tabs we have.
|
||||
// - During startup, we'll immediately set the selected tab as focused.
|
||||
// - After startup, we'll dispatch an async method to set the the selected
|
||||
// item of the TabView, which will then also trigger a
|
||||
// TabView::SelectionChanged, handled in
|
||||
// TerminalPage::_OnTabSelectionChanged
|
||||
// Return Value:
|
||||
// true iff we were able to select that tab index, false otherwise
|
||||
bool TerminalPage::_SelectTab(const uint32_t tabIndex)
|
||||
{
|
||||
if (tabIndex >= 0 && tabIndex < _tabs.Size())
|
||||
{
|
||||
if (_startupState == StartupState::InStartup)
|
||||
{
|
||||
auto tab{ _tabs.GetAt(tabIndex) };
|
||||
_tabView.SelectedItem(tab.TabViewItem());
|
||||
_UpdatedSelectedTab(tabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_SetFocusedTabIndex(tabIndex);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This method is called once a tab was selected in tab switcher
|
||||
// We'll use this event to select the relevant tab
|
||||
// Arguments:
|
||||
// - tab - tab to select
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_OnSwitchToTabRequested(const IInspectable& /*sender*/, const winrt::TerminalApp::TabBase& tab)
|
||||
{
|
||||
uint32_t index{};
|
||||
if (_tabs.IndexOf(tab, index))
|
||||
{
|
||||
_SelectTab(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the index in our list of tabs of the currently focused tab. If
|
||||
// no tab is currently selected, returns nullopt.
|
||||
// Return Value:
|
||||
// - the index of the currently focused tab if there is one, else nullopt
|
||||
std::optional<uint32_t> TerminalPage::_GetFocusedTabIndex() const noexcept
|
||||
{
|
||||
// GH#1117: This is a workaround because _tabView.SelectedIndex()
|
||||
// sometimes return incorrect result after removing some tabs
|
||||
uint32_t focusedIndex;
|
||||
if (_tabView.TabItems().IndexOf(_tabView.SelectedItem(), focusedIndex))
|
||||
{
|
||||
return focusedIndex;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - returns the currently focused tab. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::TerminalApp::TabBase TerminalPage::_GetFocusedTab() const noexcept
|
||||
{
|
||||
if (auto index{ _GetFocusedTabIndex() })
|
||||
{
|
||||
return _tabs.GetAt(*index);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - returns a com_ptr to the currently focused tab implementation. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_GetFocusedTabImpl() const noexcept
|
||||
{
|
||||
if (auto tab{ _GetFocusedTab() })
|
||||
{
|
||||
return _GetTerminalTabImpl(tab);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - returns a tab corresponding to a view item. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::TerminalApp::TabBase TerminalPage::_GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept
|
||||
{
|
||||
uint32_t tabIndexFromControl{};
|
||||
if (_tabView.TabItems().IndexOf(tabViewItem, tabIndexFromControl))
|
||||
{
|
||||
// If IndexOf returns true, we've actually got an index
|
||||
return _tabs.GetAt(tabIndexFromControl);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - An async method for changing the focused tab on the UI thread. This
|
||||
// method will _only_ set the selected item of the TabView, which will
|
||||
// then also trigger a TabView::SelectionChanged event, which we'll handle
|
||||
// in TerminalPage::_OnTabSelectionChanged, where we'll mark the new tab
|
||||
// as focused.
|
||||
// Arguments:
|
||||
// - tabIndex: the index in the list of tabs to focus.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TerminalPage::_SetFocusedTabIndex(const uint32_t tabIndex)
|
||||
{
|
||||
// GH#1117: This is a workaround because _tabView.SelectedIndex(tabIndex)
|
||||
// sometimes set focus to an incorrect tab after removing some tabs
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
co_await winrt::resume_foreground(_tabView.Dispatcher());
|
||||
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
auto tabToFocus = page->_tabs.GetAt(tabIndex);
|
||||
_tabView.SelectedItem(tabToFocus.TabViewItem());
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Close the currently focused tab. Focus will move to the left, if possible.
|
||||
void TerminalPage::_CloseFocusedTab()
|
||||
{
|
||||
if (auto index{ _GetFocusedTabIndex() })
|
||||
{
|
||||
auto tab{ _tabs.GetAt(*index) };
|
||||
_HandleCloseTabRequested(tab);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Close the currently focused pane. If the pane is the last pane in the
|
||||
// tab, the tab will also be closed. This will happen when we handle the
|
||||
// tab's Closed event.
|
||||
winrt::fire_and_forget TerminalPage::_CloseFocusedPane()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
|
||||
auto pane = terminalTab->GetActivePane();
|
||||
|
||||
if (const auto pane{ terminalTab->GetActivePane() })
|
||||
{
|
||||
if (const auto control{ pane->GetTerminalControl() })
|
||||
{
|
||||
if (control.ReadOnly())
|
||||
{
|
||||
ContentDialogResult warningResult = co_await _ShowCloseReadOnlyDialog();
|
||||
|
||||
// If the user didn't explicitly click on close tab - leave
|
||||
if (warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Clean read-only mode to prevent additional prompt if closing the pane triggers closing of a hosting tab
|
||||
if (control.ReadOnly())
|
||||
{
|
||||
control.ToggleReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
pane->Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (auto index{ _GetFocusedTabIndex() })
|
||||
{
|
||||
const auto tab{ _tabs.GetAt(*index) };
|
||||
if (tab.try_as<TerminalApp::SettingsTab>())
|
||||
{
|
||||
_HandleCloseTabRequested(tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Closes provided tabs one by one
|
||||
// Arguments:
|
||||
// - tabs - tabs to remove
|
||||
winrt::fire_and_forget TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::TabBase> tabs)
|
||||
{
|
||||
for (auto& tab : tabs)
|
||||
{
|
||||
co_await _HandleCloseTabRequested(tab);
|
||||
}
|
||||
}
|
||||
// Method Description:
|
||||
// - Responds to changes in the TabView's item list by changing the
|
||||
// tabview's visibility.
|
||||
// - This method is also invoked when tabs are dragged / dropped as part of
|
||||
// tab reordering and this method hands that case as well in concert with
|
||||
// TabDragStarting and TabDragCompleted handlers that are set up in
|
||||
// TerminalPage::Create()
|
||||
// Arguments:
|
||||
// - sender: the control that originated this event
|
||||
// - eventArgs: the event's constituent arguments
|
||||
void TerminalPage::_OnTabItemsChanged(const IInspectable& /*sender*/, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs)
|
||||
{
|
||||
if (_rearranging)
|
||||
{
|
||||
if (eventArgs.CollectionChange() == Windows::Foundation::Collections::CollectionChange::ItemRemoved)
|
||||
{
|
||||
_rearrangeFrom = eventArgs.Index();
|
||||
}
|
||||
|
||||
if (eventArgs.CollectionChange() == Windows::Foundation::Collections::CollectionChange::ItemInserted)
|
||||
{
|
||||
_rearrangeTo = eventArgs.Index();
|
||||
}
|
||||
}
|
||||
|
||||
CommandPalette().Visibility(Visibility::Collapsed);
|
||||
_UpdateTabView();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Additional responses to clicking on a TabView's item. Currently, just remove tab with middle click
|
||||
// Arguments:
|
||||
// - sender: the control that originated this event (TabViewItem)
|
||||
// - eventArgs: the event's constituent arguments
|
||||
void TerminalPage::_OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs)
|
||||
{
|
||||
if (eventArgs.GetCurrentPoint(*this).Properties().IsMiddleButtonPressed())
|
||||
{
|
||||
const auto tabViewItem = sender.try_as<MUX::Controls::TabViewItem>();
|
||||
if (auto tab{ _GetTabByTabViewItem(tabViewItem) })
|
||||
{
|
||||
_HandleCloseTabRequested(tab);
|
||||
}
|
||||
eventArgs.Handled(true);
|
||||
}
|
||||
else if (eventArgs.GetCurrentPoint(*this).Properties().IsRightButtonPressed())
|
||||
{
|
||||
eventArgs.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_UpdatedSelectedTab(const int32_t index)
|
||||
{
|
||||
// Unfocus all the tabs.
|
||||
for (auto tab : _tabs)
|
||||
{
|
||||
tab.Focus(FocusState::Unfocused);
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto tab{ _tabs.GetAt(index) };
|
||||
|
||||
_tabContent.Children().Clear();
|
||||
_tabContent.Children().Append(tab.Content());
|
||||
|
||||
// GH#7409: If the tab switcher is open, then we _don't_ want to
|
||||
// automatically focus the new tab here. The tab switcher wants
|
||||
// to be able to "preview" the selected tab as the user tabs
|
||||
// through the menu, but if we toss the focus to the control
|
||||
// here, then the user won't be able to navigate the ATS any
|
||||
// longer.
|
||||
//
|
||||
// When the tab switcher is eventually dismissed, the focus will
|
||||
// get tossed back to the focused terminal control, so we don't
|
||||
// need to worry about focus getting lost.
|
||||
if (CommandPalette().Visibility() != Visibility::Visible)
|
||||
{
|
||||
tab.Focus(FocusState::Programmatic);
|
||||
_UpdateMRUTab(index);
|
||||
}
|
||||
|
||||
tab.TabViewItem().StartBringIntoView();
|
||||
|
||||
// Raise an event that our title changed
|
||||
if (_settings.GlobalSettings().ShowTitleInTitlebar())
|
||||
{
|
||||
_TitleChangedHandlers(*this, tab.Title());
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Responds to the TabView control's Selection Changed event (to move a
|
||||
// new terminal control into focus) when not in in the middle of a tab rearrangement.
|
||||
// Arguments:
|
||||
// - sender: the control that originated this event
|
||||
// - eventArgs: the event's constituent arguments
|
||||
void TerminalPage::_OnTabSelectionChanged(const IInspectable& sender, const WUX::Controls::SelectionChangedEventArgs& /*eventArgs*/)
|
||||
{
|
||||
if (!_rearranging && !_removing)
|
||||
{
|
||||
auto tabView = sender.as<MUX::Controls::TabView>();
|
||||
auto selectedIndex = tabView.SelectedIndex();
|
||||
_UpdatedSelectedTab(selectedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Updates all tabs with their current index in _tabs.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateTabIndices()
|
||||
{
|
||||
const uint32_t size = _tabs.Size();
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto tab{ _tabs.GetAt(i) };
|
||||
auto tabImpl{ winrt::get_self<TabBase>(tab) };
|
||||
tabImpl->UpdateTabViewIndex(i, size);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Bumps the tab in its in-order index up to the top of the mru list.
|
||||
// Arguments:
|
||||
// - index: the in-order index of the tab to bump.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateMRUTab(const uint32_t index)
|
||||
{
|
||||
uint32_t mruIndex;
|
||||
const auto tab = _tabs.GetAt(index);
|
||||
if (_mruTabs.IndexOf(tab, mruIndex))
|
||||
{
|
||||
if (mruIndex > 0)
|
||||
{
|
||||
_mruTabs.RemoveAt(mruIndex);
|
||||
_mruTabs.InsertAt(0, tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the tab to another index in the tabs row (if required).
|
||||
// Arguments:
|
||||
// - currentTabIndex: the current index of the tab to move
|
||||
// - suggestedNewTabIndex: the new index of the tab, might get clamped to fit int the tabs row boundaries
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_TryMoveTab(const uint32_t currentTabIndex, const int32_t suggestedNewTabIndex)
|
||||
{
|
||||
auto newTabIndex = gsl::narrow_cast<uint32_t>(std::clamp<int32_t>(suggestedNewTabIndex, 0, _tabs.Size() - 1));
|
||||
if (currentTabIndex != newTabIndex)
|
||||
{
|
||||
auto tab = _tabs.GetAt(currentTabIndex);
|
||||
auto tabViewItem = tab.TabViewItem();
|
||||
_tabs.RemoveAt(currentTabIndex);
|
||||
_tabs.InsertAt(newTabIndex, tab);
|
||||
_UpdateTabIndices();
|
||||
|
||||
_tabView.TabItems().RemoveAt(currentTabIndex);
|
||||
_tabView.TabItems().InsertAt(newTabIndex, tabViewItem);
|
||||
_tabView.SelectedItem(tabViewItem);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_TabDragStarted(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*eventArgs*/)
|
||||
{
|
||||
_rearranging = true;
|
||||
_rearrangeFrom = std::nullopt;
|
||||
_rearrangeTo = std::nullopt;
|
||||
}
|
||||
|
||||
void TerminalPage::_TabDragCompleted(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*eventArgs*/)
|
||||
{
|
||||
auto& from{ _rearrangeFrom };
|
||||
auto& to{ _rearrangeTo };
|
||||
|
||||
if (from.has_value() && to.has_value() && to != from)
|
||||
{
|
||||
auto& tabs{ _tabs };
|
||||
auto tab = tabs.GetAt(from.value());
|
||||
tabs.RemoveAt(from.value());
|
||||
tabs.InsertAt(to.value(), tab);
|
||||
_UpdateTabIndices();
|
||||
}
|
||||
|
||||
_rearranging = false;
|
||||
from = std::nullopt;
|
||||
to = std::nullopt;
|
||||
}
|
||||
|
||||
void TerminalPage::_DismissTabContextMenus()
|
||||
{
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (tab.TabViewItem().ContextFlyout())
|
||||
{
|
||||
tab.TabViewItem().ContextFlyout().Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_FocusCurrentTab(const bool focusAlways)
|
||||
{
|
||||
// We don't want to set focus on the tab if fly-out is open as it will
|
||||
// be closed TODO GH#5400: consider checking we are not in the opening
|
||||
// state, by hooking both Opening and Open events
|
||||
if (focusAlways || !_newTabButton.Flyout().IsOpen())
|
||||
{
|
||||
// Return focus to the active control
|
||||
if (auto index{ _GetFocusedTabIndex() })
|
||||
{
|
||||
_tabs.GetAt(*index).Focus(FocusState::Programmatic);
|
||||
_UpdateMRUTab(index.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TerminalPage::_HasMultipleTabs() const
|
||||
{
|
||||
return _tabs.Size() > 1;
|
||||
}
|
||||
|
||||
void TerminalPage::_RemoveAllTabs()
|
||||
{
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
std::copy(begin(_tabs), end(_tabs), std::back_inserter(tabsToRemove));
|
||||
_RemoveTabs(tabsToRemove);
|
||||
}
|
||||
|
||||
void TerminalPage::_ResizeTabContent(const winrt::Windows::Foundation::Size& newSize)
|
||||
{
|
||||
for (auto tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab = _GetTerminalTabImpl(tab))
|
||||
{
|
||||
terminalTab->ResizeContent(newSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +1,103 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<ContentPresenter
|
||||
x:Class="TerminalApp.TabRowControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<mux:TabView x:Name="TabView"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsAddTabButtonVisible="false"
|
||||
TabWidthMode="Equal"
|
||||
CanReorderTabs="True"
|
||||
CanDragTabs="True"
|
||||
AllowDropTabs="True">
|
||||
|
||||
<mux:TabView.TabStripFooter>
|
||||
<mux:SplitButton
|
||||
x:Name="NewTabButton"
|
||||
x:Uid="NewTabSplitButton"
|
||||
Click="OnNewTabButtonClick"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Left"
|
||||
Content=""
|
||||
UseLayoutRounding="true"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontWeight="SemiLight"
|
||||
FontSize="12"
|
||||
BorderThickness="0"
|
||||
CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}"
|
||||
AutomationProperties.AccessibilityView="Control">
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<ContentPresenter x:Class="TerminalApp.TabRowControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<mux:TabView x:Name="TabView"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
AllowDropTabs="True"
|
||||
CanDragTabs="True"
|
||||
CanReorderTabs="True"
|
||||
IsAddTabButtonVisible="false"
|
||||
TabWidthMode="Equal">
|
||||
|
||||
<mux:TabView.TabStripFooter>
|
||||
<mux:SplitButton x:Name="NewTabButton"
|
||||
x:Uid="NewTabSplitButton"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Stretch"
|
||||
AutomationProperties.AccessibilityView="Control"
|
||||
BorderThickness="0"
|
||||
Click="OnNewTabButtonClick"
|
||||
Content=""
|
||||
CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
FontWeight="SemiLight"
|
||||
UseLayoutRounding="true">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip Placement="Mouse">
|
||||
<TextBlock IsTextSelectionEnabled="False">
|
||||
<Run x:Uid="NewTabRun"/> <LineBreak/>
|
||||
<Run x:Uid="NewTabRun" /> <LineBreak />
|
||||
<Run x:Uid="NewPaneRun"
|
||||
FontStyle="Italic"/> <LineBreak/>
|
||||
FontStyle="Italic" /> <LineBreak />
|
||||
<Run x:Uid="NewWindowRun"
|
||||
FontStyle="Italic"/>
|
||||
FontStyle="Italic" />
|
||||
</TextBlock>
|
||||
</ToolTip>
|
||||
</ToolTipService.ToolTip>
|
||||
<!-- U+E710 is the fancy plus icon. -->
|
||||
<mux:SplitButton.Resources>
|
||||
<!-- Override the SplitButton* resources to match the tab view's button's styles. -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed" ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver" ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed" ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver" ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="SplitButtonBackground" ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground" ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed" ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed" ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver" ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver" ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</mux:SplitButton.Resources>
|
||||
</mux:SplitButton>
|
||||
</mux:TabView.TabStripFooter>
|
||||
|
||||
</mux:TabView>
|
||||
|
||||
</ContentPresenter>
|
||||
</ToolTipService.ToolTip>
|
||||
<!-- U+E710 is the fancy plus icon. -->
|
||||
<mux:SplitButton.Resources>
|
||||
<!-- Override the SplitButton* resources to match the tab view's button's styles. -->
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="SplitButtonBackground"
|
||||
ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground"
|
||||
ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed"
|
||||
ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed"
|
||||
ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver"
|
||||
ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver"
|
||||
ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<StaticResource x:Key="SplitButtonBackground"
|
||||
ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground"
|
||||
ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed"
|
||||
ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed"
|
||||
ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver"
|
||||
ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver"
|
||||
ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="SplitButtonBackground"
|
||||
ResourceKey="TabViewButtonBackground" />
|
||||
<StaticResource x:Key="SplitButtonForeground"
|
||||
ResourceKey="TabViewButtonForeground" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPressed"
|
||||
ResourceKey="TabViewItemHeaderBackgroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPressed"
|
||||
ResourceKey="TabViewItemHeaderForegroundPressed" />
|
||||
<StaticResource x:Key="SplitButtonBackgroundPointerOver"
|
||||
ResourceKey="TabViewItemHeaderBackgroundPointerOver" />
|
||||
<StaticResource x:Key="SplitButtonForegroundPointerOver"
|
||||
ResourceKey="TabViewItemHeaderForegroundPointerOver" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</mux:SplitButton.Resources>
|
||||
</mux:SplitButton>
|
||||
</mux:TabView.TabStripFooter>
|
||||
|
||||
</mux:TabView>
|
||||
|
||||
</ContentPresenter>
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
<ClInclude Include="AppLogic.h">
|
||||
<DependentUpon>AppLogic.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Toast.h"/>
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
@@ -171,6 +172,10 @@
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TabManagement.cpp">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalTabStatus.cpp">
|
||||
<DependentUpon>TerminalTabStatus.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@@ -221,6 +226,8 @@
|
||||
<DependentUpon>AppLogic.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="Toast.cpp" />
|
||||
|
||||
</ItemGroup>
|
||||
<!-- ========================= idl Files ======================== -->
|
||||
<ItemGroup>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,10 @@
|
||||
#include "TerminalTab.h"
|
||||
#include "AppKeyBindings.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "RenameWindowRequestedArgs.g.h"
|
||||
#include "Toast.h"
|
||||
|
||||
#define DECLARE_ACTION_HANDLER(action) void _Handle##action(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
|
||||
static constexpr uint32_t DefaultRowsToScroll{ 3 };
|
||||
static constexpr std::wstring_view TabletInputServiceKey{ L"TabletInputService" };
|
||||
@@ -32,6 +36,15 @@ namespace winrt::TerminalApp::implementation
|
||||
ScrollDown = 1
|
||||
};
|
||||
|
||||
struct RenameWindowRequestedArgs : RenameWindowRequestedArgsT<RenameWindowRequestedArgs>
|
||||
{
|
||||
WINRT_PROPERTY(winrt::hstring, ProposedName);
|
||||
|
||||
public:
|
||||
RenameWindowRequestedArgs(const winrt::hstring& name) :
|
||||
_ProposedName{ name } {};
|
||||
};
|
||||
|
||||
struct TerminalPage : TerminalPageT<TerminalPage>
|
||||
{
|
||||
public:
|
||||
@@ -66,6 +79,7 @@ namespace winrt::TerminalApp::implementation
|
||||
bool AlwaysOnTop() const;
|
||||
|
||||
void SetStartupActions(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);
|
||||
void SetInboundListener();
|
||||
static std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> ConvertExecuteCommandlineToActions(const Microsoft::Terminal::Settings::Model::ExecuteCommandlineArgs& args);
|
||||
|
||||
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
||||
@@ -77,10 +91,25 @@ namespace winrt::TerminalApp::implementation
|
||||
void ShowKeyboardServiceWarning();
|
||||
winrt::hstring KeyboardServiceDisabledText();
|
||||
|
||||
winrt::fire_and_forget IdentifyWindow();
|
||||
winrt::fire_and_forget RenameFailed();
|
||||
|
||||
winrt::fire_and_forget ProcessStartupActions(Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::ActionAndArgs> actions,
|
||||
const bool initial,
|
||||
const winrt::hstring cwd = L"");
|
||||
|
||||
// Normally, WindowName and WindowId would be
|
||||
// WINRT_OBSERVABLE_PROPERTY's, but we want them to raise
|
||||
// WindowNameForDisplay and WindowIdForDisplay instead
|
||||
winrt::hstring WindowName() const noexcept;
|
||||
void WindowName(const winrt::hstring& value);
|
||||
uint64_t WindowId() const noexcept;
|
||||
void WindowId(const uint64_t& value);
|
||||
winrt::hstring WindowIdForDisplay() const noexcept;
|
||||
winrt::hstring WindowNameForDisplay() const noexcept;
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
TYPED_EVENT(TitleChanged, IInspectable, winrt::hstring);
|
||||
TYPED_EVENT(LastTabClosed, IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
|
||||
@@ -91,6 +120,8 @@ namespace winrt::TerminalApp::implementation
|
||||
TYPED_EVENT(RaiseVisualBell, IInspectable, IInspectable);
|
||||
TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable);
|
||||
TYPED_EVENT(Initialized, IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);
|
||||
TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable);
|
||||
TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs);
|
||||
|
||||
private:
|
||||
friend struct TerminalPageT<TerminalPage>; // for Xaml to bind events
|
||||
@@ -120,6 +151,8 @@ namespace winrt::TerminalApp::implementation
|
||||
bool _isInFocusMode{ false };
|
||||
bool _isFullscreen{ false };
|
||||
bool _isAlwaysOnTop{ false };
|
||||
winrt::hstring _WindowName{};
|
||||
uint64_t _WindowId{ 0 };
|
||||
|
||||
bool _rearranging;
|
||||
std::optional<int> _rearrangeFrom;
|
||||
@@ -138,6 +171,10 @@ namespace winrt::TerminalApp::implementation
|
||||
StartupState _startupState{ StartupState::NotInitialized };
|
||||
|
||||
Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::ActionAndArgs> _startupActions;
|
||||
bool _shouldStartInboundListener{ false };
|
||||
|
||||
std::shared_ptr<Toast> _windowIdToast{ nullptr };
|
||||
std::shared_ptr<Toast> _windowRenameFailedToast{ nullptr };
|
||||
|
||||
void _ShowAboutDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseWarningDialog();
|
||||
@@ -147,9 +184,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _CreateNewTabFlyout();
|
||||
void _OpenNewTabDropdown();
|
||||
void _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs);
|
||||
|
||||
void _CreateNewTabFromSettings(GUID profileGuid, Microsoft::Terminal::Settings::Model::TerminalSettingsStruct settings);
|
||||
void _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
void _CreateNewTabFromSettings(GUID profileGuid, const Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(GUID profileGuid, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
|
||||
|
||||
winrt::fire_and_forget _OpenNewWindow(const bool elevate, const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
|
||||
@@ -177,12 +213,19 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _DuplicateFocusedTab();
|
||||
void _DuplicateTab(const TerminalTab& tab);
|
||||
void _RemoveTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem);
|
||||
winrt::Windows::Foundation::IAsyncAction _RemoveTab(winrt::TerminalApp::TabBase tab);
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::TabBase tab);
|
||||
void _RemoveTab(const winrt::TerminalApp::TabBase& tab);
|
||||
winrt::fire_and_forget _RemoveTabs(const std::vector<winrt::TerminalApp::TabBase> tabs);
|
||||
|
||||
void _RegisterTerminalEvents(Microsoft::Terminal::Control::TermControl term, TerminalTab& hostingTab);
|
||||
|
||||
void _DismissTabContextMenus();
|
||||
void _FocusCurrentTab(const bool focusAlways);
|
||||
bool _HasMultipleTabs() const;
|
||||
void _RemoveAllTabs();
|
||||
void _ResizeTabContent(const winrt::Windows::Foundation::Size& newSize);
|
||||
|
||||
void _SelectNextTab(const bool bMoveRight, const Windows::Foundation::IReference<Microsoft::Terminal::Settings::Model::TabSwitcherMode>& customTabSwitcherMode);
|
||||
bool _SelectTab(const uint32_t tabIndex);
|
||||
void _MoveFocus(const Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
@@ -191,6 +234,7 @@ namespace winrt::TerminalApp::implementation
|
||||
std::optional<uint32_t> _GetFocusedTabIndex() const noexcept;
|
||||
TerminalApp::TabBase _GetFocusedTab() const noexcept;
|
||||
winrt::com_ptr<TerminalTab> _GetFocusedTabImpl() const noexcept;
|
||||
TerminalApp::TabBase _GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept;
|
||||
|
||||
winrt::fire_and_forget _SetFocusedTabIndex(const uint32_t tabIndex);
|
||||
void _CloseFocusedTab();
|
||||
@@ -198,8 +242,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::fire_and_forget _RemoveOnCloseRoutine(Microsoft::UI::Xaml::Controls::TabViewItem tabViewItem, winrt::com_ptr<TerminalPage> page);
|
||||
|
||||
// Todo: add more event implementations here
|
||||
// MSFT:20641986: Add keybindings for New Window
|
||||
void _Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll);
|
||||
|
||||
void _SplitPane(const Microsoft::Terminal::Settings::Model::SplitState splitType,
|
||||
@@ -231,6 +273,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
fire_and_forget _LaunchSettings(const Microsoft::Terminal::Settings::Model::SettingsTarget target);
|
||||
|
||||
void _TabDragStarted(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
void _TabDragCompleted(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
|
||||
void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
|
||||
void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs);
|
||||
void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
|
||||
@@ -245,7 +290,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _Find();
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsStruct& settings,
|
||||
winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
|
||||
|
||||
winrt::fire_and_forget _RefreshUIForSettingsReload();
|
||||
@@ -257,7 +302,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _CompleteInitialization();
|
||||
|
||||
void _CommandPaletteClosed(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||
void _FocusActiveControl(IInspectable sender, IInspectable eventArgs);
|
||||
|
||||
void _UnZoomIfNeeded();
|
||||
|
||||
@@ -283,55 +328,20 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::Command _lastPreviewedCommand{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::TerminalSettings _originalSettings{ nullptr };
|
||||
|
||||
void _OnNewConnection(winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection connection);
|
||||
void _HandleToggleInboundPty(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
|
||||
void _WindowRenamerActionClick(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
void _RequestWindowRename(const winrt::hstring& newName);
|
||||
void _WindowRenamerKeyUp(const IInspectable& sender, winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
|
||||
|
||||
void _UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element);
|
||||
|
||||
#pragma region ActionHandlers
|
||||
// These are all defined in AppActionHandlers.cpp
|
||||
void _HandleOpenNewTabDropdown(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleDuplicateTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleCloseTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleClosePane(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleScrollUp(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleScrollDown(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleNextTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandlePrevTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleSendInput(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleSplitPane(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleTogglePaneZoom(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleScrollUpPage(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleScrollDownPage(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleScrollToTop(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleScrollToBottom(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleOpenSettings(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandlePasteText(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleNewTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleSwitchToTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleResizePane(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleMoveFocus(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleCopyText(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleCloseWindow(const IInspectable&, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleAdjustFontSize(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleFind(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleResetFontSize(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleToggleShaderEffects(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleToggleFocusMode(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleToggleFullscreen(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleToggleAlwaysOnTop(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleSetColorScheme(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleSetTabColor(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleOpenTabColorPicker(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleRenameTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleOpenTabRenamer(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleExecuteCommandline(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleToggleCommandPalette(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleCloseOtherTabs(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleCloseTabsAfter(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleOpenTabSearch(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleMoveTab(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleBreakIntoDebugger(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleFindMatch(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleTogglePaneReadOnly(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
void _HandleNewWindow(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
|
||||
// Make sure to hook new actions up in _RegisterActionCallbacks!
|
||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
||||
ALL_SHORTCUT_ACTIONS
|
||||
#undef ON_ALL_ACTIONS
|
||||
#pragma endregion
|
||||
|
||||
friend class TerminalAppLocalTests::TabTests;
|
||||
|
||||
@@ -5,12 +5,17 @@ namespace TerminalApp
|
||||
{
|
||||
delegate void LastTabClosedEventArgs();
|
||||
|
||||
[default_interface] runtimeclass RenameWindowRequestedArgs
|
||||
{
|
||||
String ProposedName { get; };
|
||||
};
|
||||
|
||||
interface IDialogPresenter
|
||||
{
|
||||
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page
|
||||
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
TerminalPage();
|
||||
|
||||
@@ -22,6 +27,13 @@ namespace TerminalApp
|
||||
Boolean Fullscreen { get; };
|
||||
Boolean AlwaysOnTop { get; };
|
||||
|
||||
void IdentifyWindow();
|
||||
String WindowName;
|
||||
UInt64 WindowId;
|
||||
String WindowNameForDisplay { get; };
|
||||
String WindowIdForDisplay { get; };
|
||||
void RenameFailed();
|
||||
|
||||
// We cannot use the default XAML APIs because we want to make sure
|
||||
// that there's only one application-global dialog visible at a time,
|
||||
// and because of GH#5224.
|
||||
@@ -40,5 +52,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.RoutedEventArgs> Initialized;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,136 +1,150 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<Page
|
||||
x:Class="TerminalApp.TerminalPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid x:Name="Root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<local:TabRowControl x:Name="TabRow" Grid.Row="0" />
|
||||
|
||||
<Grid x:Name="TabContent" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="AboutDialog"
|
||||
x:Uid="AboutDialog"
|
||||
DefaultButton="Close">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock IsTextSelectionEnabled="True">
|
||||
<Run Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
|
||||
<Run x:Uid="AboutDialog_VersionLabel" />
|
||||
<Run Text="{x:Bind ApplicationVersion}" />
|
||||
</TextBlock>
|
||||
<HyperlinkButton
|
||||
x:Uid="AboutDialog_DocumentationLink"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125416" />
|
||||
<HyperlinkButton
|
||||
x:Uid="AboutDialog_ReleaseNotesLink"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125417" />
|
||||
<HyperlinkButton
|
||||
x:Uid="AboutDialog_PrivacyPolicyLink"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125418" />
|
||||
<HyperlinkButton
|
||||
x:Uid="AboutDialog_ThirdPartyNoticesLink"
|
||||
Click="_ThirdPartyNoticesOnClick" />
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="CloseAllDialog"
|
||||
x:Uid="CloseAllDialog"
|
||||
DefaultButton="Primary">
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="CloseReadOnlyDialog"
|
||||
x:Uid="CloseReadOnlyDialog"
|
||||
DefaultButton="Close">
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="MultiLinePasteDialog"
|
||||
x:Uid="MultiLinePasteDialog"
|
||||
DefaultButton="Primary">
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
x:Uid="MultiLineWarningText"
|
||||
TextWrapping="Wrap">
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
x:Uid="ClipboardTextHeader"
|
||||
Margin="0,16,0,0">
|
||||
</TextBlock>
|
||||
<ScrollViewer
|
||||
Margin="0,8,0,0"
|
||||
x:Name="ClipboardContentScrollViewer"
|
||||
MaxHeight="100">
|
||||
<TextBlock
|
||||
x:Name="ClipboardText"
|
||||
TextWrapping="Wrap"
|
||||
FontFamily="Cascadia Mono">
|
||||
</TextBlock>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="LargePasteDialog"
|
||||
x:Uid="LargePasteDialog"
|
||||
DefaultButton="Primary">
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="ControlNoticeDialog"
|
||||
x:Uid="ControlNoticeDialog"
|
||||
DefaultButton="Primary">
|
||||
<TextBlock IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords">
|
||||
<Run x:Name="NoticeMessage"/>
|
||||
</TextBlock>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog
|
||||
x:Load="False"
|
||||
x:Name="CouldNotOpenUriDialog"
|
||||
x:Uid="CouldNotOpenUriDialog"
|
||||
DefaultButton="Primary">
|
||||
<TextBlock IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords">
|
||||
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
||||
<Run
|
||||
x:Name="UnopenedUri"
|
||||
FontFamily="Cascadia Mono">
|
||||
</Run>
|
||||
</TextBlock>
|
||||
</ContentDialog>
|
||||
|
||||
<local:CommandPalette
|
||||
x:Name="CommandPalette"
|
||||
Grid.Row="1"
|
||||
Visibility="Collapsed"
|
||||
PreviewKeyDown ="_KeyDownHandler"
|
||||
VerticalAlignment="Stretch" />
|
||||
|
||||
<mux:InfoBar x:Name="KeyboardWarningInfoBar"
|
||||
x:Load="False"
|
||||
IsClosable="True"
|
||||
IsIconVisible="True"
|
||||
IsOpen="False"
|
||||
Severity="Warning"
|
||||
Message="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}"/>
|
||||
</Grid>
|
||||
</Page>
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<Page x:Class="TerminalApp.TerminalPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid x:Name="Root"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<local:TabRowControl x:Name="TabRow"
|
||||
Grid.Row="0" />
|
||||
|
||||
<Grid x:Name="TabContent"
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" />
|
||||
|
||||
<ContentDialog x:Name="AboutDialog"
|
||||
x:Uid="AboutDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Close">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock IsTextSelectionEnabled="True">
|
||||
<Run Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
|
||||
<Run x:Uid="AboutDialog_VersionLabel" />
|
||||
<Run Text="{x:Bind ApplicationVersion}" />
|
||||
</TextBlock>
|
||||
<HyperlinkButton x:Uid="AboutDialog_DocumentationLink"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125416" />
|
||||
<HyperlinkButton x:Uid="AboutDialog_ReleaseNotesLink"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125417" />
|
||||
<HyperlinkButton x:Uid="AboutDialog_PrivacyPolicyLink"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125418" />
|
||||
<HyperlinkButton x:Uid="AboutDialog_ThirdPartyNoticesLink"
|
||||
Click="_ThirdPartyNoticesOnClick" />
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="CloseAllDialog"
|
||||
x:Uid="CloseAllDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary" />
|
||||
|
||||
<ContentDialog x:Name="CloseReadOnlyDialog"
|
||||
x:Uid="CloseReadOnlyDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Close" />
|
||||
|
||||
<ContentDialog x:Name="MultiLinePasteDialog"
|
||||
x:Uid="MultiLinePasteDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="MultiLineWarningText"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock x:Uid="ClipboardTextHeader"
|
||||
Margin="0,16,0,0" />
|
||||
<ScrollViewer x:Name="ClipboardContentScrollViewer"
|
||||
MaxHeight="100"
|
||||
Margin="0,8,0,0">
|
||||
<TextBlock x:Name="ClipboardText"
|
||||
FontFamily="Cascadia Mono"
|
||||
TextWrapping="Wrap" />
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="LargePasteDialog"
|
||||
x:Uid="LargePasteDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary" />
|
||||
|
||||
<ContentDialog x:Name="ControlNoticeDialog"
|
||||
x:Uid="ControlNoticeDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary">
|
||||
<TextBlock IsTextSelectionEnabled="True"
|
||||
TextWrapping="WrapWholeWords">
|
||||
<Run x:Name="NoticeMessage" />
|
||||
</TextBlock>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="CouldNotOpenUriDialog"
|
||||
x:Uid="CouldNotOpenUriDialog"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary">
|
||||
<TextBlock IsTextSelectionEnabled="True"
|
||||
TextWrapping="WrapWholeWords">
|
||||
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
||||
<Run x:Name="UnopenedUri"
|
||||
FontFamily="Cascadia Mono" />
|
||||
</TextBlock>
|
||||
</ContentDialog>
|
||||
|
||||
<local:CommandPalette x:Name="CommandPalette"
|
||||
Grid.Row="1"
|
||||
VerticalAlignment="Stretch"
|
||||
PreviewKeyDown="_KeyDownHandler"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<mux:InfoBar x:Name="KeyboardWarningInfoBar"
|
||||
x:Load="False"
|
||||
IsClosable="True"
|
||||
IsIconVisible="True"
|
||||
IsOpen="False"
|
||||
Message="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
|
||||
<!--
|
||||
A TeachingTip with IsLightDismissEnabled="True" will immediately
|
||||
dismiss itself if the window is unfocused (In Xaml Islands). This is
|
||||
tracked by MUX#4382
|
||||
-->
|
||||
<mux:TeachingTip x:Name="WindowIdToast"
|
||||
Title="{x:Bind WindowIdForDisplay}"
|
||||
x:Load="False"
|
||||
IsLightDismissEnabled="True"
|
||||
Subtitle="{x:Bind WindowNameForDisplay, Mode=OneWay}" />
|
||||
|
||||
<mux:TeachingTip x:Name="RenameFailedToast"
|
||||
x:Uid="RenameFailedToast"
|
||||
x:Load="False"
|
||||
IsLightDismissEnabled="True" />
|
||||
|
||||
<mux:TeachingTip x:Name="WindowRenamer"
|
||||
x:Uid="WindowRenamer"
|
||||
Title="{x:Bind WindowIdForDisplay}"
|
||||
x:Load="False"
|
||||
ActionButtonClick="_WindowRenamerActionClick"
|
||||
ActionButtonStyle="{ThemeResource AccentButtonStyle}"
|
||||
IsLightDismissEnabled="True">
|
||||
<mux:TeachingTip.Content>
|
||||
<TextBox x:Name="WindowRenamerTextBox"
|
||||
KeyUp="_WindowRenamerKeyUp"
|
||||
Text="{x:Bind WindowName, Mode=OneWay}" />
|
||||
</mux:TeachingTip.Content>
|
||||
</mux:TeachingTip>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@@ -207,11 +207,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - Attempts to update the settings of this tab's tree of panes.
|
||||
// Arguments:
|
||||
// - settings: The new TerminalSettings to apply to any matching controls
|
||||
// - settings: The new TerminalSettingsCreateResult to apply to any matching controls
|
||||
// - profile: The GUID of the profile these settings should apply to.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalTab::UpdateSettings(const TerminalSettingsStruct& settings, const GUID& profile)
|
||||
void TerminalTab::UpdateSettings(const TerminalSettingsCreateResult& settings, const GUID& profile)
|
||||
{
|
||||
_rootPane->UpdateSettings(settings, profile);
|
||||
|
||||
@@ -666,6 +666,11 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_RecalculateAndApplyReadOnly();
|
||||
|
||||
if (const auto control{ pane->GetTerminalControl() })
|
||||
{
|
||||
control.TaskbarProgressChanged();
|
||||
}
|
||||
|
||||
// Raise our own ActivePaneChanged event.
|
||||
_ActivePaneChangedHandlers();
|
||||
}
|
||||
@@ -788,7 +793,7 @@ namespace winrt::TerminalApp::implementation
|
||||
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_ClosedHandlers(nullptr, nullptr);
|
||||
tab->_CloseRequestedHandlers(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
closeTabMenuItem.Text(RS_(L"TabClose"));
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||
void NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
|
||||
void UpdateSettings(const Microsoft::Terminal::Settings::Model::TerminalSettingsStruct& settings, const GUID& profile);
|
||||
void UpdateSettings(const Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings, const GUID& profile);
|
||||
winrt::fire_and_forget UpdateTitle();
|
||||
|
||||
void Shutdown() override;
|
||||
|
||||
@@ -1,45 +1,47 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<Grid
|
||||
x:Class="TerminalApp.TitlebarControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
x:Name="Root"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
SizeChanged="Root_SizeChanged"
|
||||
d:DesignHeight="36"
|
||||
Background="{ThemeResource TabViewBackground}"
|
||||
d:DesignWidth="400">
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<Grid x:Class="TerminalApp.TitlebarControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Name="Root"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
d:DesignHeight="36"
|
||||
d:DesignWidth="400"
|
||||
Background="{ThemeResource TabViewBackground}"
|
||||
SizeChanged="Root_SizeChanged"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<!-- TODO:GH#1988
|
||||
This xaml should probably be a template thing, where the background is a
|
||||
resource that the app hosting this control can override. Then, it App.xaml,
|
||||
we'd make sure to set the resource for our background to the appropriate
|
||||
color. SystemControlForegroundAccentBrush also works nicely, to use the
|
||||
accent color. (which is GH#1963)-->
|
||||
<!--
|
||||
TODO:GH#1988
|
||||
This xaml should probably be a template thing, where the background is a
|
||||
resource that the app hosting this control can override. Then, it App.xaml,
|
||||
we'd make sure to set the resource for our background to the appropriate
|
||||
color. SystemControlForegroundAccentBrush also works nicely, to use the
|
||||
accent color. (which is GH#1963)
|
||||
-->
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter x:Name="ContentRoot" Grid.Column="0" />
|
||||
<ContentPresenter x:Name="ContentRoot"
|
||||
Grid.Column="0" />
|
||||
|
||||
<Border
|
||||
x:Name="DragBar"
|
||||
Grid.Column="1"
|
||||
MinWidth="45.0"
|
||||
DoubleTapped="DragBar_DoubleTapped"/>
|
||||
<Border x:Name="DragBar"
|
||||
Grid.Column="1"
|
||||
MinWidth="45.0"
|
||||
DoubleTapped="DragBar_DoubleTapped" />
|
||||
|
||||
<local:MinMaxCloseControl
|
||||
Grid.Column="2"
|
||||
x:Name="MinMaxCloseControl"
|
||||
HorizontalAlignment="Right" />
|
||||
<local:MinMaxCloseControl x:Name="MinMaxCloseControl"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
|
||||
|
||||
40
src/cascadia/TerminalApp/Toast.cpp
Normal file
40
src/cascadia/TerminalApp/Toast.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "Toast.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
constexpr const auto ToastDuration = std::chrono::milliseconds(3000);
|
||||
|
||||
Toast::Toast(const winrt::Microsoft::UI::Xaml::Controls::TeachingTip& tip) :
|
||||
_tip{ tip }
|
||||
{
|
||||
_timer.Interval(ToastDuration);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Open() the TeachingTip, and start our timer. When the timer expires, the
|
||||
// tip will be closed.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Toast::Open()
|
||||
{
|
||||
_tip.IsOpen(true);
|
||||
|
||||
std::weak_ptr<Toast> weakThis{ shared_from_this() };
|
||||
_timer.Tick([weakThis](auto&&...) {
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
self->_timer.Stop();
|
||||
self->_tip.IsOpen(false);
|
||||
}
|
||||
});
|
||||
_timer.Start();
|
||||
}
|
||||
38
src/cascadia/TerminalApp/Toast.h
Normal file
38
src/cascadia/TerminalApp/Toast.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- Toast.h
|
||||
|
||||
Module Description:
|
||||
- This is a helper class for wrapping a TeachingTip with a timer to
|
||||
automatically dismiss it. Callers should add the TeachingTip wherever they'd
|
||||
like in the UI tree, then wrap that TeachingTip in a toast like so:
|
||||
|
||||
```
|
||||
std::unique_ptr<Toast> myToast = std::make_unique<Toast>(MyTeachingTip());
|
||||
```
|
||||
- Then, you can show the TeachingTip with
|
||||
|
||||
```
|
||||
myToast->Open();
|
||||
```
|
||||
|
||||
which will open the tip and close it after a brief timeout.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
|
||||
class Toast : public std::enable_shared_from_this<Toast>
|
||||
{
|
||||
public:
|
||||
Toast(const winrt::Microsoft::UI::Xaml::Controls::TeachingTip& tip);
|
||||
void Open();
|
||||
|
||||
private:
|
||||
winrt::Microsoft::UI::Xaml::Controls::TeachingTip _tip;
|
||||
winrt::Windows::UI::Xaml::DispatcherTimer _timer;
|
||||
};
|
||||
@@ -104,7 +104,7 @@
|
||||
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>User32.lib;WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>User32.lib;WindowsApp.lib;shell32.lib;WinMM.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<!-- TerminalAppLib contains a DllMain that we need to force the use of. -->
|
||||
<AdditionalOptions Condition="'$(Platform)'=='Win32'">/INCLUDE:_DllMain@12</AdditionalOptions>
|
||||
<AdditionalOptions Condition="'$(Platform)'!='Win32'">/INCLUDE:DllMain</AdditionalOptions>
|
||||
|
||||
108
src/cascadia/TerminalConnection/CTerminalHandoff.cpp
Normal file
108
src/cascadia/TerminalConnection/CTerminalHandoff.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "CTerminalHandoff.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
// The callback function when a connection is received
|
||||
static NewHandoffFunction _pfnHandoff = nullptr;
|
||||
// The registration ID of the class object for clean up later
|
||||
static DWORD g_cTerminalHandoffRegistration = 0;
|
||||
|
||||
// Routine Description:
|
||||
// - Starts listening for TerminalHandoff requests by registering
|
||||
// our class and interface with COM.
|
||||
// Arguments:
|
||||
// - pfnHandoff - Function to callback when a handoff is received
|
||||
// Return Value:
|
||||
// - S_OK, E_NOT_VALID_STATE (start called when already started) or relevant COM registration error.
|
||||
HRESULT CTerminalHandoff::s_StartListening(NewHandoffFunction pfnHandoff) noexcept
|
||||
try
|
||||
{
|
||||
RETURN_HR_IF(E_NOT_VALID_STATE, _pfnHandoff != nullptr);
|
||||
|
||||
const auto classFactory = Make<SimpleClassFactory<CTerminalHandoff>>();
|
||||
|
||||
RETURN_IF_NULL_ALLOC(classFactory);
|
||||
|
||||
ComPtr<IUnknown> unk;
|
||||
RETURN_IF_FAILED(classFactory.As(&unk));
|
||||
|
||||
RETURN_IF_FAILED(CoRegisterClassObject(__uuidof(CTerminalHandoff), unk.Get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &g_cTerminalHandoffRegistration));
|
||||
|
||||
_pfnHandoff = pfnHandoff;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
// Routine Description:
|
||||
// - Stops listening for TerminalHandoff requests by revoking the registration
|
||||
// our class and interface with COM
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - S_OK, E_NOT_VALID_STATE (stop called when not started), or relevant COM class revoke error
|
||||
HRESULT CTerminalHandoff::s_StopListening() noexcept
|
||||
{
|
||||
RETURN_HR_IF_NULL(E_NOT_VALID_STATE, _pfnHandoff);
|
||||
|
||||
_pfnHandoff = nullptr;
|
||||
|
||||
if (g_cTerminalHandoffRegistration)
|
||||
{
|
||||
RETURN_IF_FAILED(CoRevokeClassObject(g_cTerminalHandoffRegistration));
|
||||
g_cTerminalHandoffRegistration = 0;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Helper to duplicate a handle to ourselves so we can keep holding onto it
|
||||
// after the caller frees the original one.
|
||||
// Arguments:
|
||||
// - in - Handle to duplicate
|
||||
// - out - Where to place the duplicated value
|
||||
// Return Value:
|
||||
// - S_OK or Win32 error from `::DuplicateHandle`
|
||||
static HRESULT _duplicateHandle(const HANDLE in, HANDLE& out) noexcept
|
||||
{
|
||||
RETURN_IF_WIN32_BOOL_FALSE(::DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), &out, 0, FALSE, DUPLICATE_SAME_ACCESS));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Receives the terminal handoff via COM from the other process,
|
||||
// duplicates handles as COM will free those given on the way out,
|
||||
// then fires off an event notifying the rest of the terminal that
|
||||
// a connection is on its way in.
|
||||
// Arguments:
|
||||
// - in - PTY input handle that we will read from
|
||||
// - out - PTY output handle that we will write to
|
||||
// - signal - PTY signal handle for out of band messaging
|
||||
// - process - Process handle to client so we can track its lifetime and exit appropriately
|
||||
// Return Value:
|
||||
// - E_NOT_VALID_STATE if a event handler is not registered before calling. `::DuplicateHandle`
|
||||
// error codes if we cannot manage to make our own copy of handles to retain. Or S_OK/error
|
||||
// from the registered handler event function.
|
||||
HRESULT CTerminalHandoff::EstablishPtyHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE process) noexcept
|
||||
{
|
||||
// Report an error if no one registered a handoff function before calling this.
|
||||
RETURN_HR_IF_NULL(E_NOT_VALID_STATE, _pfnHandoff);
|
||||
|
||||
// Duplicate the handles from what we received.
|
||||
// The contract with COM specifies that any HANDLEs we receive from the caller belong
|
||||
// to the caller and will be freed when we leave the scope of this method.
|
||||
// Making our own duplicate copy ensures they hang around in our lifetime.
|
||||
RETURN_IF_FAILED(_duplicateHandle(in, in));
|
||||
RETURN_IF_FAILED(_duplicateHandle(out, out));
|
||||
RETURN_IF_FAILED(_duplicateHandle(signal, signal));
|
||||
RETURN_IF_FAILED(_duplicateHandle(process, process));
|
||||
|
||||
// Call registered handler from when we started listening.
|
||||
return _pfnHandoff(in, out, signal, process);
|
||||
}
|
||||
56
src/cascadia/TerminalConnection/CTerminalHandoff.h
Normal file
56
src/cascadia/TerminalConnection/CTerminalHandoff.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- CTerminalHandoff.h
|
||||
|
||||
Abstract:
|
||||
- This module receives an incoming request to host a terminal UX
|
||||
for a console mode application already started and attached to a PTY.
|
||||
|
||||
Author(s):
|
||||
- Michael Niksa (MiNiksa) 31-Aug-2020
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ITerminalHandoff.h"
|
||||
|
||||
#if defined(WT_BRANDING_RELEASE)
|
||||
#define __CLSID_CTerminalHandoff "E12CFF52-A866-4C77-9A90-F570A7AA2C6B"
|
||||
#elif defined(WT_BRANDING_PREVIEW)
|
||||
#define __CLSID_CTerminalHandoff "86633F1F-6454-40EC-89CE-DA4EBA977EE2"
|
||||
#else
|
||||
#define __CLSID_CTerminalHandoff "051F34EE-C1FD-4B19-AF75-9BA54648434C"
|
||||
#endif
|
||||
|
||||
using NewHandoffFunction = HRESULT (*)(HANDLE, HANDLE, HANDLE, HANDLE);
|
||||
|
||||
struct __declspec(uuid(__CLSID_CTerminalHandoff))
|
||||
CTerminalHandoff : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, ITerminalHandoff>
|
||||
{
|
||||
#pragma region ITerminalHandoff
|
||||
STDMETHODIMP EstablishPtyHandoff(HANDLE in,
|
||||
HANDLE out,
|
||||
HANDLE signal,
|
||||
HANDLE process) noexcept override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
static HRESULT s_StartListening(NewHandoffFunction pfnHandoff) noexcept;
|
||||
static HRESULT s_StopListening() noexcept;
|
||||
};
|
||||
|
||||
// Disable warnings from the CoCreatableClass macro as the value it provides for
|
||||
// automatic COM class registration is of much greater value than the nits from
|
||||
// the static analysis warnings.
|
||||
#pragma warning(push)
|
||||
|
||||
#pragma warning(disable : 26477) // Macro uses 0/NULL over nullptr.
|
||||
#pragma warning(disable : 26476) // Macro uses naked union over variant.
|
||||
|
||||
CoCreatableClass(CTerminalHandoff);
|
||||
|
||||
#pragma warning(pop)
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <userenv.h>
|
||||
|
||||
#include "ConptyConnection.g.cpp"
|
||||
#include "CTerminalHandoff.h"
|
||||
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../types/inc/Environment.hpp"
|
||||
@@ -190,6 +191,32 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
ConptyConnection::ConptyConnection(const HANDLE hSig,
|
||||
const HANDLE hIn,
|
||||
const HANDLE hOut,
|
||||
const HANDLE hClientProcess) :
|
||||
_initialRows{ 25 },
|
||||
_initialCols{ 80 },
|
||||
_commandline{ L"" },
|
||||
_startingDirectory{ L"" },
|
||||
_startingTitle{ L"" },
|
||||
_environment{ nullptr },
|
||||
_guid{},
|
||||
_u8State{},
|
||||
_u16Str{},
|
||||
_buffer{},
|
||||
_inPipe{ hIn },
|
||||
_outPipe{ hOut }
|
||||
{
|
||||
hSig; // TODO: GH 9464 this needs to be packed into the hpcon
|
||||
if (_guid == guid{})
|
||||
{
|
||||
_guid = Utils::CreateGuid();
|
||||
}
|
||||
|
||||
_piClient.hProcess = hClientProcess;
|
||||
}
|
||||
|
||||
ConptyConnection::ConptyConnection(const hstring& commandline,
|
||||
const hstring& startingDirectory,
|
||||
const hstring& startingTitle,
|
||||
@@ -222,9 +249,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
void ConptyConnection::Start()
|
||||
try
|
||||
{
|
||||
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, PSEUDOCONSOLE_RESIZE_QUIRK | PSEUDOCONSOLE_WIN32_INPUT_MODE, &_inPipe, &_outPipe, &_hPC));
|
||||
THROW_IF_FAILED(_LaunchAttachedClient());
|
||||
if (!_inPipe)
|
||||
{
|
||||
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, PSEUDOCONSOLE_RESIZE_QUIRK | PSEUDOCONSOLE_WIN32_INPUT_MODE, &_inPipe, &_outPipe, &_hPC));
|
||||
THROW_IF_FAILED(_LaunchAttachedClient());
|
||||
}
|
||||
|
||||
_startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
@@ -451,6 +481,31 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
return 0;
|
||||
}
|
||||
|
||||
static winrt::event<NewConnectionHandler> _newConnectionHandlers;
|
||||
|
||||
winrt::event_token ConptyConnection::NewConnection(NewConnectionHandler const& handler) { return _newConnectionHandlers.add(handler); };
|
||||
void ConptyConnection::NewConnection(winrt::event_token const& token) { _newConnectionHandlers.remove(token); };
|
||||
|
||||
HRESULT ConptyConnection::NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE process) noexcept
|
||||
try
|
||||
{
|
||||
auto conn = winrt::make<implementation::ConptyConnection>(signal, in, out, process);
|
||||
_newConnectionHandlers(conn);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
void ConptyConnection::StartInboundListener()
|
||||
{
|
||||
THROW_IF_FAILED(CTerminalHandoff::s_StartListening(&ConptyConnection::NewHandoff));
|
||||
}
|
||||
|
||||
void ConptyConnection::StopInboundListener()
|
||||
{
|
||||
THROW_IF_FAILED(CTerminalHandoff::s_StopListening());
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - This function will be called (by C++/WinRT) after the final outstanding reference to
|
||||
// any given connection instance is released.
|
||||
|
||||
@@ -19,6 +19,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
struct ConptyConnection : ConptyConnectionT<ConptyConnection>, ConnectionStateHolder<ConptyConnection>
|
||||
{
|
||||
ConptyConnection(const HANDLE hSig,
|
||||
const HANDLE hIn,
|
||||
const HANDLE hOut,
|
||||
const HANDLE hClientProcess);
|
||||
|
||||
ConptyConnection(
|
||||
const hstring& cmdline,
|
||||
const hstring& startingDirectory,
|
||||
@@ -36,6 +41,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
winrt::guid Guid() const noexcept;
|
||||
|
||||
static void StartInboundListener();
|
||||
static void StopInboundListener();
|
||||
|
||||
static winrt::event_token NewConnection(NewConnectionHandler const& handler);
|
||||
static void NewConnection(winrt::event_token const& token);
|
||||
|
||||
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
||||
|
||||
private:
|
||||
@@ -43,6 +54,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
void _indicateExitWithStatus(unsigned int status) noexcept;
|
||||
void _ClientTerminated() noexcept;
|
||||
|
||||
static HRESULT NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE process) noexcept;
|
||||
|
||||
uint32_t _initialRows{};
|
||||
uint32_t _initialCols{};
|
||||
hstring _commandline;
|
||||
|
||||
@@ -5,11 +5,13 @@ import "ITerminalConnection.idl";
|
||||
|
||||
namespace Microsoft.Terminal.TerminalConnection
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass ConptyConnection : ITerminalConnection
|
||||
[default_interface] runtimeclass ConptyConnection : ITerminalConnection
|
||||
{
|
||||
ConptyConnection(String cmdline, String startingDirectory, String startingTitle, IMapView<String,String> environment, UInt32 rows, UInt32 columns, Guid guid);
|
||||
ConptyConnection(String cmdline, String startingDirectory, String startingTitle, IMapView<String, String> environment, UInt32 rows, UInt32 columns, Guid guid);
|
||||
Guid Guid { get; };
|
||||
};
|
||||
|
||||
static event NewConnectionHandler NewConnection;
|
||||
static void StartInboundListener();
|
||||
static void StopInboundListener();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,4 +27,6 @@ namespace Microsoft.Terminal.TerminalConnection
|
||||
event Windows.Foundation.TypedEventHandler<ITerminalConnection, Object> StateChanged;
|
||||
ConnectionState State { get; };
|
||||
};
|
||||
|
||||
delegate void NewConnectionHandler(ITerminalConnection connection);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<ClInclude Include="AzureConnection.h">
|
||||
<DependentUpon>AzureConnection.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CTerminalHandoff.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ConptyConnection.h">
|
||||
<DependentUpon>ConptyConnection.idl</DependentUpon>
|
||||
@@ -24,6 +25,7 @@
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CTerminalHandoff.cpp" />
|
||||
<ClCompile Include="init.cpp" />
|
||||
<ClCompile Include="AzureConnection.cpp">
|
||||
<DependentUpon>AzureConnection.idl</DependentUpon>
|
||||
@@ -77,9 +79,12 @@
|
||||
<Error Condition="!Exists('..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets'))" />
|
||||
</Target>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(IntDir)..\OpenConsoleProxy;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -18,12 +18,14 @@
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="AzureConnection.cpp" />
|
||||
<ClCompile Include="init.cpp" />
|
||||
<ClCompile Include="CTerminalHandoff.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="EchoConnection.h" />
|
||||
<ClInclude Include="AzureConnection.h" />
|
||||
<ClInclude Include="AzureClientID.h" />
|
||||
<ClInclude Include="CTerminalHandoff.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="ITerminalConnection.idl" />
|
||||
@@ -38,8 +40,6 @@
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PRIResource Include="Resources/en-US/Resources.resw">
|
||||
<Filter>Resources\en-US</Filter>
|
||||
</PRIResource>
|
||||
<PRIResource Include="Resources\en-US\Resources.resw" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -5,7 +5,7 @@ namespace Microsoft.Terminal.Control
|
||||
{
|
||||
interface IControlAppearance requires Microsoft.Terminal.Core.ICoreAppearance
|
||||
{
|
||||
UInt32 SelectionBackground;
|
||||
Microsoft.Terminal.Core.Color SelectionBackground;
|
||||
String BackgroundImage;
|
||||
Double BackgroundImageOpacity;
|
||||
Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode;
|
||||
|
||||
@@ -1,149 +1,225 @@
|
||||
<UserControl
|
||||
x:Class="Microsoft.Terminal.Control.SearchBoxControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Control"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
x:Name="Root"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
d:DesignHeight="55"
|
||||
d:DesignWidth="285"
|
||||
TabNavigation="Cycle">
|
||||
<UserControl x:Class="Microsoft.Terminal.Control.SearchBoxControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Control"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Name="Root"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
d:DesignHeight="55"
|
||||
d:DesignWidth="285"
|
||||
TabNavigation="Cycle"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Style x:Key="ToggleButtonStyle"
|
||||
TargetType="ToggleButton">
|
||||
<Setter Property="Width" Value="25" />
|
||||
<Setter Property="Height" Value="25" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Padding" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="2"/>
|
||||
<Setter Property="CornerRadius" Value="2" />
|
||||
</Style>
|
||||
<Style x:Key="ButtonStyle" TargetType="Button">
|
||||
<Style x:Key="ButtonStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="Width" Value="25" />
|
||||
<Setter Property="Height" Value="25" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="CornerRadius" Value="2"/>
|
||||
<Setter Property="CornerRadius" Value="2" />
|
||||
</Style>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Style x:Key="FontIconStyle" TargetType="FontIcon">
|
||||
<Style x:Key="FontIconStyle"
|
||||
TargetType="FontIcon">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
</Style>
|
||||
<Style x:Key="SearchBoxBackground" TargetType="StackPanel">
|
||||
<Style x:Key="SearchBoxBackground"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Background" Value="#333333" />
|
||||
</Style>
|
||||
<!-- TextBox colors !-->
|
||||
<SolidColorBrush x:Key="TextControlBackground" Color="#333333"/>
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#B5B5B5"/>
|
||||
<SolidColorBrush x:Key="TextControlForeground" Color="#B5B5B5"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground" Color="#B5B5B5"/>
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlForeground"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#B5B5B5" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver" Color="#FF4343"/>
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused" Color="#333333"/>
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed" Color="#FF4343"/>
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- ToggleButton colors !-->
|
||||
<SolidColorBrush x:Key="ToggleButtonForeground" Color="#B5B5B5"/>
|
||||
<!-- ToggleButton colors ! -->
|
||||
<SolidColorBrush x:Key="ToggleButtonForeground"
|
||||
Color="#B5B5B5" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPointerOver" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPointerOver" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPointerOver"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPressed" Color="#555555"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPressed" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPressed"
|
||||
Color="#555555" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPressed"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundChecked" Color="#555555"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundChecked" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushChecked" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundChecked"
|
||||
Color="#555555" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundChecked"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushChecked"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPointerOver" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPointerOver" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPointerOver"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPressed" Color="#555555"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPressed" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPressed"
|
||||
Color="#555555" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPressed"
|
||||
Color="Transparent" />
|
||||
|
||||
<!--Button color !-->
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver" Color="#404040"/>
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver" Color="Transparent"/>
|
||||
<!-- Button color ! -->
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed" Color="#555555"/>
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPressed" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed"
|
||||
Color="#555555" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPressed"
|
||||
Color="Transparent" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Style x:Key="FontIconStyle" TargetType="FontIcon">
|
||||
<Style x:Key="FontIconStyle"
|
||||
TargetType="FontIcon">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
</Style>
|
||||
<Style x:Key="SearchBoxBackground" TargetType="StackPanel">
|
||||
<Style x:Key="SearchBoxBackground"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Background" Value="#CCCCCC" />
|
||||
</Style>
|
||||
<!-- TextBox colors !-->
|
||||
<SolidColorBrush x:Key="TextControlBackground" Color="#CCCCCC"/>
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground" Color="#636363"/>
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#636363" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver" Color="#DADADA"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver" Color="#FF4343"/>
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused" Color="#CCCCCC"/>
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed" Color="#FF4343"/>
|
||||
<!-- ToggleButton colors !-->
|
||||
<SolidColorBrush x:Key="ToggleButtonForeground" Color="#636363"/>
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
<!-- ToggleButton colors ! -->
|
||||
<SolidColorBrush x:Key="ToggleButtonForeground"
|
||||
Color="#636363" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPointerOver" Color="#DADADA"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPointerOver" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPointerOver" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPointerOver"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPointerOver"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPressed" Color="#B8B8B8"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPressed" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPressed" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundPressed"
|
||||
Color="#B8B8B8" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundPressed"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushPressed"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundChecked" Color="#B8B8B8"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundChecked" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushChecked" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundChecked"
|
||||
Color="#B8B8B8" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundChecked"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushChecked"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPointerOver" Color="#DADADA"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPointerOver" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPointerOver" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPointerOver"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPointerOver"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPressed" Color="#B8B8B8"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPressed" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPressed" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPressed"
|
||||
Color="#B8B8B8" />
|
||||
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPressed"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ToggleButtonBorderBrushCheckedPressed"
|
||||
Color="Transparent" />
|
||||
|
||||
<!-- Button color !-->
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver" Color="#DADADA"/>
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver" Color="Transparent"/>
|
||||
<!-- Button color ! -->
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver"
|
||||
Color="Transparent" />
|
||||
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed" Color="#B8B8B8"/>
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed" Color="#000000"/>
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPressed" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed"
|
||||
Color="#B8B8B8" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed"
|
||||
Color="#000000" />
|
||||
<SolidColorBrush x:Key="ButtonBorderBrushPressed"
|
||||
Color="Transparent" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="FontIconStyle" TargetType="FontIcon">
|
||||
<Style x:Key="FontIconStyle"
|
||||
TargetType="FontIcon">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
</Style>
|
||||
<Style x:Key="SearchBoxBackground" TargetType="StackPanel">
|
||||
<Style x:Key="SearchBoxBackground"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Background" Value="{ThemeResource SystemColorWindowColor}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -151,38 +227,44 @@
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Style="{ThemeResource SearchBoxBackground}" Padding="5" CornerRadius="0,0,2,2">
|
||||
<TextBox x:Name="TextBox"
|
||||
x:Uid="SearchBox_TextBox"
|
||||
CornerRadius="2"
|
||||
Width="160"
|
||||
PlaceholderForeground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"
|
||||
FontSize="15"
|
||||
KeyDown="TextBoxKeyDown"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center">
|
||||
</TextBox>
|
||||
<StackPanel Padding="5"
|
||||
CornerRadius="0,0,2,2"
|
||||
Orientation="Horizontal"
|
||||
Style="{ThemeResource SearchBoxBackground}">
|
||||
<TextBox x:Name="TextBox"
|
||||
x:Uid="SearchBox_TextBox"
|
||||
Width="160"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="2"
|
||||
FontSize="15"
|
||||
KeyDown="TextBoxKeyDown"
|
||||
PlaceholderForeground="{ThemeResource TextBoxPlaceholderTextThemeBrush}" />
|
||||
|
||||
<ToggleButton x:Name="GoBackwardButton"
|
||||
x:Uid="SearchBox_SearchBackwards"
|
||||
HorizontalAlignment="Right"
|
||||
Style="{StaticResource ToggleButtonStyle}"
|
||||
Click="GoBackwardClicked"
|
||||
IsChecked="True">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" Style="{ThemeResource FontIconStyle}"/>
|
||||
IsChecked="True"
|
||||
Style="{StaticResource ToggleButtonStyle}">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
Style="{ThemeResource FontIconStyle}" />
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="GoForwardButton"
|
||||
x:Uid="SearchBox_SearchForwards"
|
||||
Style="{StaticResource ToggleButtonStyle}"
|
||||
Click="GoForwardClicked">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" Style="{ThemeResource FontIconStyle}"/>
|
||||
Click="GoForwardClicked"
|
||||
Style="{StaticResource ToggleButtonStyle}">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
Style="{ThemeResource FontIconStyle}" />
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleButton x:Name="CaseSensitivityButton"
|
||||
x:Uid="SearchBox_CaseSensitivity"
|
||||
Style="{StaticResource ToggleButtonStyle}">
|
||||
<PathIcon Data="M8.87305 10H7.60156L6.5625 7.25195H2.40625L1.42871 10H0.150391L3.91016 0.197266H5.09961L8.87305 10ZM6.18652 6.21973L4.64844 2.04297C4.59831 1.90625 4.54818 1.6875 4.49805 1.38672H4.4707C4.42513 1.66471 4.37272 1.88346 4.31348 2.04297L2.78906 6.21973H6.18652ZM15.1826 10H14.0615V8.90625H14.0342C13.5465 9.74479 12.8288 10.1641 11.8809 10.1641C11.1836 10.1641 10.6367 9.97949 10.2402 9.61035C9.84831 9.24121 9.65234 8.7513 9.65234 8.14062C9.65234 6.83268 10.4225 6.07161 11.9629 5.85742L14.0615 5.56348C14.0615 4.37402 13.5807 3.7793 12.6191 3.7793C11.776 3.7793 11.015 4.06641 10.3359 4.64062V3.49219C11.0241 3.05469 11.8171 2.83594 12.7148 2.83594C14.36 2.83594 15.1826 3.70638 15.1826 5.44727V10ZM14.0615 6.45898L12.373 6.69141C11.8535 6.76432 11.4616 6.89421 11.1973 7.08105C10.9329 7.26335 10.8008 7.58919 10.8008 8.05859C10.8008 8.40039 10.9215 8.68066 11.1631 8.89941C11.4092 9.11361 11.735 9.2207 12.1406 9.2207C12.6966 9.2207 13.1546 9.02702 13.5146 8.63965C13.8792 8.24772 14.0615 7.75326 14.0615 7.15625V6.45898Z"/>
|
||||
<PathIcon Data="M8.87305 10H7.60156L6.5625 7.25195H2.40625L1.42871 10H0.150391L3.91016 0.197266H5.09961L8.87305 10ZM6.18652 6.21973L4.64844 2.04297C4.59831 1.90625 4.54818 1.6875 4.49805 1.38672H4.4707C4.42513 1.66471 4.37272 1.88346 4.31348 2.04297L2.78906 6.21973H6.18652ZM15.1826 10H14.0615V8.90625H14.0342C13.5465 9.74479 12.8288 10.1641 11.8809 10.1641C11.1836 10.1641 10.6367 9.97949 10.2402 9.61035C9.84831 9.24121 9.65234 8.7513 9.65234 8.14062C9.65234 6.83268 10.4225 6.07161 11.9629 5.85742L14.0615 5.56348C14.0615 4.37402 13.5807 3.7793 12.6191 3.7793C11.776 3.7793 11.015 4.06641 10.3359 4.64062V3.49219C11.0241 3.05469 11.8171 2.83594 12.7148 2.83594C14.36 2.83594 15.1826 3.70638 15.1826 5.44727V10ZM14.0615 6.45898L12.373 6.69141C11.8535 6.76432 11.4616 6.89421 11.1973 7.08105C10.9329 7.26335 10.8008 7.58919 10.8008 8.05859C10.8008 8.40039 10.9215 8.68066 11.1631 8.89941C11.4092 9.11361 11.735 9.2207 12.1406 9.2207C12.6966 9.2207 13.1546 9.02702 13.5146 8.63965C13.8792 8.24772 14.0615 7.75326 14.0615 7.15625V6.45898Z" />
|
||||
</ToggleButton>
|
||||
|
||||
<Button x:Name="CloseButton"
|
||||
@@ -190,7 +272,9 @@
|
||||
Padding="0"
|
||||
Click="CloseClick"
|
||||
Style="{ThemeResource ButtonStyle}">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="12"/>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<UserControl
|
||||
x:Class="Microsoft.Terminal.Control.TSFInputControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="768"
|
||||
d:DesignWidth="1024">
|
||||
<UserControl x:Class="Microsoft.Terminal.Control.TSFInputControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
d:DesignHeight="768"
|
||||
d:DesignWidth="1024"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Canvas x:Name="Canvas"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="TextBlock"
|
||||
IsTextSelectionEnabled="false"
|
||||
TextWrapping="Wrap"
|
||||
TextDecorations="Underline" />
|
||||
TextDecorations="Underline"
|
||||
TextWrapping="Wrap" />
|
||||
</Canvas>
|
||||
</UserControl>
|
||||
|
||||
@@ -306,24 +306,31 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// terminal.
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
|
||||
_UpdateSettingsFromUIThread(_settings);
|
||||
// Take the lock before calling the helper functions to update the settings and appearance
|
||||
auto lock = _terminal->LockForWriting();
|
||||
|
||||
_UpdateSettingsFromUIThreadUnderLock(_settings);
|
||||
|
||||
auto appearance = _settings.try_as<IControlAppearance>();
|
||||
if (!_focused && _UnfocusedAppearance)
|
||||
{
|
||||
appearance = _UnfocusedAppearance;
|
||||
}
|
||||
_UpdateAppearanceFromUIThread(appearance);
|
||||
_UpdateAppearanceFromUIThreadUnderLock(appearance);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Dispatches a call to the UI thread and updates the appearance
|
||||
// Arguments:
|
||||
// - newAppearance: the new appearance to set
|
||||
winrt::fire_and_forget TermControl::UpdateAppearance(IControlAppearance newAppearance)
|
||||
winrt::fire_and_forget TermControl::UpdateAppearance(const IControlAppearance newAppearance)
|
||||
{
|
||||
// Dispatch a call to the UI thread
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
_UpdateAppearanceFromUIThread(newAppearance);
|
||||
|
||||
// Take the lock before calling the helper function to update the appearance
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_UpdateAppearanceFromUIThreadUnderLock(newAppearance);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -366,9 +373,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// issue that causes one of our hstring -> wstring_view conversions to result in garbage,
|
||||
// but only from a coroutine context. See GH#8723.
|
||||
// - INVARIANT: This method must be called from the UI thread.
|
||||
// - INVARIANT: This method can only be called if the caller has the writing lock on the terminal.
|
||||
// Arguments:
|
||||
// - newSettings: the new settings to set
|
||||
void TermControl::_UpdateSettingsFromUIThread(IControlSettings newSettings)
|
||||
void TermControl::_UpdateSettingsFromUIThreadUnderLock(IControlSettings newSettings)
|
||||
{
|
||||
if (_closing)
|
||||
{
|
||||
@@ -381,7 +389,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Update the terminal core with its new Core settings
|
||||
_terminal->UpdateSettings(_settings);
|
||||
|
||||
auto lock = _terminal->LockForWriting();
|
||||
if (!_initializedTerminal)
|
||||
{
|
||||
// If we haven't initialized, there's no point in continuing.
|
||||
// Initialization will handle the renderer settings.
|
||||
return;
|
||||
}
|
||||
|
||||
// Update DxEngine settings under the lock
|
||||
_renderEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering());
|
||||
@@ -413,10 +426,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Updates the appearance
|
||||
// - This should only be called from the UI thread
|
||||
// - INVARIANT: This method must be called from the UI thread.
|
||||
// - INVARIANT: This method can only be called if the caller has the writing lock on the terminal.
|
||||
// Arguments:
|
||||
// - newAppearance: the new appearance to set
|
||||
void TermControl::_UpdateAppearanceFromUIThread(IControlAppearance newAppearance)
|
||||
void TermControl::_UpdateAppearanceFromUIThreadUnderLock(IControlAppearance newAppearance)
|
||||
{
|
||||
if (_closing)
|
||||
{
|
||||
@@ -456,7 +470,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// Update our control settings
|
||||
COLORREF bg = newAppearance.DefaultBackground();
|
||||
const auto bg = newAppearance.DefaultBackground();
|
||||
_BackgroundColorChanged(bg);
|
||||
|
||||
// Set TSF Foreground
|
||||
@@ -467,10 +481,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Update the terminal core with its new Core settings
|
||||
_terminal->UpdateAppearance(newAppearance);
|
||||
|
||||
auto lock = _terminal->LockForWriting();
|
||||
|
||||
// Update DxEngine settings under the lock
|
||||
_renderEngine->SetSelectionBackground(newAppearance.SelectionBackground());
|
||||
_renderEngine->SetSelectionBackground(til::color{ newAppearance.SelectionBackground() });
|
||||
_renderEngine->SetRetroTerminalEffect(newAppearance.RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(newAppearance.PixelShaderPath());
|
||||
_renderer->TriggerRedrawAll();
|
||||
@@ -561,12 +573,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// see GH#1082: Initialize background color so we don't get a
|
||||
// fade/flash when _BackgroundColorChanged is called
|
||||
uint32_t color = _settings.DefaultBackground();
|
||||
winrt::Windows::UI::Color bgColor{};
|
||||
bgColor.R = GetRValue(color);
|
||||
bgColor.G = GetGValue(color);
|
||||
bgColor.B = GetBValue(color);
|
||||
bgColor.A = 255;
|
||||
auto bgColor = til::color{ _settings.DefaultBackground() }.with_alpha(0xff);
|
||||
|
||||
acrylic.FallbackColor(bgColor);
|
||||
acrylic.TintColor(bgColor);
|
||||
@@ -605,7 +612,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - color: The background color to use as a uint32 (aka DWORD COLORREF)
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TermControl::_BackgroundColorChanged(const COLORREF color)
|
||||
winrt::fire_and_forget TermControl::_BackgroundColorChanged(const til::color color)
|
||||
{
|
||||
til::color newBgColor{ color };
|
||||
|
||||
@@ -799,9 +806,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, windowSize);
|
||||
LOG_IF_FAILED(dxEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() }));
|
||||
|
||||
// Update DxEngine's SelectionBackground
|
||||
dxEngine->SetSelectionBackground(_settings.SelectionBackground());
|
||||
|
||||
const auto vp = dxEngine->GetViewportInCharacters(viewInPixels);
|
||||
const auto width = vp.Width();
|
||||
const auto height = vp.Height();
|
||||
@@ -819,8 +823,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// the first paint will be ignored!
|
||||
dxEngine->SetWarningCallback(std::bind(&TermControl::_RendererWarning, this, std::placeholders::_1));
|
||||
|
||||
dxEngine->SetRetroTerminalEffect(_settings.RetroTerminalEffect());
|
||||
dxEngine->SetPixelShaderPath(_settings.PixelShaderPath());
|
||||
dxEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering());
|
||||
dxEngine->SetSoftwareRendering(_settings.SoftwareRendering());
|
||||
|
||||
@@ -910,7 +912,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
this->Focus(FocusState::Programmatic);
|
||||
|
||||
// Now that the renderer is set up, update the appearance for initialization
|
||||
UpdateAppearance(_settings);
|
||||
_UpdateAppearanceFromUIThreadUnderLock(_settings);
|
||||
|
||||
_initializedTerminal = true;
|
||||
} // scope for TerminalLock
|
||||
@@ -1382,11 +1384,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
mode = ::Terminal::SelectionExpansionMode::Line;
|
||||
}
|
||||
|
||||
// Capture the position of the first click when no selection is active
|
||||
if (mode == ::Terminal::SelectionExpansionMode::Cell && !_terminal->IsSelectionActive())
|
||||
// Capture the position of the first click
|
||||
if (mode == ::Terminal::SelectionExpansionMode::Cell)
|
||||
{
|
||||
_singleClickTouchdownPos = cursorPosition;
|
||||
_lastMouseClickPosNoSelection = cursorPosition;
|
||||
if (!_terminal->IsSelectionActive())
|
||||
{
|
||||
_lastMouseClickPosNoSelection = cursorPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// We reset the active selection if one of the conditions apply:
|
||||
@@ -1417,6 +1422,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_selectionNeedsToBeCopied = true;
|
||||
}
|
||||
|
||||
if (_terminal->IsSelectionActive())
|
||||
{
|
||||
// GH#9787: if selection is active we don't want to track the touchdown position
|
||||
// so that dragging the mouse will extend the selection rather than starting the new one
|
||||
_singleClickTouchdownPos = std::nullopt;
|
||||
}
|
||||
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
else if (point.Properties().IsRightButtonPressed())
|
||||
@@ -1739,7 +1751,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
_settings.UseAcrylic(false);
|
||||
_InitializeBackgroundBrush();
|
||||
COLORREF bg = _settings.DefaultBackground();
|
||||
const auto bg = _settings.DefaultBackground();
|
||||
_BackgroundColorChanged(bg);
|
||||
}
|
||||
else
|
||||
@@ -1844,7 +1856,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
|
||||
_terminal->ClearPatternTree();
|
||||
{
|
||||
// We're taking the lock here instead of in ClearPatternTree because ClearPatternTree is
|
||||
// sometimes called from an already-locked context. Here, we are sure we are not
|
||||
// already under lock (since it is not an internal scroll bar update)
|
||||
// TODO GH#9617: refine locking around pattern tree
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_terminal->ClearPatternTree();
|
||||
}
|
||||
|
||||
const auto newValue = static_cast<int>(args.NewValue());
|
||||
|
||||
@@ -2155,8 +2174,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// actually fail. We need a way to gracefully fallback.
|
||||
_renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont);
|
||||
|
||||
// If the actual font isn't what was requested...
|
||||
if (_actualFont.GetFaceName() != _desiredFont.GetFaceName())
|
||||
// If the actual font went through the last-chance fallback routines...
|
||||
if (_actualFont.GetFallback())
|
||||
{
|
||||
// Then warn the user that we picked something because we couldn't find their font.
|
||||
|
||||
@@ -2478,6 +2497,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
|
||||
// We're **NOT** taking the lock here unlike _ScrollbarChangeHandler because
|
||||
// we are already under lock (since this usually happens as a result of writing).
|
||||
// TODO GH#9617: refine locking around pattern tree
|
||||
_terminal->ClearPatternTree();
|
||||
|
||||
_scrollPositionChangedHandlers(viewTop, viewHeight, bufferSize);
|
||||
@@ -2520,6 +2542,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return hstr;
|
||||
}
|
||||
|
||||
bool TermControl::BracketedPasteEnabled() const noexcept
|
||||
{
|
||||
return _terminal->IsXtermBracketedPasteModeEnabled();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Given a copy-able selection, get the selected text from the buffer and send it to the
|
||||
// Windows Clipboard (CascadiaWin32:main.cpp).
|
||||
@@ -2562,7 +2589,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TextBuffer::GenHTML(bufferData,
|
||||
_actualFont.GetUnscaledSize().Y,
|
||||
_actualFont.GetFaceName(),
|
||||
_settings.DefaultBackground()) :
|
||||
til::color{ _settings.DefaultBackground() }) :
|
||||
"";
|
||||
|
||||
// convert to RTF format
|
||||
@@ -2570,7 +2597,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TextBuffer::GenRTF(bufferData,
|
||||
_actualFont.GetUnscaledSize().Y,
|
||||
_actualFont.GetFaceName(),
|
||||
_settings.DefaultBackground()) :
|
||||
til::color{ _settings.DefaultBackground() }) :
|
||||
"";
|
||||
|
||||
if (!_settings.CopyOnSelect())
|
||||
@@ -3306,7 +3333,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TermControl::TabColor() noexcept
|
||||
{
|
||||
auto coreColor = _terminal->GetTabColor();
|
||||
return coreColor.has_value() ? Windows::Foundation::IReference<winrt::Windows::UI::Color>(coreColor.value()) : nullptr;
|
||||
return coreColor.has_value() ? Windows::Foundation::IReference<winrt::Windows::UI::Color>(til::color{ coreColor.value() }) : nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -3378,8 +3405,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
_lastHoveredCell = terminalPosition;
|
||||
|
||||
uint16_t newId{ 0u };
|
||||
// we can't use auto here because we're pre-declaring newInterval.
|
||||
decltype(_terminal->GetHyperlinkIntervalFromPosition(COORD{})) newInterval{ std::nullopt };
|
||||
if (terminalPosition.has_value())
|
||||
{
|
||||
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||
|
||||
const auto uri = _terminal->GetHyperlinkAtPosition(*terminalPosition);
|
||||
if (!uri.empty())
|
||||
{
|
||||
@@ -3405,15 +3437,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
OverlayCanvas().SetLeft(HyperlinkTooltipBorder(), (locationInDIPs.x() - SwapChainPanel().ActualOffset().x));
|
||||
OverlayCanvas().SetTop(HyperlinkTooltipBorder(), (locationInDIPs.y() - SwapChainPanel().ActualOffset().y));
|
||||
}
|
||||
}
|
||||
|
||||
const uint16_t newId = terminalPosition.has_value() ? _terminal->GetHyperlinkIdAtPosition(*terminalPosition) : 0u;
|
||||
const auto newInterval = terminalPosition.has_value() ? _terminal->GetHyperlinkIntervalFromPosition(*terminalPosition) : std::nullopt;
|
||||
newId = _terminal->GetHyperlinkIdAtPosition(*terminalPosition);
|
||||
newInterval = _terminal->GetHyperlinkIntervalFromPosition(*terminalPosition);
|
||||
}
|
||||
|
||||
// If the hyperlink ID changed or the interval changed, trigger a redraw all
|
||||
// (so this will happen both when we move onto a link and when we move off a link)
|
||||
if (newId != _lastHoveredId || (newInterval != _lastHoveredInterval))
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
_lastHoveredId = newId;
|
||||
_lastHoveredInterval = newInterval;
|
||||
_renderEngine->UpdateHyperlinkHoveredId(newId);
|
||||
|
||||
@@ -26,12 +26,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
||||
|
||||
winrt::fire_and_forget UpdateSettings();
|
||||
winrt::fire_and_forget UpdateAppearance(IControlAppearance newAppearance);
|
||||
winrt::fire_and_forget UpdateAppearance(const IControlAppearance newAppearance);
|
||||
|
||||
hstring Title();
|
||||
hstring GetProfileName() const;
|
||||
hstring WorkingDirectory() const;
|
||||
|
||||
bool BracketedPasteEnabled() const noexcept;
|
||||
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void PasteTextFromClipboard();
|
||||
void Close();
|
||||
@@ -197,15 +198,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
||||
|
||||
void _UpdateSettingsFromUIThread(IControlSettings newSettings);
|
||||
void _UpdateAppearanceFromUIThread(IControlAppearance newAppearance);
|
||||
void _UpdateSettingsFromUIThreadUnderLock(IControlSettings newSettings);
|
||||
void _UpdateAppearanceFromUIThreadUnderLock(IControlAppearance newAppearance);
|
||||
bool _isReadOnly{ false };
|
||||
|
||||
void _ApplyUISettings(const IControlSettings&);
|
||||
void _UpdateSettingsOnUIThread();
|
||||
void _UpdateSystemParameterSettings() noexcept;
|
||||
void _InitializeBackgroundBrush();
|
||||
winrt::fire_and_forget _BackgroundColorChanged(const COLORREF color);
|
||||
winrt::fire_and_forget _BackgroundColorChanged(const til::color color);
|
||||
bool _InitializeTerminal();
|
||||
void _UpdateFont(const bool initialUpdate = false);
|
||||
void _SetFontSize(int fontSize);
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
String Title { get; };
|
||||
|
||||
Boolean BracketedPasteEnabled { get; };
|
||||
Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference<CopyFormat> formats);
|
||||
void PasteTextFromClipboard();
|
||||
void Close();
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<UserControl
|
||||
x:Class="Microsoft.Terminal.Control.TermControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Control"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
d:DesignHeight="768"
|
||||
d:DesignWidth="1024"
|
||||
TabNavigation="Cycle"
|
||||
IsTabStop="True"
|
||||
AllowFocusOnInteraction="True"
|
||||
AllowDrop="True"
|
||||
Drop="_DragDropHandler"
|
||||
DragOver="_DragOverHandler"
|
||||
Tapped="_TappedHandler"
|
||||
PointerWheelChanged="_MouseWheelHandler"
|
||||
PreviewKeyDown="_KeyDownHandler"
|
||||
KeyUp="_KeyUpHandler"
|
||||
CharacterReceived="_CharacterHandler"
|
||||
GotFocus="_GotFocusHandler"
|
||||
LostFocus="_LostFocusHandler">
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<UserControl x:Class="Microsoft.Terminal.Control.TermControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Control"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
d:DesignHeight="768"
|
||||
d:DesignWidth="1024"
|
||||
AllowDrop="True"
|
||||
AllowFocusOnInteraction="True"
|
||||
CharacterReceived="_CharacterHandler"
|
||||
DragOver="_DragOverHandler"
|
||||
Drop="_DragDropHandler"
|
||||
GotFocus="_GotFocusHandler"
|
||||
IsTabStop="True"
|
||||
KeyUp="_KeyUpHandler"
|
||||
LostFocus="_LostFocusHandler"
|
||||
PointerWheelChanged="_MouseWheelHandler"
|
||||
PreviewKeyDown="_KeyDownHandler"
|
||||
TabNavigation="Cycle"
|
||||
Tapped="_TappedHandler"
|
||||
mc:Ignorable="d">
|
||||
<!--
|
||||
TODO GH#4031: We've investigated whether we should be using KeyDown or PreviewKeyDown
|
||||
but not necessarily come to a consensus. It's possible that moving input to the SwapChainPanel
|
||||
@@ -41,16 +42,16 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid Grid.Column="0"
|
||||
Visibility="Visible"
|
||||
Background="Transparent"
|
||||
PointerPressed="_PointerPressedHandler"
|
||||
PointerExited="_PointerExitedHandler"
|
||||
PointerMoved="_PointerMovedHandler"
|
||||
PointerPressed="_PointerPressedHandler"
|
||||
PointerReleased="_PointerReleasedHandler"
|
||||
PointerExited="_PointerExitedHandler">
|
||||
Visibility="Visible">
|
||||
|
||||
<SwapChainPanel x:Name="SwapChainPanel"
|
||||
SizeChanged="_SwapChainSizeChanged"
|
||||
CompositionScaleChanged="_SwapChainScaleChanged">
|
||||
CompositionScaleChanged="_SwapChainScaleChanged"
|
||||
SizeChanged="_SwapChainSizeChanged">
|
||||
|
||||
<Canvas x:Name="OverlayCanvas"
|
||||
Visibility="Visible">
|
||||
@@ -60,10 +61,9 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
<ToolTip x:Name="LinkTip"
|
||||
Placement="Mouse">
|
||||
<TextBlock IsTextSelectionEnabled="True">
|
||||
<Run x:Name="HoveredUri"/> <LineBreak />
|
||||
<Run x:Name="HoveredUri" /> <LineBreak />
|
||||
<Run x:Uid="HowToOpenRun"
|
||||
FontStyle="Italic">
|
||||
</Run>
|
||||
FontStyle="Italic" />
|
||||
</TextBlock>
|
||||
</ToolTip>
|
||||
</ToolTipService.ToolTip>
|
||||
@@ -71,31 +71,33 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</Canvas>
|
||||
</SwapChainPanel>
|
||||
|
||||
<!-- Putting this in a grid w/ the SwapChainPanel
|
||||
ensures that it's always aligned w/ the scrollbar -->
|
||||
<!--
|
||||
Putting this in a grid w/ the SwapChainPanel
|
||||
ensures that it's always aligned w/ the scrollbar
|
||||
-->
|
||||
<local:SearchBoxControl x:Name="SearchBox"
|
||||
x:Load="False"
|
||||
Visibility="Collapsed"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
x:Load="False"
|
||||
Closed="_CloseSearchBoxControl"
|
||||
Search="_Search"
|
||||
Closed="_CloseSearchBoxControl" />
|
||||
Visibility="Collapsed" />
|
||||
</Grid>
|
||||
|
||||
<ScrollBar Grid.Column="1"
|
||||
x:Name="ScrollBar"
|
||||
Orientation="Vertical"
|
||||
IndicatorMode="MouseIndicator"
|
||||
<ScrollBar x:Name="ScrollBar"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Stretch"
|
||||
Maximum="1"
|
||||
ViewportSize="10"
|
||||
IndicatorMode="MouseIndicator"
|
||||
IsTabStop="False"
|
||||
SmallChange="1"
|
||||
LargeChange="4"
|
||||
ValueChanged="_ScrollbarChangeHandler"
|
||||
Maximum="1"
|
||||
Orientation="Vertical"
|
||||
PointerPressed="_CapturePointer"
|
||||
PointerReleased="_ReleasePointerCapture" />
|
||||
PointerReleased="_ReleasePointerCapture"
|
||||
SmallChange="1"
|
||||
ValueChanged="_ScrollbarChangeHandler"
|
||||
ViewportSize="10" />
|
||||
</Grid>
|
||||
|
||||
<local:TSFInputControl x:Name="TSFInputControl"
|
||||
@@ -104,18 +106,22 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
CurrentFontInfo="_FontInfoHandler" />
|
||||
|
||||
<Grid x:Name="RendererFailedNotice"
|
||||
x:Load="False"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<Border Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
BorderBrush="{ThemeResource SystemAccentColor}"
|
||||
Margin="8,8,8,8"
|
||||
VerticalAlignment="Center"
|
||||
x:Load="False">
|
||||
<Border Margin="8,8,8,8"
|
||||
Padding="8,8,8,8"
|
||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
BorderBrush="{ThemeResource SystemAccentColor}"
|
||||
BorderThickness="2,2,2,2"
|
||||
CornerRadius="{ThemeResource OverlayCornerRadius}">
|
||||
<StackPanel>
|
||||
<TextBlock HorizontalAlignment="Center" x:Uid="TermControl_RendererFailedTextBlock" TextWrapping="WrapWholeWords"/>
|
||||
<Button Click="_RenderRetryButton_Click" x:Uid="TermControl_RendererRetryButton" HorizontalAlignment="Right" />
|
||||
<TextBlock x:Uid="TermControl_RendererFailedTextBlock"
|
||||
HorizontalAlignment="Center"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<Button x:Uid="TermControl_RendererRetryButton"
|
||||
HorizontalAlignment="Right"
|
||||
Click="_RenderRetryButton_Click" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
<ClCompile Include="TermControl.cpp">
|
||||
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ThrottledFunc.cpp" />
|
||||
<ClCompile Include="TSFInputControl.cpp">
|
||||
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "ThrottledFunc.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
ThrottledFunc<>::ThrottledFunc(ThrottledFunc::Func func, TimeSpan delay, CoreDispatcher dispatcher) :
|
||||
_func{ func },
|
||||
_delay{ delay },
|
||||
_dispatcher{ dispatcher },
|
||||
_isRunPending{}
|
||||
{
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Runs the function later, except if `Run` is called again before
|
||||
// with a new argument, in which case the request will be ignored.
|
||||
// - For more information, read the class' documentation.
|
||||
// - This method is always thread-safe. It can be called multiple times on
|
||||
// different threads.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ThrottledFunc<>::Run()
|
||||
{
|
||||
if (_isRunPending.test_and_set(std::memory_order_acquire))
|
||||
{
|
||||
// already pending
|
||||
return;
|
||||
}
|
||||
|
||||
_dispatcher.RunAsync(CoreDispatcherPriority::Low, [weakThis = this->weak_from_this()]() {
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
DispatcherTimer timer;
|
||||
timer.Interval(self->_delay);
|
||||
timer.Tick([=](auto&&...) {
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
timer.Stop();
|
||||
self->_isRunPending.clear(std::memory_order_release);
|
||||
self->_func();
|
||||
}
|
||||
});
|
||||
timer.Start();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -56,27 +56,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
_dispatcher.RunAsync(CoreDispatcherPriority::Low, [weakThis = this->weak_from_this()]() {
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
DispatcherTimer timer;
|
||||
timer.Interval(self->_delay);
|
||||
timer.Tick([=](auto&&...) {
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
timer.Stop();
|
||||
|
||||
std::optional<std::tuple<Args...>> args;
|
||||
{
|
||||
std::lock_guard guard{ self->_lock };
|
||||
self->_pendingRunArgs.swap(args);
|
||||
}
|
||||
std::apply(self->_func, args.value());
|
||||
}
|
||||
});
|
||||
timer.Start();
|
||||
}
|
||||
});
|
||||
_Fire(_delay, _dispatcher, this->weak_from_this());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -110,12 +90,29 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static winrt::fire_and_forget _Fire(winrt::Windows::Foundation::TimeSpan delay, winrt::Windows::UI::Core::CoreDispatcher dispatcher, std::weak_ptr<ThrottledFunc> weakThis)
|
||||
{
|
||||
co_await winrt::resume_after(delay);
|
||||
co_await winrt::resume_foreground(dispatcher);
|
||||
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
std::optional<std::tuple<Args...>> args;
|
||||
{
|
||||
std::lock_guard guard{ self->_lock };
|
||||
self->_pendingRunArgs.swap(args);
|
||||
}
|
||||
|
||||
std::apply(self->_func, args.value());
|
||||
}
|
||||
}
|
||||
|
||||
Func _func;
|
||||
winrt::Windows::Foundation::TimeSpan _delay;
|
||||
winrt::Windows::UI::Core::CoreDispatcher _dispatcher;
|
||||
|
||||
std::optional<std::tuple<Args...>> _pendingRunArgs;
|
||||
std::mutex _lock;
|
||||
std::optional<std::tuple<Args...>> _pendingRunArgs;
|
||||
};
|
||||
|
||||
// Class Description:
|
||||
@@ -129,11 +126,45 @@ class ThrottledFunc<> : public std::enable_shared_from_this<ThrottledFunc<>>
|
||||
public:
|
||||
using Func = std::function<void()>;
|
||||
|
||||
ThrottledFunc(Func func, winrt::Windows::Foundation::TimeSpan delay, winrt::Windows::UI::Core::CoreDispatcher dispatcher);
|
||||
ThrottledFunc(Func func, winrt::Windows::Foundation::TimeSpan delay, winrt::Windows::UI::Core::CoreDispatcher dispatcher) :
|
||||
_func{ func },
|
||||
_delay{ delay },
|
||||
_dispatcher{ dispatcher }
|
||||
{
|
||||
}
|
||||
|
||||
void Run();
|
||||
// Method Description:
|
||||
// - Runs the function later, except if `Run` is called again before
|
||||
// with a new argument, in which case the request will be ignored.
|
||||
// - For more information, read the class' documentation.
|
||||
// - This method is always thread-safe. It can be called multiple times on
|
||||
// different threads.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
template<typename... MakeArgs>
|
||||
void Run(MakeArgs&&... args)
|
||||
{
|
||||
if (!_isRunPending.test_and_set(std::memory_order_relaxed))
|
||||
{
|
||||
_Fire(_delay, _dispatcher, this->weak_from_this());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static winrt::fire_and_forget _Fire(winrt::Windows::Foundation::TimeSpan delay, winrt::Windows::UI::Core::CoreDispatcher dispatcher, std::weak_ptr<ThrottledFunc> weakThis)
|
||||
{
|
||||
co_await winrt::resume_after(delay);
|
||||
co_await winrt::resume_foreground(dispatcher);
|
||||
|
||||
if (auto self{ weakThis.lock() })
|
||||
{
|
||||
self->_isRunPending.clear(std::memory_order_relaxed);
|
||||
self->_func();
|
||||
}
|
||||
}
|
||||
|
||||
Func _func;
|
||||
winrt::Windows::Foundation::TimeSpan _delay;
|
||||
winrt::Windows::UI::Core::CoreDispatcher _dispatcher;
|
||||
|
||||
@@ -83,7 +83,11 @@
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>dwrite.lib;dxgi.lib;d2d1.lib;d3d11.lib;shcore.lib;winmm.lib;pathcch.lib;propsys.lib;uiautomationcore.lib;Shlwapi.lib;ntdll.lib;user32.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<!-- ControlLib contains a DllMain that we need to force the use of. -->
|
||||
<!--
|
||||
ControlLib contains a DllMain that we need to force the use of.
|
||||
If you don't have this, then you'll see an error like
|
||||
"(init.obj) : error LNK2005: DllMain already defined in MSVCRTD.lib(dll_dllmain_stub.obj)"
|
||||
-->
|
||||
<AdditionalOptions Condition="'$(Platform)'=='Win32'">/INCLUDE:_DllMain@12</AdditionalOptions>
|
||||
<AdditionalOptions Condition="'$(Platform)'!='Win32'">/INCLUDE:DllMain</AdditionalOptions>
|
||||
|
||||
|
||||
@@ -13,12 +13,30 @@ namespace Microsoft.Terminal.Core
|
||||
EmptyBox
|
||||
};
|
||||
|
||||
// TerminalCore declares its own Color struct to avoid depending
|
||||
// on Windows.UI.Color and to avoid passing around unclothed uint32s.
|
||||
// It is supported by til::color for conversions in and out of WinRT land.
|
||||
struct Color
|
||||
{
|
||||
UInt8 R;
|
||||
UInt8 G;
|
||||
UInt8 B;
|
||||
UInt8 A;
|
||||
};
|
||||
|
||||
declare
|
||||
{
|
||||
// Forward declare this parameterized specialization so that it lives
|
||||
// in TerminalCore instead of being flung to the winds of all IDL dependents.
|
||||
interface Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>;
|
||||
}
|
||||
|
||||
interface ICoreAppearance
|
||||
{
|
||||
UInt32 GetColorTableEntry(Int32 index);
|
||||
UInt32 DefaultForeground { get; set; };
|
||||
UInt32 DefaultBackground { get; set; };
|
||||
UInt32 CursorColor { get; set; };
|
||||
Microsoft.Terminal.Core.Color DefaultForeground;
|
||||
Microsoft.Terminal.Core.Color DefaultBackground;
|
||||
Microsoft.Terminal.Core.Color GetColorTableEntry(Int32 index);
|
||||
Microsoft.Terminal.Core.Color CursorColor;
|
||||
CursorStyle CursorShape;
|
||||
UInt32 CursorHeight;
|
||||
};
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace Microsoft.Terminal.Core
|
||||
|
||||
Boolean ForceVTInput;
|
||||
|
||||
Windows.Foundation.IReference<UInt32> TabColor;
|
||||
Windows.Foundation.IReference<UInt32> StartingTabColor;
|
||||
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> TabColor;
|
||||
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> StartingTabColor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -128,12 +128,12 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
}
|
||||
else
|
||||
{
|
||||
_tabColor = til::color(settings.TabColor().Value() | 0xff000000);
|
||||
_tabColor = til::color{ settings.TabColor().Value() }.with_alpha(0xff);
|
||||
}
|
||||
|
||||
if (!_startingTabColor && settings.StartingTabColor())
|
||||
{
|
||||
_startingTabColor = til::color(settings.StartingTabColor().Value() | 0xff000000);
|
||||
_startingTabColor = til::color{ settings.StartingTabColor().Value() }.with_alpha(0xff);
|
||||
}
|
||||
|
||||
if (_pfnTabColorChanged)
|
||||
@@ -153,17 +153,17 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
// CoreAppearance object.
|
||||
// Arguments:
|
||||
// - appearance: an ICoreAppearance with new settings values for us to use.
|
||||
void Terminal::UpdateAppearance(const ICoreAppearance appearance)
|
||||
void Terminal::UpdateAppearance(const ICoreAppearance& appearance)
|
||||
{
|
||||
// Set the default background as transparent to prevent the
|
||||
// DX layer from overwriting the background image or acrylic effect
|
||||
til::color newBackgroundColor{ static_cast<COLORREF>(appearance.DefaultBackground()) };
|
||||
til::color newBackgroundColor{ appearance.DefaultBackground() };
|
||||
_defaultBg = newBackgroundColor.with_alpha(0);
|
||||
_defaultFg = appearance.DefaultForeground();
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
_colorTable.at(i) = appearance.GetColorTableEntry(i);
|
||||
_colorTable.at(i) = til::color{ appearance.GetColorTableEntry(i) };
|
||||
}
|
||||
|
||||
CursorType cursorShape = CursorType::VerticalBar;
|
||||
@@ -193,7 +193,7 @@ void Terminal::UpdateAppearance(const ICoreAppearance appearance)
|
||||
if (_buffer)
|
||||
{
|
||||
_buffer->GetCursor().SetStyle(appearance.CursorHeight(),
|
||||
appearance.CursorColor(),
|
||||
til::color{ appearance.CursorColor() },
|
||||
cursorShape);
|
||||
}
|
||||
|
||||
@@ -1138,8 +1138,8 @@ void Terminal::SetCursorPositionChangedCallback(std::function<void()> pfn) noexc
|
||||
// Method Description:
|
||||
// - Allows setting a callback for when the background color is changed
|
||||
// Arguments:
|
||||
// - pfn: a function callback that takes a uint32 (DWORD COLORREF) color in the format 0x00BBGGRR
|
||||
void Terminal::SetBackgroundCallback(std::function<void(const COLORREF)> pfn) noexcept
|
||||
// - pfn: a function callback that takes a color
|
||||
void Terminal::SetBackgroundCallback(std::function<void(const til::color)> pfn) noexcept
|
||||
{
|
||||
_pfnBackgroundColorChanged.swap(pfn);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
Microsoft::Console::Render::IRenderTarget& renderTarget);
|
||||
|
||||
void UpdateSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings);
|
||||
void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance appearance);
|
||||
void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance);
|
||||
|
||||
// Write goes through the parser
|
||||
void Write(std::wstring_view stringView);
|
||||
@@ -200,7 +200,7 @@ public:
|
||||
void SetCopyToClipboardCallback(std::function<void(const std::wstring_view&)> pfn) noexcept;
|
||||
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
|
||||
void SetCursorPositionChangedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetBackgroundCallback(std::function<void(const COLORREF)> pfn) noexcept;
|
||||
void SetBackgroundCallback(std::function<void(const til::color)> pfn) noexcept;
|
||||
void TaskbarProgressChangedCallback(std::function<void()> pfn) noexcept;
|
||||
|
||||
void SetCursorOn(const bool isOn);
|
||||
@@ -238,7 +238,7 @@ private:
|
||||
std::function<void(const std::wstring_view&)> _pfnTitleChanged;
|
||||
std::function<void(const std::wstring_view&)> _pfnCopyToClipboard;
|
||||
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
|
||||
std::function<void(const COLORREF)> _pfnBackgroundColorChanged;
|
||||
std::function<void(const til::color)> _pfnBackgroundColorChanged;
|
||||
std::function<void()> _pfnCursorPositionChanged;
|
||||
std::function<void(const std::optional<til::color>)> _pfnTabColorChanged;
|
||||
std::function<void()> _pfnTaskbarProgressChanged;
|
||||
@@ -251,9 +251,10 @@ private:
|
||||
std::optional<til::color> _tabColor;
|
||||
std::optional<til::color> _startingTabColor;
|
||||
|
||||
// This is still stored as a COLORREF because it interacts with some code in ConTypes
|
||||
std::array<COLORREF, XTERM_COLOR_TABLE_SIZE> _colorTable;
|
||||
COLORREF _defaultFg;
|
||||
COLORREF _defaultBg;
|
||||
til::color _defaultFg;
|
||||
til::color _defaultBg;
|
||||
CursorType _defaultCursorShape;
|
||||
bool _screenReversed;
|
||||
mutable Microsoft::Console::Render::BlinkingState _blinkingState;
|
||||
|
||||
@@ -3,5 +3,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// We're suspending the inclusion of til here so that we can include
|
||||
// it after some of our C++/WinRT headers.
|
||||
#define BLOCK_TIL
|
||||
#include <LibraryIncludes.h>
|
||||
#include "winrt/Windows.Foundation.h"
|
||||
|
||||
#include "winrt/Microsoft.Terminal.Core.h"
|
||||
#include <til.h>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user