Migrate OSS up to 84e30bcd3
This commit is contained in:
commit
ee6ca81d70
3
.github/actions/spelling/allow/allow.txt
vendored
3
.github/actions/spelling/allow/allow.txt
vendored
|
@ -25,6 +25,7 @@ hyperlinks
|
|||
img
|
||||
It'd
|
||||
kje
|
||||
liga
|
||||
lje
|
||||
maxed
|
||||
mru
|
||||
|
@ -42,8 +43,10 @@ reserialize
|
|||
reserializes
|
||||
runtimes
|
||||
shcha
|
||||
slnt
|
||||
Sos
|
||||
timestamped
|
||||
TLDR
|
||||
tokenizes
|
||||
tonos
|
||||
tshe
|
||||
|
|
9
.github/actions/spelling/allow/apis.txt
vendored
9
.github/actions/spelling/allow/apis.txt
vendored
|
@ -13,6 +13,7 @@ cmdletbinding
|
|||
COLORPROPERTY
|
||||
colspan
|
||||
COMDLG
|
||||
comparand
|
||||
cstdint
|
||||
CXICON
|
||||
CYICON
|
||||
|
@ -25,6 +26,7 @@ DWORDLONG
|
|||
environstrings
|
||||
EXPCMDFLAGS
|
||||
EXPCMDSTATE
|
||||
filetime
|
||||
FILTERSPEC
|
||||
FORCEFILESYSTEM
|
||||
FORCEMINIMIZE
|
||||
|
@ -75,6 +77,7 @@ llu
|
|||
localtime
|
||||
lround
|
||||
LSHIFT
|
||||
memicmp
|
||||
mov
|
||||
msappx
|
||||
MULTIPLEUSE
|
||||
|
@ -124,6 +127,8 @@ smoothstep
|
|||
snprintf
|
||||
spsc
|
||||
sregex
|
||||
SRWLOC
|
||||
SRWLOCK
|
||||
STDCPP
|
||||
STDMETHOD
|
||||
strchr
|
||||
|
@ -134,8 +139,10 @@ Subpage
|
|||
syscall
|
||||
TBPF
|
||||
THEMECHANGED
|
||||
tlg
|
||||
tmp
|
||||
tolower
|
||||
toupper
|
||||
TTask
|
||||
TVal
|
||||
UChar
|
||||
|
@ -152,6 +159,7 @@ XDocument
|
|||
XElement
|
||||
xfacet
|
||||
xhash
|
||||
XIcon
|
||||
xiosbase
|
||||
xlocale
|
||||
xlocbuf
|
||||
|
@ -167,3 +175,4 @@ xstddef
|
|||
xstring
|
||||
xtree
|
||||
xutility
|
||||
YIcon
|
||||
|
|
1
.github/actions/spelling/allow/fonts.txt
vendored
1
.github/actions/spelling/allow/fonts.txt
vendored
|
@ -7,3 +7,4 @@ Iosevka
|
|||
MDL
|
||||
Monofur
|
||||
Segoe
|
||||
wght
|
||||
|
|
3
.github/actions/spelling/allow/microsoft.txt
vendored
3
.github/actions/spelling/allow/microsoft.txt
vendored
|
@ -28,6 +28,7 @@ LKG
|
|||
mfcribbon
|
||||
microsoft
|
||||
microsoftonline
|
||||
MSAA
|
||||
msixbundle
|
||||
MSVC
|
||||
muxc
|
||||
|
@ -44,6 +45,7 @@ pscustomobject
|
|||
QWORD
|
||||
robocopy
|
||||
SACLs
|
||||
sdkddkver
|
||||
Shobjidl
|
||||
Skype
|
||||
SRW
|
||||
|
@ -61,6 +63,7 @@ Virtualization
|
|||
visualstudio
|
||||
vscode
|
||||
VSTHRD
|
||||
winsdkver
|
||||
wlk
|
||||
wslpath
|
||||
wtl
|
||||
|
|
26
.github/actions/spelling/expect/expect.txt
vendored
26
.github/actions/spelling/expect/expect.txt
vendored
|
@ -14,7 +14,6 @@ ACTIVEBORDER
|
|||
ACTIVECAPTION
|
||||
adaa
|
||||
ADDALIAS
|
||||
ADDB
|
||||
ADDREF
|
||||
addressof
|
||||
ADDSTRING
|
||||
|
@ -50,6 +49,7 @@ APARTMENTTHREADED
|
|||
APCs
|
||||
api
|
||||
APIENTRY
|
||||
apimswincoresynchl
|
||||
apiset
|
||||
APPBARDATA
|
||||
appconsult
|
||||
|
@ -114,6 +114,7 @@ Backgrounder
|
|||
backgrounding
|
||||
backport
|
||||
backstory
|
||||
barbaz
|
||||
Batang
|
||||
baz
|
||||
Bazz
|
||||
|
@ -379,6 +380,7 @@ cplusplus
|
|||
cpp
|
||||
CPPCORECHECK
|
||||
cppcorecheckrules
|
||||
cppm
|
||||
cpprest
|
||||
cpprestsdk
|
||||
cppwinrt
|
||||
|
@ -496,7 +498,6 @@ DEADCHAR
|
|||
dealloc
|
||||
Debian
|
||||
debolden
|
||||
debounce
|
||||
debugtype
|
||||
DECALN
|
||||
DECANM
|
||||
|
@ -757,7 +758,6 @@ filepath
|
|||
FILESUBTYPE
|
||||
FILESYSPATH
|
||||
filesystem
|
||||
FILETIME
|
||||
FILETYPE
|
||||
fileurl
|
||||
FILEW
|
||||
|
@ -795,6 +795,7 @@ FONTTYPE
|
|||
FONTWEIGHT
|
||||
FONTWIDTH
|
||||
FONTWINDOW
|
||||
fooo
|
||||
forceinline
|
||||
FORCEOFFFEEDBACK
|
||||
FORCEONFEEDBACK
|
||||
|
@ -981,7 +982,7 @@ hostlib
|
|||
Hostx
|
||||
HPA
|
||||
HPAINTBUFFER
|
||||
hpcon
|
||||
HPCON
|
||||
hpj
|
||||
hpp
|
||||
HPR
|
||||
|
@ -1113,6 +1114,7 @@ interop
|
|||
interoperability
|
||||
inthread
|
||||
intptr
|
||||
intrin
|
||||
intsafe
|
||||
INVALIDARG
|
||||
INVALIDATERECT
|
||||
|
@ -1165,6 +1167,7 @@ IWin
|
|||
IWindow
|
||||
IXaml
|
||||
IXMP
|
||||
ixx
|
||||
jconcpp
|
||||
JOBOBJECT
|
||||
JOBOBJECTINFOCLASS
|
||||
|
@ -1643,6 +1646,7 @@ oss
|
|||
ostream
|
||||
ostringstream
|
||||
ouicompat
|
||||
OUnter
|
||||
outdir
|
||||
outfile
|
||||
Outof
|
||||
|
@ -1653,6 +1657,7 @@ Outptr
|
|||
OVERLAPPEDWINDOW
|
||||
OWNDC
|
||||
OWNERDRAWFIXED
|
||||
packagename
|
||||
packageuwp
|
||||
PACKCOORD
|
||||
PACKVERSION
|
||||
|
@ -1944,7 +1949,6 @@ reingest
|
|||
Relayout
|
||||
RELBINPATH
|
||||
remoting
|
||||
Remoting
|
||||
renamer
|
||||
renderengine
|
||||
rendersize
|
||||
|
@ -1985,6 +1989,7 @@ rhs
|
|||
RIGHTALIGN
|
||||
RIGHTBUTTON
|
||||
riid
|
||||
Rike
|
||||
RIPMSG
|
||||
RIS
|
||||
RMENU
|
||||
|
@ -2033,7 +2038,6 @@ scanline
|
|||
schemename
|
||||
SCL
|
||||
scm
|
||||
scprintf
|
||||
SCRBUF
|
||||
SCRBUFSIZE
|
||||
screenbuffer
|
||||
|
@ -2065,7 +2069,7 @@ selectany
|
|||
SELECTEDFONT
|
||||
SELECTSTRING
|
||||
Selfhosters
|
||||
serializers
|
||||
SERIALIZERS
|
||||
SERVERDLL
|
||||
SETACTIVE
|
||||
SETBUDDYINT
|
||||
|
@ -2208,6 +2212,7 @@ stoi
|
|||
stol
|
||||
stoul
|
||||
stoutapot
|
||||
Stri
|
||||
strikethrough
|
||||
stringstream
|
||||
STRINGTABLE
|
||||
|
@ -2306,7 +2311,6 @@ testmddefinition
|
|||
testmode
|
||||
testname
|
||||
testnameprefix
|
||||
testnetv
|
||||
TESTNULL
|
||||
testpass
|
||||
testpasses
|
||||
|
@ -2342,7 +2346,6 @@ TITLEISLINKNAME
|
|||
TJson
|
||||
TLambda
|
||||
TLEN
|
||||
Tlg
|
||||
Tlgdata
|
||||
TMAE
|
||||
TMPF
|
||||
|
@ -2542,7 +2545,6 @@ VMs
|
|||
VPA
|
||||
VPATH
|
||||
VPR
|
||||
VPrintf
|
||||
VProc
|
||||
VRaw
|
||||
VREDRAW
|
||||
|
@ -2769,11 +2771,9 @@ XCount
|
|||
xdy
|
||||
XEncoding
|
||||
xes
|
||||
Xes
|
||||
xff
|
||||
XFile
|
||||
XFORM
|
||||
xIcon
|
||||
XManifest
|
||||
XMath
|
||||
XMFLOAT
|
||||
|
@ -2781,7 +2781,6 @@ xml
|
|||
xmlns
|
||||
xor
|
||||
xorg
|
||||
Xpath
|
||||
XPosition
|
||||
XResource
|
||||
xsd
|
||||
|
@ -2807,7 +2806,6 @@ YCast
|
|||
YCENTER
|
||||
YCount
|
||||
YDPI
|
||||
yIcon
|
||||
yml
|
||||
YOffset
|
||||
YPosition
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
||||
name: Spell checking
|
||||
on:
|
||||
pull_request_target:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
spelling:
|
||||
name: Spell checking
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout-merge
|
||||
if: "contains(github.event_name, 'pull_request')"
|
||||
uses: actions/checkout@v2.0.0
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: refs/pull/${{github.event.pull_request.number}}/merge
|
||||
- name: checkout
|
||||
if: "!contains(github.event_name, 'pull_request')"
|
||||
uses: actions/checkout@v2.0.0
|
||||
- uses: check-spelling/check-spelling@v0.0.18
|
||||
uses: actions/checkout@v2
|
||||
- uses: check-spelling/check-spelling@v0.0.19
|
|
@ -9,7 +9,7 @@ $payloadDir = "HelixPayload\$Configuration\$Platform"
|
|||
|
||||
$repoDirectory = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "..\..\"
|
||||
$nugetPackagesDir = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "packages"
|
||||
|
||||
|
||||
# Create the payload directory. Remove it if it already exists.
|
||||
If(test-path $payloadDir)
|
||||
{
|
||||
|
@ -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\Microsoft.Taef.10.58.210305002\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.58.210305002\build\Binaries\$Platform\NetFx4.5\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\NetFx4.5\*" $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\"
|
||||
|
@ -59,7 +59,7 @@ Copy-Item "build\Helix\EnsureMachineState.ps1" "$payloadDir"
|
|||
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\appx\CascadiaPackage_0.0.1.0_$Platform.msix" $payloadDir\CascadiaPackage.zip
|
||||
|
||||
# Rename it to extension of ZIP because Expand-Archive is real sassy on the build machines
|
||||
# and refuses to unzip it because of its file extension while on a desktop, it just
|
||||
# and refuses to unzip it because of its file extension while on a desktop, it just
|
||||
# does the job without complaining.
|
||||
|
||||
# Extract the APPX package
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.TestContent" version="1.0.1" />
|
||||
<package id="Microsoft.Taef" version="10.58.210305002" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" 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="Microsoft.Taef" version="10.58.210305002" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -12,4 +12,4 @@ steps:
|
|||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\GenerateTestProjFile.ps1
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.58.210305002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
buildPlatform: ${{ parameters.platform }}
|
||||
openHelixTargetQueues: ${{ parameters.openHelixTargetQueues }}
|
||||
artifactsDir: $(Build.SourcesDirectory)\Artifacts
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.58.210305002\build\Binaries\$(buildPlatform)
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\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}}'
|
||||
|
||||
|
||||
|
@ -147,4 +147,3 @@ jobs:
|
|||
projects: build\Helix\RunTestsInHelix.proj
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:IsExternal=true /p:Creator=Terminal /p:HelixTargetQueues=$(openHelixTargetQueues)'
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2021</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>10</VersionMinor>
|
||||
<VersionMinor>11</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
105
doc/specs/#1790 - Font features and axes-spec.md
Normal file
105
doc/specs/#1790 - Font features and axes-spec.md
Normal file
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
author: Pankaj Bhojwani, pabhojwa@microsoft.com
|
||||
created on: 2021-6-17
|
||||
last updated: 2021-6-23
|
||||
issue id: #1790
|
||||
---
|
||||
|
||||
# Font features and axes of variation
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec outlines how we can allow users to specify font features and axes of variation for fonts in Windows Terminal. Font features include things like being able to specify whether ligatures should be used as well as the specific stylistic set used for a font. Axes of variation commonly include things like weight and slant but can also include fancier things like shadow distance, depending on the font.
|
||||
|
||||
## Inspiration
|
||||
|
||||
Reference: [#1790](https://github.com/microsoft/terminal/issues/1790)
|
||||
|
||||
Currently, if a font has ligatures, we offer no way for a user to disable them. Many users would like the option to do so, and would also like the ability to choose stylistic sets for fonts - for example, at the time of this writing, Cascadia Code offers 4 stylistic sets but we offer no way for users to specify any of them.
|
||||
|
||||
In a similar vein, many fonts allow for setting variations on the font along certain attributes, commonly referred to as 'axes of variation'. We can offer users more font customization options by allowing them to configure these font variations.
|
||||
|
||||
## Solution Design
|
||||
|
||||
### Font features
|
||||
|
||||
It is already possible to pass in a list of [font feature structs](https://docs.microsoft.com/en-us/windows/win32/api/dwrite/ns-dwrite-dwrite_font_feature) to DWrite for it to handle. A font feature struct contains only 2 things:
|
||||
|
||||
1. A font feature tag
|
||||
2. A parameter value
|
||||
|
||||
A font feature tag is constructed using a 4-character feature tag and the parameter value defines how the feature is applied. For most features, the parameter value is simply treated as a binary value - a value of 0 means the feature is not applied and a non-zero value means the feature is applied. For example, a font feature struct like {'ss03', 1} enables stylistic set 3 for the font and a font feature struct like {'liga', 0} disables ligatures. (Technically, the feature tag is _constructed_ with the 4-character tag and is not the 4-character tag itself, but they are treated the same in the example here for brevity's sake).
|
||||
|
||||
Currently, we pass in to DWrite a null value for the list of features to apply to the font. This causes DWrite to automatically apply a ['standard' list](https://github.com/fdwr/TextLayoutSampler/blob/master/DrawableObject.ixx#L802) of font features to the font. Naturally, passing in our own list of font features to DWrite means DWrite will _only_ apply the features we defined, and no longer apply the standard list. Since the standard list contains 11 features, we need to consider how we can allow users to specify 1 additional feature or delete 1 of the standard features without needing to redefine all the others.
|
||||
|
||||
We will do this by allowing users to define a dictionary in their settings.json file, where the keys are the 4-character feature tags and the values are the parameter values. This dictionary will then get applied to our internal dictionary (which will contain the standard list of 11 features with their parameter values), meaning that any new key-value pairs will get added to our dictionary and any existing key-value pairs will get updated. Finally, this 'merged' dictionary will be what we use to construct the list of features to pass into DWrite.
|
||||
|
||||
### Axes of variation
|
||||
|
||||
Specifying axes of variation is done in an extremely similar manner to the way font features are specified - a 4-character tag is used to specify which font axis is being modified and a numerical value is provided to specify the value the axis should be set to. For example, {'slnt', 20} specifies that the 'slant' axis should be set to 20.
|
||||
|
||||
There is also a standard list of axes of variation, and each axis has its own default. We will approach this the same way we approached font features, by allowing users to specify additional features or omit features without needing to redefine the defaults.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
Users will be able to add a new setting to their font objects (added in [#10433](https://github.com/microsoft/terminal/pull/10433)). The resultant font object may look something like this
|
||||
|
||||
```json
|
||||
"font": {
|
||||
"face": "Cascadia Code",
|
||||
"size": 12,
|
||||
"features": {
|
||||
"ss03": 1,
|
||||
"liga": 0
|
||||
},
|
||||
"axes": {
|
||||
"slnt": 20.5
|
||||
}
|
||||
}
|
||||
```
|
||||
There is one point to note here about clashing. For example, if a user has the old "weight" setting defined _as well as_ a "wght" axis defined, we will only use the "wght" axis value. We prioritize that value for a few reasons:
|
||||
|
||||
1. It is the more recent addition to our settings model. Thus, it is likely that a user that has defined both values probably just forgot to remove the old value.
|
||||
2. It is the more precise value, it is a specific float value whereas the the old "weight" setting is an enum (that eventually gets mapped to a float value).
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
Should not affect accessibility.
|
||||
|
||||
### Security
|
||||
|
||||
Should not affect security.
|
||||
|
||||
### Reliability
|
||||
|
||||
Aside from additional parsing required for the settings file (which inherently offers more locations for parsing to fail), we need to be careful about badly formed/non-existant feature tags or axes specified in the user-defined dictionaries. We must make sure to ignore such declarations (perhaps alongside emitting a warning to the user) and only apply those that are correctly formed and exist.
|
||||
|
||||
### Compatibility
|
||||
|
||||
Older versions of Windows may not have the DWrite updates that allow for defining font features and axes of variation. We must make sure to fallback to the current implementation in these cases.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
Currently when rendering a run of text, if we detect that the given run is simple we will use a shortcut to obtain the glyphs needed, skipping over an expensive `GetGlyphs` call to DWrite. However, when the default feature list is changed in any way (either by adding a new feature or removing one of the defaults), there is no way for us to detect beforehand how the font glyphs would change.
|
||||
|
||||
This means that as long as the user requests a change to the default font feature list, we will _always_ skip the shortcut and call the expensive `GetGlyphs` function for every run of text.
|
||||
|
||||
This will naturally cause a performance cost that we will have to bear for this feature. However, it is worth noting that there are a fair number of glyphs that will cause a run of text to be deemed "not simple" (and thus cause us to call `GetGlyphs` anyway), for example when using Cascadia Code, any run of text that has the letters 'i', 'j', 'l', 'n', 'w' or 'x' is not considered simple (because those glyphs have localized variants).
|
||||
|
||||
## Potential Issues
|
||||
|
||||
See performance issues above.
|
||||
|
||||
## Future considerations
|
||||
|
||||
DWrite additionally offers the ability to vary the font features across runs of text. However, for our initial implementation of this feature, we will only apply font features to the entire buffer. If/when we decide to allow specifying font features for particular runs of text, we can lean into our existing mechanisms of splitting up runs of text to implement that.
|
||||
|
||||
We will also need to consider how we want to represent this in the settings UI. This is slightly more complex than other settings since users should be allowed to manually input 4-character tags.
|
||||
|
||||
## Resources
|
||||
|
||||
[DWRITE_FONT_FEATURE structure](https://docs.microsoft.com/en-us/windows/win32/api/dwrite/ns-dwrite-dwrite_font_feature)
|
||||
|
||||
[DWRITE_FONT_AXIS_VALUE structure](https://docs.microsoft.com/en-us/windows/win32/api/dwrite_3/ns-dwrite_3-dwrite_font_axis_value)
|
|
@ -19,7 +19,7 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
<ClCompile>
|
||||
|
@ -148,13 +148,13 @@
|
|||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<!-- ========================= XAML files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- DON'T PUT XAML FILES HERE! Put them in SampleAppLib.vcxproj -->
|
||||
|
@ -77,13 +77,13 @@
|
|||
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.2" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{b4427499-9fde-4208-b456-5bc580637633}</ProjectGuid>
|
||||
|
@ -121,15 +121,15 @@
|
|||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets'))" />
|
||||
</Target>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.2" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -212,7 +212,7 @@ constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexce
|
|||
#ifdef UNIT_TESTING
|
||||
|
||||
#define LOG_ATTR(attr) (Log::Comment(NoThrowString().Format( \
|
||||
L#attr L"=%s", VerifyOutputTraits<TextAttribute>::ToString(attr).GetBuffer())))
|
||||
L## #attr L"=%s", VerifyOutputTraits<TextAttribute>::ToString(attr).GetBuffer())))
|
||||
|
||||
namespace WEX
|
||||
{
|
||||
|
|
|
@ -265,3 +265,8 @@ const OutputCellView* TextBufferCellIterator::operator->() const noexcept
|
|||
{
|
||||
return &_view;
|
||||
}
|
||||
|
||||
COORD TextBufferCellIterator::Pos() const noexcept
|
||||
{
|
||||
return _pos;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
const OutputCellView& operator*() const noexcept;
|
||||
const OutputCellView* operator->() const noexcept;
|
||||
|
||||
COORD Pos() const noexcept;
|
||||
|
||||
protected:
|
||||
void _SetPos(const COORD newPos);
|
||||
void _GenerateView();
|
||||
|
|
|
@ -16,6 +16,7 @@ using namespace WEX::TestExecution;
|
|||
using namespace WEX::Common;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
|
||||
namespace SettingsModelLocalTests
|
||||
{
|
||||
|
@ -1970,9 +1971,9 @@ namespace SettingsModelLocalTests
|
|||
auto settings = implementation::CascadiaSettings::FromJson(settingsObject);
|
||||
|
||||
VERIFY_ARE_EQUAL(3u, settings->_globals->_actionMap->_KeyMap.size());
|
||||
VERIFY_IS_NULL(settings->_globals->_actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('a') }));
|
||||
VERIFY_IS_NULL(settings->_globals->_actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('b') }));
|
||||
VERIFY_IS_NULL(settings->_globals->_actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('c') }));
|
||||
VERIFY_IS_NULL(settings->_globals->_actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('a') }));
|
||||
VERIFY_IS_NULL(settings->_globals->_actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('b') }));
|
||||
VERIFY_IS_NULL(settings->_globals->_actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('c') }));
|
||||
|
||||
for (const auto& warning : settings->_globals->_keybindingsWarnings)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ using namespace winrt::Microsoft::Terminal::Control;
|
|||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
|
||||
namespace SettingsModelLocalTests
|
||||
{
|
||||
|
@ -141,7 +142,7 @@ namespace SettingsModelLocalTests
|
|||
L"Try unbinding a key using `\"unbound\"` to unbind the key"));
|
||||
actionMap->LayerJson(bindings2Json);
|
||||
VERIFY_ARE_EQUAL(1u, actionMap->_KeyMap.size());
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('c') }));
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('c') }));
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Try unbinding a key using `null` to unbind the key"));
|
||||
|
@ -151,7 +152,7 @@ namespace SettingsModelLocalTests
|
|||
// Then try layering in the bad setting
|
||||
actionMap->LayerJson(bindings3Json);
|
||||
VERIFY_ARE_EQUAL(1u, actionMap->_KeyMap.size());
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('c') }));
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('c') }));
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Try unbinding a key using an unrecognized command to unbind the key"));
|
||||
|
@ -161,7 +162,7 @@ namespace SettingsModelLocalTests
|
|||
// Then try layering in the bad setting
|
||||
actionMap->LayerJson(bindings4Json);
|
||||
VERIFY_ARE_EQUAL(1u, actionMap->_KeyMap.size());
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('c') }));
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('c') }));
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Try unbinding a key using a straight up invalid value to unbind the key"));
|
||||
|
@ -171,13 +172,13 @@ namespace SettingsModelLocalTests
|
|||
// Then try layering in the bad setting
|
||||
actionMap->LayerJson(bindings5Json);
|
||||
VERIFY_ARE_EQUAL(1u, actionMap->_KeyMap.size());
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('c') }));
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('c') }));
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Try unbinding a key that wasn't bound at all"));
|
||||
actionMap->LayerJson(bindings2Json);
|
||||
VERIFY_ARE_EQUAL(1u, actionMap->_KeyMap.size());
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ KeyModifiers::Ctrl, static_cast<int32_t>('c') }));
|
||||
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('c') }));
|
||||
}
|
||||
|
||||
void KeyBindingsTests::TestArbitraryArgs()
|
||||
|
@ -676,7 +677,7 @@ namespace SettingsModelLocalTests
|
|||
actionMap->LayerJson(bindings0Json);
|
||||
VERIFY_ARE_EQUAL(1u, actionMap->_KeyMap.size());
|
||||
const auto& kbd{ actionMap->GetKeyBindingForAction(ShortcutAction::CloseWindow) };
|
||||
VerifyKeyChordEquality({ KeyModifiers::Ctrl, static_cast<int32_t>('A') }, kbd);
|
||||
VerifyKeyChordEquality({ VirtualKeyModifiers::Control, static_cast<int32_t>('A') }, kbd);
|
||||
}
|
||||
{
|
||||
Log::Comment(L"command with args");
|
||||
|
@ -687,7 +688,7 @@ namespace SettingsModelLocalTests
|
|||
args->SingleLine(true);
|
||||
|
||||
const auto& kbd{ actionMap->GetKeyBindingForAction(ShortcutAction::CopyText, *args) };
|
||||
VerifyKeyChordEquality({ KeyModifiers::Ctrl, static_cast<int32_t>('B') }, kbd);
|
||||
VerifyKeyChordEquality({ VirtualKeyModifiers::Control, static_cast<int32_t>('B') }, kbd);
|
||||
}
|
||||
{
|
||||
Log::Comment(L"command with new terminal args");
|
||||
|
@ -699,7 +700,7 @@ namespace SettingsModelLocalTests
|
|||
auto args{ winrt::make_self<implementation::NewTabArgs>(*newTerminalArgs) };
|
||||
|
||||
const auto& kbd{ actionMap->GetKeyBindingForAction(ShortcutAction::NewTab, *args) };
|
||||
VerifyKeyChordEquality({ KeyModifiers::Ctrl, static_cast<int32_t>('C') }, kbd);
|
||||
VerifyKeyChordEquality({ VirtualKeyModifiers::Control, static_cast<int32_t>('C') }, kbd);
|
||||
}
|
||||
{
|
||||
Log::Comment(L"command with hidden args");
|
||||
|
@ -707,7 +708,7 @@ namespace SettingsModelLocalTests
|
|||
VERIFY_ARE_EQUAL(4u, actionMap->_KeyMap.size());
|
||||
|
||||
const auto& kbd{ actionMap->GetKeyBindingForAction(ShortcutAction::ToggleCommandPalette) };
|
||||
VerifyKeyChordEquality({ KeyModifiers::Ctrl | KeyModifiers::Shift, static_cast<int32_t>('P') }, kbd);
|
||||
VerifyKeyChordEquality({ VirtualKeyModifiers::Control | VirtualKeyModifiers::Shift, static_cast<int32_t>('P') }, kbd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,16 +26,18 @@ public:
|
|||
static const winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs GetActionAndArgs(const winrt::Microsoft::Terminal::Settings::Model::ActionMap& actionMap,
|
||||
const winrt::Microsoft::Terminal::Control::KeyChord& kc)
|
||||
{
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
|
||||
std::wstring buffer{ L"" };
|
||||
if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::Control::KeyModifiers::Ctrl))
|
||||
if (WI_IsFlagSet(kc.Modifiers(), VirtualKeyModifiers::Control))
|
||||
{
|
||||
buffer += L"Ctrl+";
|
||||
}
|
||||
if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::Control::KeyModifiers::Shift))
|
||||
if (WI_IsFlagSet(kc.Modifiers(), VirtualKeyModifiers::Shift))
|
||||
{
|
||||
buffer += L"Shift+";
|
||||
}
|
||||
if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::Control::KeyModifiers::Alt))
|
||||
if (WI_IsFlagSet(kc.Modifiers(), VirtualKeyModifiers::Menu))
|
||||
{
|
||||
buffer += L"Alt+";
|
||||
}
|
||||
|
|
|
@ -97,6 +97,6 @@
|
|||
|
||||
<!-- We actually can just straight up reference MUX here, it's fine -->
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestExecutor.WinRTCore">
|
||||
<HintPath>$(OpenConsoleDir)\packages\Microsoft.Taef.10.58.210305002\lib\Microsoft.VisualStudio.TestPlatform.TestExecutor.WinRTCore.winmd</HintPath>
|
||||
<HintPath>$(OpenConsoleDir)\packages\Microsoft.Taef.10.60.210621002\lib\Microsoft.VisualStudio.TestPlatform.TestExecutor.WinRTCore.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
|
||||
<!-- This path is _relative to the .winmd_ -->
|
||||
|
|
|
@ -172,7 +172,6 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) :
|
|||
_desiredFont{ L"Consolas", 0, DEFAULT_FONT_WEIGHT, { 0, 14 }, CP_UTF8 },
|
||||
_actualFont{ L"Consolas", 0, DEFAULT_FONT_WEIGHT, { 0, 14 }, CP_UTF8, false },
|
||||
_uiaProvider{ nullptr },
|
||||
_uiaProviderInitialized{ false },
|
||||
_currentDpi{ USER_DEFAULT_SCREEN_DPI },
|
||||
_pfnWriteCallback{ nullptr },
|
||||
_multiClickTime{ 500 } // this will be overwritten by the windows system double-click time
|
||||
|
@ -324,26 +323,22 @@ void HwndTerminal::_UpdateFont(int newDpi)
|
|||
|
||||
IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
|
||||
{
|
||||
if (nullptr == _uiaProvider && !_uiaProviderInitialized)
|
||||
// If TermControlUiaProvider throws during construction,
|
||||
// we don't want to try constructing an instance again and again.
|
||||
// _uiaProviderInitialized helps us prevent this.
|
||||
if (!_uiaProviderInitialized)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> lock;
|
||||
try
|
||||
{
|
||||
#pragma warning(suppress : 26441) // The lock is named, this appears to be a false positive
|
||||
lock = _terminal->LockForWriting();
|
||||
if (_uiaProviderInitialized)
|
||||
{
|
||||
return _uiaProvider.Get();
|
||||
}
|
||||
|
||||
auto lock = _terminal->LockForWriting();
|
||||
LOG_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, this->GetUiaData(), this));
|
||||
_uiaProviderInitialized = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_HR(wil::ResultFromCaughtException());
|
||||
_uiaProvider = nullptr;
|
||||
}
|
||||
_uiaProviderInitialized = true;
|
||||
}
|
||||
|
||||
return _uiaProvider.Get();
|
||||
|
|
|
@ -73,7 +73,6 @@ private:
|
|||
FontInfoDesired _desiredFont;
|
||||
FontInfo _actualFont;
|
||||
int _currentDpi;
|
||||
bool _uiaProviderInitialized;
|
||||
std::function<void(wchar_t*)> _pfnWriteCallback;
|
||||
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
|
||||
|
||||
|
@ -83,6 +82,7 @@ private:
|
|||
std::unique_ptr<::Microsoft::Console::Render::DxEngine> _renderEngine;
|
||||
|
||||
bool _focused{ false };
|
||||
bool _uiaProviderInitialized{ false };
|
||||
|
||||
std::chrono::milliseconds _multiClickTime;
|
||||
unsigned int _multiClickCounter{};
|
||||
|
|
|
@ -56,16 +56,17 @@ HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray,
|
|||
siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
|
||||
|
||||
// Append a "\." to the given path, so that this will work in "C:\"
|
||||
auto cmdline{ wil::str_printf<std::wstring>(LR"-("%s" -d "%s\.")-", GetWtExePath().c_str(), pszName.get()) };
|
||||
auto path{ wil::str_printf<std::wstring>(LR"-(%s\.)-", pszName.get()) };
|
||||
auto cmdline{ wil::str_printf<std::wstring>(LR"-("%s" -d "%s")-", GetWtExePath().c_str(), path.c_str()) };
|
||||
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(
|
||||
nullptr,
|
||||
nullptr, // lpApplicationName
|
||||
cmdline.data(),
|
||||
nullptr, // lpProcessAttributes
|
||||
nullptr, // lpThreadAttributes
|
||||
false, // bInheritHandles
|
||||
EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, // dwCreationFlags
|
||||
nullptr, // lpEnvironment
|
||||
nullptr,
|
||||
path.data(),
|
||||
&siEx.StartupInfo, // lpStartupInfo
|
||||
&_piClient // lpProcessInformation
|
||||
));
|
||||
|
|
|
@ -63,23 +63,15 @@ namespace winrt::TerminalApp::implementation
|
|||
// - <none>
|
||||
void ColorPickupFlyout::ShowColorPickerButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&)
|
||||
{
|
||||
auto targetType = this->FlyoutPresenterStyle().TargetType();
|
||||
auto s = Windows::UI::Xaml::Style{};
|
||||
s.TargetType(targetType);
|
||||
auto visibility = customColorPanel().Visibility();
|
||||
if (visibility == winrt::Windows::UI::Xaml::Visibility::Collapsed)
|
||||
{
|
||||
customColorPanel().Visibility(winrt::Windows::UI::Xaml::Visibility::Visible);
|
||||
auto setter = Windows::UI::Xaml::Setter(Windows::UI::Xaml::FrameworkElement::MinWidthProperty(), winrt::box_value(540));
|
||||
s.Setters().Append(setter);
|
||||
}
|
||||
else
|
||||
{
|
||||
customColorPanel().Visibility(winrt::Windows::UI::Xaml::Visibility::Collapsed);
|
||||
auto setter = Windows::UI::Xaml::Setter(Windows::UI::Xaml::FrameworkElement::MinWidthProperty(), winrt::box_value(0));
|
||||
s.Setters().Append(setter);
|
||||
}
|
||||
this->FlyoutPresenterStyle(s);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
<ClCompile>
|
||||
|
@ -372,13 +372,13 @@
|
|||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace winrt
|
|||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
using IInspectable = Windows::Foundation::IInspectable;
|
||||
using VirtualKeyModifiers = Windows::System::VirtualKeyModifiers;
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
|
@ -1348,26 +1349,26 @@ namespace winrt::TerminalApp::implementation
|
|||
// Return Value:
|
||||
// - a string representation of the key modifiers for the shortcut
|
||||
//NOTE: This needs to be localized with https://github.com/microsoft/terminal/issues/794 if XAML framework issue not resolved before then
|
||||
static std::wstring _FormatOverrideShortcutText(KeyModifiers modifiers)
|
||||
static std::wstring _FormatOverrideShortcutText(VirtualKeyModifiers modifiers)
|
||||
{
|
||||
std::wstring buffer{ L"" };
|
||||
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Ctrl))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Control))
|
||||
{
|
||||
buffer += L"Ctrl+";
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Shift))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift))
|
||||
{
|
||||
buffer += L"Shift+";
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Alt))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Menu))
|
||||
{
|
||||
buffer += L"Alt+";
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Windows))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Windows))
|
||||
{
|
||||
buffer += L"Win+";
|
||||
}
|
||||
|
@ -1393,11 +1394,8 @@ namespace winrt::TerminalApp::implementation
|
|||
// TODO: Modify this when https://github.com/microsoft/terminal/issues/877 is resolved
|
||||
menuShortcut.Key(static_cast<Windows::System::VirtualKey>(keyChord.Vkey()));
|
||||
|
||||
// inspect the modifiers from the KeyChord and set the flags int he XAML value
|
||||
auto modifiers = ActionMap::ConvertVKModifiers(keyChord.Modifiers());
|
||||
|
||||
// add the modifiers to the shortcut
|
||||
menuShortcut.Modifiers(modifiers);
|
||||
menuShortcut.Modifiers(keyChord.Modifiers());
|
||||
|
||||
// add to the menu
|
||||
menuItem.KeyboardAccelerators().Append(menuShortcut);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<!-- ========================= XAML files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- DON'T PUT XAML FILES HERE! Put them in TerminalAppLib.vcxproj -->
|
||||
|
@ -90,13 +90,13 @@
|
|||
|
||||
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.2" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -592,6 +592,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
const int newDpi = static_cast<int>(static_cast<double>(USER_DEFAULT_SCREEN_DPI) *
|
||||
_compositionScale);
|
||||
|
||||
_terminal->SetFontInfo(_actualFont);
|
||||
|
||||
// TODO: MSFT:20895307 If the font doesn't exist, this doesn't
|
||||
// actually fail. We need a way to gracefully fallback.
|
||||
_renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "KeyChord.g.cpp"
|
||||
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
KeyChord::KeyChord() noexcept :
|
||||
|
@ -15,34 +17,34 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
|
||||
KeyChord::KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept :
|
||||
_modifiers{ (ctrl ? Control::KeyModifiers::Ctrl : Control::KeyModifiers::None) |
|
||||
(alt ? Control::KeyModifiers::Alt : Control::KeyModifiers::None) |
|
||||
(shift ? Control::KeyModifiers::Shift : Control::KeyModifiers::None) },
|
||||
_modifiers{ (ctrl ? VirtualKeyModifiers::Control : VirtualKeyModifiers::None) |
|
||||
(alt ? VirtualKeyModifiers::Menu : VirtualKeyModifiers::None) |
|
||||
(shift ? VirtualKeyModifiers::Shift : VirtualKeyModifiers::None) },
|
||||
_vkey{ vkey }
|
||||
{
|
||||
}
|
||||
|
||||
KeyChord::KeyChord(bool ctrl, bool alt, bool shift, bool win, int32_t vkey) noexcept :
|
||||
_modifiers{ (ctrl ? Control::KeyModifiers::Ctrl : Control::KeyModifiers::None) |
|
||||
(alt ? Control::KeyModifiers::Alt : Control::KeyModifiers::None) |
|
||||
(shift ? Control::KeyModifiers::Shift : Control::KeyModifiers::None) |
|
||||
(win ? Control::KeyModifiers::Windows : Control::KeyModifiers::None) },
|
||||
_modifiers{ (ctrl ? VirtualKeyModifiers::Control : VirtualKeyModifiers::None) |
|
||||
(alt ? VirtualKeyModifiers::Menu : VirtualKeyModifiers::None) |
|
||||
(shift ? VirtualKeyModifiers::Shift : VirtualKeyModifiers::None) |
|
||||
(win ? VirtualKeyModifiers::Windows : VirtualKeyModifiers::None) },
|
||||
_vkey{ vkey }
|
||||
{
|
||||
}
|
||||
|
||||
KeyChord::KeyChord(Control::KeyModifiers const& modifiers, int32_t vkey) noexcept :
|
||||
KeyChord::KeyChord(VirtualKeyModifiers const& modifiers, int32_t vkey) noexcept :
|
||||
_modifiers{ modifiers },
|
||||
_vkey{ vkey }
|
||||
{
|
||||
}
|
||||
|
||||
Control::KeyModifiers KeyChord::Modifiers() noexcept
|
||||
VirtualKeyModifiers KeyChord::Modifiers() noexcept
|
||||
{
|
||||
return _modifiers;
|
||||
}
|
||||
|
||||
void KeyChord::Modifiers(Control::KeyModifiers const& value) noexcept
|
||||
void KeyChord::Modifiers(VirtualKeyModifiers const& value) noexcept
|
||||
{
|
||||
_modifiers = value;
|
||||
}
|
||||
|
|
|
@ -10,17 +10,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
struct KeyChord : KeyChordT<KeyChord>
|
||||
{
|
||||
KeyChord() noexcept;
|
||||
KeyChord(Control::KeyModifiers const& modifiers, int32_t vkey) noexcept;
|
||||
KeyChord(winrt::Windows::System::VirtualKeyModifiers const& modifiers, int32_t vkey) noexcept;
|
||||
KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept;
|
||||
KeyChord(bool ctrl, bool alt, bool shift, bool win, int32_t vkey) noexcept;
|
||||
|
||||
Control::KeyModifiers Modifiers() noexcept;
|
||||
void Modifiers(Control::KeyModifiers const& value) noexcept;
|
||||
winrt::Windows::System::VirtualKeyModifiers Modifiers() noexcept;
|
||||
void Modifiers(winrt::Windows::System::VirtualKeyModifiers const& value) noexcept;
|
||||
int32_t Vkey() noexcept;
|
||||
void Vkey(int32_t value) noexcept;
|
||||
|
||||
private:
|
||||
Control::KeyModifiers _modifiers;
|
||||
winrt::Windows::System::VirtualKeyModifiers _modifiers;
|
||||
int32_t _vkey;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,25 +3,15 @@
|
|||
|
||||
namespace Microsoft.Terminal.Control
|
||||
{
|
||||
[flags]
|
||||
enum KeyModifiers
|
||||
{
|
||||
None = 0x0000,
|
||||
Alt = 0x0001,
|
||||
Ctrl = 0x0002,
|
||||
Shift = 0x0004,
|
||||
Windows = 0x0008
|
||||
};
|
||||
|
||||
[default_interface]
|
||||
runtimeclass KeyChord
|
||||
{
|
||||
KeyChord();
|
||||
KeyChord(KeyModifiers modifiers, Int32 vkey);
|
||||
KeyChord(Windows.System.VirtualKeyModifiers modifiers, Int32 vkey);
|
||||
KeyChord(Boolean ctrl, Boolean alt, Boolean shift, Int32 vkey);
|
||||
KeyChord(Boolean ctrl, Boolean alt, Boolean shift, Boolean win, Int32 vkey);
|
||||
|
||||
KeyModifiers Modifiers;
|
||||
Windows.System.VirtualKeyModifiers Modifiers;
|
||||
Int32 Vkey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "XamlUiaTextRange.h"
|
||||
#include "../types/TermControlUiaTextRange.hpp"
|
||||
#include <UIAutomationClient.h>
|
||||
#include <UIAutomationCoreApi.h>
|
||||
|
||||
// the same as COR_E_NOTSUPPORTED
|
||||
// we don't want to import the CLR headers to get it
|
||||
|
@ -89,12 +90,52 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
winrt::Windows::Foundation::IInspectable XamlUiaTextRange::GetAttributeValue(int32_t textAttributeId) const
|
||||
{
|
||||
// Copied functionality from Types::UiaTextRange.cpp
|
||||
if (textAttributeId == UIA_IsReadOnlyAttributeId)
|
||||
// Call the function off of the underlying UiaTextRange.
|
||||
VARIANT result;
|
||||
THROW_IF_FAILED(_uiaProvider->GetAttributeValue(textAttributeId, &result));
|
||||
|
||||
// Convert the resulting VARIANT into a format that is consumable by XAML.
|
||||
switch (result.vt)
|
||||
{
|
||||
return winrt::box_value(false);
|
||||
case VT_BSTR:
|
||||
{
|
||||
return box_value(result.bstrVal);
|
||||
}
|
||||
else
|
||||
case VT_I4:
|
||||
{
|
||||
// Surprisingly, `long` is _not_ a WinRT type.
|
||||
// So we have to use `int32_t` to make sure this is output properly.
|
||||
// Otherwise, you'll get "Attribute does not exist" out the other end.
|
||||
return box_value<int32_t>(result.lVal);
|
||||
}
|
||||
case VT_R8:
|
||||
{
|
||||
return box_value(result.dblVal);
|
||||
}
|
||||
case VT_BOOL:
|
||||
{
|
||||
return box_value<bool>(result.boolVal);
|
||||
}
|
||||
case VT_UNKNOWN:
|
||||
{
|
||||
// This one is particularly special.
|
||||
// We might return a special value like UiaGetReservedMixedAttributeValue
|
||||
// or UiaGetReservedNotSupportedValue.
|
||||
// Some text attributes may return a real value, however, none of those
|
||||
// are supported at this time.
|
||||
// So we need to figure out what was actually intended to be returned.
|
||||
|
||||
com_ptr<IUnknown> mixedAttributeVal;
|
||||
UiaGetReservedMixedAttributeValue(mixedAttributeVal.put());
|
||||
|
||||
if (result.punkVal == mixedAttributeVal.get())
|
||||
{
|
||||
return Windows::UI::Xaml::DependencyProperty::UnsetValue();
|
||||
}
|
||||
|
||||
[[fallthrough]];
|
||||
}
|
||||
default:
|
||||
{
|
||||
// We _need_ to return XAML_E_NOT_SUPPORTED here.
|
||||
// Returning nullptr is an improper implementation of it being unsupported.
|
||||
|
@ -103,6 +144,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// Magically, this doesn't affect other forms of navigation...
|
||||
winrt::throw_hresult(XAML_E_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XamlUiaTextRange::GetBoundingRectangles(com_array<double>& returnValue) const
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "../../terminal/parser/OutputStateMachineEngine.hpp"
|
||||
#include "TerminalDispatch.hpp"
|
||||
#include "../../inc/unicode.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
#include "../../inc/argb.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../types/inc/colorTable.hpp"
|
||||
|
@ -867,9 +866,9 @@ WORD Terminal::_TakeVirtualKeyFromLastKeyEvent(const WORD scanCode) noexcept
|
|||
// Return Value:
|
||||
// - a shared_lock which can be used to unlock the terminal. The shared_lock
|
||||
// will release this lock when it's destructed.
|
||||
[[nodiscard]] std::shared_lock<std::shared_mutex> Terminal::LockForReading()
|
||||
[[nodiscard]] std::unique_lock<til::ticket_lock> Terminal::LockForReading()
|
||||
{
|
||||
return std::shared_lock<std::shared_mutex>(_readWriteLock);
|
||||
return std::unique_lock{ _readWriteLock };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -877,9 +876,9 @@ WORD Terminal::_TakeVirtualKeyFromLastKeyEvent(const WORD scanCode) noexcept
|
|||
// Return Value:
|
||||
// - a unique_lock which can be used to unlock the terminal. The unique_lock
|
||||
// will release this lock when it's destructed.
|
||||
[[nodiscard]] std::unique_lock<std::shared_mutex> Terminal::LockForWriting()
|
||||
[[nodiscard]] std::unique_lock<til::ticket_lock> Terminal::LockForWriting()
|
||||
{
|
||||
return std::unique_lock<std::shared_mutex>(_readWriteLock);
|
||||
return std::unique_lock{ _readWriteLock };
|
||||
}
|
||||
|
||||
Viewport Terminal::_GetMutableViewport() const noexcept
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <conattrs.hpp>
|
||||
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
#include "../../buffer/out/textBuffer.hpp"
|
||||
#include "../../types/inc/sgrStack.hpp"
|
||||
#include "../../renderer/inc/BlinkingState.hpp"
|
||||
|
@ -17,6 +18,8 @@
|
|||
#include "../../cascadia/terminalcore/ITerminalApi.hpp"
|
||||
#include "../../cascadia/terminalcore/ITerminalInput.hpp"
|
||||
|
||||
#include <til/ticket_lock.h>
|
||||
|
||||
static constexpr std::wstring_view linkPattern{ LR"(\b(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|$!:,.;]*[A-Za-z0-9+&@#/%=~_|$])" };
|
||||
static constexpr size_t TaskbarMinProgress{ 10 };
|
||||
|
||||
|
@ -68,6 +71,7 @@ public:
|
|||
|
||||
void UpdateSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings);
|
||||
void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance);
|
||||
void SetFontInfo(const FontInfo& fontInfo);
|
||||
|
||||
// Write goes through the parser
|
||||
void Write(std::wstring_view stringView);
|
||||
|
@ -75,8 +79,8 @@ public:
|
|||
// WritePastedText goes directly to the connection
|
||||
void WritePastedText(std::wstring_view stringView);
|
||||
|
||||
[[nodiscard]] std::shared_lock<std::shared_mutex> LockForReading();
|
||||
[[nodiscard]] std::unique_lock<std::shared_mutex> LockForWriting();
|
||||
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForReading();
|
||||
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
|
||||
|
||||
short GetBufferHeight() const noexcept;
|
||||
|
||||
|
@ -160,6 +164,7 @@ public:
|
|||
COORD GetTextBufferEndPosition() const noexcept override;
|
||||
const TextBuffer& GetTextBuffer() noexcept override;
|
||||
const FontInfo& GetFontInfo() noexcept override;
|
||||
std::pair<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept override;
|
||||
|
||||
void LockConsole() noexcept override;
|
||||
void UnlockConsole() noexcept override;
|
||||
|
@ -168,7 +173,6 @@ public:
|
|||
#pragma region IRenderData
|
||||
// These methods are defined in TerminalRenderData.cpp
|
||||
const TextAttribute GetDefaultBrushColors() noexcept override;
|
||||
std::pair<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept override;
|
||||
COORD GetCursorPosition() const noexcept override;
|
||||
bool IsCursorVisible() const noexcept override;
|
||||
bool IsCursorOn() const noexcept override;
|
||||
|
@ -242,6 +246,15 @@ private:
|
|||
std::function<void()> _pfnWarningBell;
|
||||
std::function<void(std::wstring_view)> _pfnTitleChanged;
|
||||
std::function<void(std::wstring_view)> _pfnCopyToClipboard;
|
||||
|
||||
// I've specifically put this instance here as it requires
|
||||
// alignas(std::hardware_destructive_interference_size)
|
||||
// for best performance.
|
||||
//
|
||||
// But we can abuse the fact that the surrounding members rarely change and are huge
|
||||
// (std::function is like 64 bytes) to create some natural padding without wasting space.
|
||||
til::ticket_lock _readWriteLock;
|
||||
|
||||
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
|
||||
std::function<void(const til::color)> _pfnBackgroundColorChanged;
|
||||
std::function<void()> _pfnCursorPositionChanged;
|
||||
|
@ -276,6 +289,10 @@ private:
|
|||
size_t _hyperlinkPatternId;
|
||||
|
||||
std::wstring _workingDirectory;
|
||||
|
||||
// This default fake font value is only used to check if the font is a raster font.
|
||||
// Otherwise, the font is changed to a real value with the renderer via TriggerFontChange.
|
||||
FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
|
||||
#pragma region Text Selection
|
||||
// a selection is represented as a range between two COORDs (start and end)
|
||||
// the pivot is the COORD that remains selected when you extend a selection in any direction
|
||||
|
@ -293,8 +310,6 @@ private:
|
|||
SelectionExpansionMode _multiClickSelectionMode;
|
||||
#pragma endregion
|
||||
|
||||
std::shared_mutex _readWriteLock;
|
||||
|
||||
// TODO: These members are not shared by an alt-buffer. They should be
|
||||
// encapsulated, such that a Terminal can have both a main and alt buffer.
|
||||
std::unique_ptr<TextBuffer> _buffer;
|
||||
|
|
|
@ -733,6 +733,10 @@ bool TerminalDispatch::HardReset() noexcept
|
|||
// Cursor to 1,1 - the Soft Reset guarantees this is absolute
|
||||
success = CursorPosition(1, 1) && success;
|
||||
|
||||
// Reset the mouse mode
|
||||
success = EnableSGRExtendedMouseMode(false) && success;
|
||||
success = EnableAnyEventMouseMode(false) && success;
|
||||
|
||||
// Delete all current tab stops and reapply
|
||||
_ResetTabStops();
|
||||
|
||||
|
|
|
@ -27,23 +27,15 @@ const TextBuffer& Terminal::GetTextBuffer() noexcept
|
|||
return *_buffer;
|
||||
}
|
||||
|
||||
// Creating a FontInfo can technically throw (on string allocation) and this is noexcept.
|
||||
// That means this will std::terminate. We could come back and make there be a default constructor
|
||||
// backup to FontInfo that throws no exceptions and allocates a default FontInfo structure.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26447)
|
||||
const FontInfo& Terminal::GetFontInfo() noexcept
|
||||
{
|
||||
// TODO: This font value is only used to check if the font is a raster font.
|
||||
// Otherwise, the font is changed with the renderer via TriggerFontChange.
|
||||
// The renderer never uses any of the other members from the value returned
|
||||
// by this method.
|
||||
// We could very likely replace this with just an IsRasterFont method
|
||||
// (which would return false)
|
||||
static const FontInfo _fakeFontInfo(DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false);
|
||||
return _fakeFontInfo;
|
||||
return _fontInfo;
|
||||
}
|
||||
|
||||
void Terminal::SetFontInfo(const FontInfo& fontInfo)
|
||||
{
|
||||
_fontInfo = fontInfo;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
const TextAttribute Terminal::GetDefaultBrushColors() noexcept
|
||||
{
|
||||
|
@ -238,14 +230,14 @@ catch (...)
|
|||
// they're done with any querying they need to do.
|
||||
void Terminal::LockConsole() noexcept
|
||||
{
|
||||
_readWriteLock.lock_shared();
|
||||
_readWriteLock.lock();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Unlocks the terminal after a call to Terminal::LockConsole.
|
||||
void Terminal::UnlockConsole() noexcept
|
||||
{
|
||||
_readWriteLock.unlock_shared();
|
||||
_readWriteLock.unlock();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
374
src/cascadia/TerminalSettingsEditor/Appearances.cpp
Normal file
374
src/cascadia/TerminalSettingsEditor/Appearances.cpp
Normal file
|
@ -0,0 +1,374 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "Appearances.h"
|
||||
#include "Appearances.g.cpp"
|
||||
#include "EnumEntry.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
using namespace winrt::Windows::UI::Text;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Data;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
AppearanceViewModel::AppearanceViewModel(const Model::AppearanceConfig& appearance) :
|
||||
_appearance{ appearance }
|
||||
{
|
||||
// Add a property changed handler to our own property changed event.
|
||||
// This propagates changes from the settings model to anybody listening to our
|
||||
// unique view model members.
|
||||
PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
|
||||
const auto viewModelProperty{ args.PropertyName() };
|
||||
if (viewModelProperty == L"BackgroundImagePath")
|
||||
{
|
||||
// notify listener that all background image related values might have changed
|
||||
//
|
||||
// We need to do this so if someone manually types "desktopWallpaper"
|
||||
// into the path TextBox, we properly update the checkbox and stored
|
||||
// _lastBgImagePath. Without this, then we'll permanently hide the text
|
||||
// box, prevent it from ever being changed again.
|
||||
_NotifyChanges(L"UseDesktopBGImage", L"BackgroundImageSettingsVisible");
|
||||
}
|
||||
});
|
||||
|
||||
// Cache the original BG image path. If the user clicks "Use desktop
|
||||
// wallpaper", then un-checks it, this is the string we'll restore to
|
||||
// them.
|
||||
if (BackgroundImagePath() != L"desktopWallpaper")
|
||||
{
|
||||
_lastBgImagePath = BackgroundImagePath();
|
||||
}
|
||||
}
|
||||
|
||||
bool AppearanceViewModel::UseDesktopBGImage()
|
||||
{
|
||||
return BackgroundImagePath() == L"desktopWallpaper";
|
||||
}
|
||||
|
||||
void AppearanceViewModel::UseDesktopBGImage(const bool useDesktop)
|
||||
{
|
||||
if (useDesktop)
|
||||
{
|
||||
// Stash the current value of BackgroundImagePath. If the user
|
||||
// checks and un-checks the "Use desktop wallpaper" button, we want
|
||||
// the path that we display in the text box to remain unchanged.
|
||||
//
|
||||
// Only stash this value if it's not the special "desktopWallpaper"
|
||||
// value.
|
||||
if (BackgroundImagePath() != L"desktopWallpaper")
|
||||
{
|
||||
_lastBgImagePath = BackgroundImagePath();
|
||||
}
|
||||
BackgroundImagePath(L"desktopWallpaper");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore the path we had previously cached. This might be the
|
||||
// empty string.
|
||||
BackgroundImagePath(_lastBgImagePath);
|
||||
}
|
||||
}
|
||||
|
||||
bool AppearanceViewModel::BackgroundImageSettingsVisible()
|
||||
{
|
||||
return BackgroundImagePath() != L"";
|
||||
}
|
||||
|
||||
DependencyProperty Appearances::_AppearanceProperty{ nullptr };
|
||||
|
||||
Appearances::Appearances() :
|
||||
_ShowAllFonts{ false },
|
||||
_ColorSchemeList{ single_threaded_observable_vector<ColorScheme>() }
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(CursorShape, CursorStyle, winrt::Microsoft::Terminal::Core::CursorStyle, L"Profile_CursorShape", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING_REVERSE_ORDER(BackgroundImageStretchMode, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch, L"Profile_BackgroundImageStretchMode", L"Content");
|
||||
|
||||
// manually add Custom FontWeight option. Don't add it to the Map
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(FontWeight, FontWeight, uint16_t, L"Profile_FontWeight", L"Content");
|
||||
_CustomFontWeight = winrt::make<EnumEntry>(RS_(L"Profile_FontWeightCustom/Content"), winrt::box_value<uint16_t>(0u));
|
||||
_FontWeightList.Append(_CustomFontWeight);
|
||||
|
||||
if (!_AppearanceProperty)
|
||||
{
|
||||
_AppearanceProperty =
|
||||
DependencyProperty::Register(
|
||||
L"Appearance",
|
||||
xaml_typename<Editor::AppearanceViewModel>(),
|
||||
xaml_typename<Editor::Appearances>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &Appearances::_ViewModelChanged } });
|
||||
}
|
||||
|
||||
// manually keep track of all the Background Image Alignment buttons
|
||||
_BIAlignmentButtons.at(0) = BIAlign_TopLeft();
|
||||
_BIAlignmentButtons.at(1) = BIAlign_Top();
|
||||
_BIAlignmentButtons.at(2) = BIAlign_TopRight();
|
||||
_BIAlignmentButtons.at(3) = BIAlign_Left();
|
||||
_BIAlignmentButtons.at(4) = BIAlign_Center();
|
||||
_BIAlignmentButtons.at(5) = BIAlign_Right();
|
||||
_BIAlignmentButtons.at(6) = BIAlign_BottomLeft();
|
||||
_BIAlignmentButtons.at(7) = BIAlign_Bottom();
|
||||
_BIAlignmentButtons.at(8) = BIAlign_BottomRight();
|
||||
|
||||
// apply automation properties to more complex setting controls
|
||||
for (const auto& biButton : _BIAlignmentButtons)
|
||||
{
|
||||
const auto tooltip{ ToolTipService::GetToolTip(biButton) };
|
||||
Automation::AutomationProperties::SetName(biButton, unbox_value<hstring>(tooltip));
|
||||
}
|
||||
|
||||
const auto showAllFontsCheckboxTooltip{ ToolTipService::GetToolTip(ShowAllFontsCheckbox()) };
|
||||
Automation::AutomationProperties::SetFullDescription(ShowAllFontsCheckbox(), unbox_value<hstring>(showAllFontsCheckboxTooltip));
|
||||
|
||||
const auto backgroundImgCheckboxTooltip{ ToolTipService::GetToolTip(UseDesktopImageCheckBox()) };
|
||||
Automation::AutomationProperties::SetFullDescription(UseDesktopImageCheckBox(), unbox_value<hstring>(backgroundImgCheckboxTooltip));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Searches through our list of monospace fonts to determine if the settings model's current font face is a monospace font
|
||||
bool Appearances::UsingMonospaceFont() const noexcept
|
||||
{
|
||||
bool result{ false };
|
||||
const auto currentFont{ Appearance().FontFace() };
|
||||
for (const auto& font : SourceProfile().MonospaceFontList())
|
||||
{
|
||||
if (font.LocalizedName() == currentFont)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether we should show the list of all the fonts, or we should just show monospace fonts
|
||||
bool Appearances::ShowAllFonts() const noexcept
|
||||
{
|
||||
// - _ShowAllFonts is directly bound to the checkbox. So this is the user set value.
|
||||
// - If we are not using a monospace font, show all of the fonts so that the ComboBox is still properly bound
|
||||
return _ShowAllFonts || !UsingMonospaceFont();
|
||||
}
|
||||
|
||||
void Appearances::ShowAllFonts(const bool& value)
|
||||
{
|
||||
if (_ShowAllFonts != value)
|
||||
{
|
||||
_ShowAllFonts = value;
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"ShowAllFonts" });
|
||||
}
|
||||
}
|
||||
|
||||
IInspectable Appearances::CurrentFontFace() const
|
||||
{
|
||||
// look for the current font in our shown list of fonts
|
||||
const auto& appearanceVM{ Appearance() };
|
||||
const auto appearanceFontFace{ appearanceVM.FontFace() };
|
||||
const auto& currentFontList{ ShowAllFonts() ? SourceProfile().CompleteFontList() : SourceProfile().MonospaceFontList() };
|
||||
IInspectable fallbackFont;
|
||||
for (const auto& font : currentFontList)
|
||||
{
|
||||
if (font.LocalizedName() == appearanceFontFace)
|
||||
{
|
||||
return box_value(font);
|
||||
}
|
||||
else if (font.LocalizedName() == L"Cascadia Mono")
|
||||
{
|
||||
fallbackFont = box_value(font);
|
||||
}
|
||||
}
|
||||
|
||||
// we couldn't find the desired font, set to "Cascadia Mono" since that ships by default
|
||||
return fallbackFont;
|
||||
}
|
||||
|
||||
void Appearances::FontFace_SelectionChanged(IInspectable const& /*sender*/, SelectionChangedEventArgs const& e)
|
||||
{
|
||||
// NOTE: We need to hook up a selection changed event handler here instead of directly binding to the appearance view model.
|
||||
// A two way binding to the view model causes an infinite loop because both combo boxes keep fighting over which one's right.
|
||||
const auto selectedItem{ e.AddedItems().GetAt(0) };
|
||||
const auto newFontFace{ unbox_value<Editor::Font>(selectedItem) };
|
||||
Appearance().FontFace(newFontFace.LocalizedName());
|
||||
}
|
||||
|
||||
void Appearances::_ViewModelChanged(DependencyObject const& d, DependencyPropertyChangedEventArgs const& /*args*/)
|
||||
{
|
||||
const auto& obj{ d.as<Editor::Appearances>() };
|
||||
get_self<Appearances>(obj)->_UpdateWithNewViewModel();
|
||||
}
|
||||
|
||||
void Appearances::_UpdateWithNewViewModel()
|
||||
{
|
||||
if (Appearance())
|
||||
{
|
||||
const auto& colorSchemeMap{ Appearance().Schemes() };
|
||||
for (const auto& pair : colorSchemeMap)
|
||||
{
|
||||
_ColorSchemeList.Append(pair.Value());
|
||||
}
|
||||
|
||||
const auto& biAlignmentVal{ static_cast<int32_t>(Appearance().BackgroundImageAlignment()) };
|
||||
for (const auto& biButton : _BIAlignmentButtons)
|
||||
{
|
||||
biButton.IsChecked(biButton.Tag().as<int32_t>() == biAlignmentVal);
|
||||
}
|
||||
|
||||
_ViewModelChangedRevoker = Appearance().PropertyChanged(winrt::auto_revoke, [=](auto&&, const PropertyChangedEventArgs& args) {
|
||||
const auto settingName{ args.PropertyName() };
|
||||
if (settingName == L"CursorShape")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentCursorShape" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsVintageCursor" });
|
||||
}
|
||||
else if (settingName == L"ColorSchemeName")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentColorScheme" });
|
||||
}
|
||||
else if (settingName == L"BackgroundImageStretchMode")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentBackgroundImageStretchMode" });
|
||||
}
|
||||
else if (settingName == L"BackgroundImageAlignment")
|
||||
{
|
||||
_UpdateBIAlignmentControl(static_cast<int32_t>(Appearance().BackgroundImageAlignment()));
|
||||
}
|
||||
else if (settingName == L"FontWeight")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentFontWeight" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsCustomFontWeight" });
|
||||
}
|
||||
else if (settingName == L"FontFace" || settingName == L"CurrentFontList")
|
||||
{
|
||||
// notify listener that all font face related values might have changed
|
||||
if (!UsingMonospaceFont())
|
||||
{
|
||||
_ShowAllFonts = true;
|
||||
}
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentFontFace" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"ShowAllFonts" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"UsingMonospaceFont" });
|
||||
}
|
||||
});
|
||||
|
||||
// make sure to send all the property changed events once here
|
||||
// we do this in the case an old appearance was deleted and then a new one is created,
|
||||
// the old settings need to be updated in xaml
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentCursorShape" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsVintageCursor" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentColorScheme" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentBackgroundImageStretchMode" });
|
||||
_UpdateBIAlignmentControl(static_cast<int32_t>(Appearance().BackgroundImageAlignment()));
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentFontWeight" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsCustomFontWeight" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentFontFace" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"ShowAllFonts" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"UsingMonospaceFont" });
|
||||
}
|
||||
}
|
||||
|
||||
fire_and_forget Appearances::BackgroundImage_Click(IInspectable const&, RoutedEventArgs const&)
|
||||
{
|
||||
auto lifetime = get_strong();
|
||||
|
||||
const auto parentHwnd{ reinterpret_cast<HWND>(Appearance().WindowRoot().GetHostingWindow()) };
|
||||
auto file = co_await OpenImagePicker(parentHwnd);
|
||||
if (!file.empty())
|
||||
{
|
||||
Appearance().BackgroundImagePath(file);
|
||||
}
|
||||
}
|
||||
|
||||
void Appearances::BIAlignment_Click(IInspectable const& sender, RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
if (const auto& button{ sender.try_as<Primitives::ToggleButton>() })
|
||||
{
|
||||
if (const auto& tag{ button.Tag().try_as<int32_t>() })
|
||||
{
|
||||
// Update the Appearance's value and the control
|
||||
Appearance().BackgroundImageAlignment(static_cast<ConvergedAlignment>(*tag));
|
||||
_UpdateBIAlignmentControl(*tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resets all of the buttons to unchecked, and checks the one with the provided tag
|
||||
// Arguments:
|
||||
// - val - the background image alignment (ConvergedAlignment) that we want to represent in the control
|
||||
void Appearances::_UpdateBIAlignmentControl(const int32_t val)
|
||||
{
|
||||
for (const auto& biButton : _BIAlignmentButtons)
|
||||
{
|
||||
if (const auto& biButtonAlignment{ biButton.Tag().try_as<int32_t>() })
|
||||
{
|
||||
biButton.IsChecked(biButtonAlignment == val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorScheme Appearances::CurrentColorScheme()
|
||||
{
|
||||
const auto schemeName{ Appearance().ColorSchemeName() };
|
||||
if (const auto scheme{ Appearance().Schemes().TryLookup(schemeName) })
|
||||
{
|
||||
return scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This Appearance points to a color scheme that was renamed or deleted.
|
||||
// Fallback to Campbell.
|
||||
return Appearance().Schemes().TryLookup(L"Campbell");
|
||||
}
|
||||
}
|
||||
|
||||
void Appearances::CurrentColorScheme(const ColorScheme& val)
|
||||
{
|
||||
Appearance().ColorSchemeName(val.Name());
|
||||
}
|
||||
|
||||
bool Appearances::IsVintageCursor() const
|
||||
{
|
||||
return Appearance().CursorShape() == Core::CursorStyle::Vintage;
|
||||
}
|
||||
|
||||
IInspectable Appearances::CurrentFontWeight() const
|
||||
{
|
||||
// if no value was found, we have a custom value
|
||||
const auto maybeEnumEntry{ _FontWeightMap.TryLookup(Appearance().FontWeight().Weight) };
|
||||
return maybeEnumEntry ? maybeEnumEntry : _CustomFontWeight;
|
||||
}
|
||||
|
||||
void Appearances::CurrentFontWeight(const IInspectable& enumEntry)
|
||||
{
|
||||
if (auto ee = enumEntry.try_as<Editor::EnumEntry>())
|
||||
{
|
||||
if (ee != _CustomFontWeight)
|
||||
{
|
||||
const auto weight{ winrt::unbox_value<uint16_t>(ee.EnumValue()) };
|
||||
const Windows::UI::Text::FontWeight setting{ weight };
|
||||
Appearance().FontWeight(setting);
|
||||
|
||||
// Appearance does not have observable properties
|
||||
// So the TwoWay binding doesn't update on the State --> Slider direction
|
||||
FontWeightSlider().Value(weight);
|
||||
}
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsCustomFontWeight" });
|
||||
}
|
||||
}
|
||||
|
||||
bool Appearances::IsCustomFontWeight()
|
||||
{
|
||||
// Use SelectedItem instead of CurrentFontWeight.
|
||||
// CurrentFontWeight converts the Appearance's value to the appropriate enum entry,
|
||||
// whereas SelectedItem identifies which one was selected by the user.
|
||||
return FontWeightComboBox().SelectedItem() == _CustomFontWeight;
|
||||
}
|
||||
}
|
143
src/cascadia/TerminalSettingsEditor/Appearances.h
Normal file
143
src/cascadia/TerminalSettingsEditor/Appearances.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- Appearances
|
||||
|
||||
Abstract:
|
||||
- The classes defined in this module are responsible for encapsulating the appearance settings
|
||||
of profiles and presenting them in the settings UI
|
||||
|
||||
Author(s):
|
||||
- Pankaj Bhojwani - May 2021
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Font.g.h"
|
||||
#include "Appearances.g.h"
|
||||
#include "AppearanceViewModel.g.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
#include "SettingContainer.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct FontComparator
|
||||
{
|
||||
bool operator()(const Font& lhs, const Font& rhs) const
|
||||
{
|
||||
return lhs.LocalizedName() < rhs.LocalizedName();
|
||||
}
|
||||
};
|
||||
|
||||
struct Font : FontT<Font>
|
||||
{
|
||||
public:
|
||||
Font(std::wstring name, std::wstring localizedName) :
|
||||
_Name{ name },
|
||||
_LocalizedName{ localizedName } {};
|
||||
|
||||
hstring ToString() { return _LocalizedName; }
|
||||
|
||||
WINRT_PROPERTY(hstring, Name);
|
||||
WINRT_PROPERTY(hstring, LocalizedName);
|
||||
};
|
||||
|
||||
struct AppearanceViewModel : AppearanceViewModelT<AppearanceViewModel>, ViewModelHelper<AppearanceViewModel>
|
||||
{
|
||||
public:
|
||||
AppearanceViewModel(const Model::AppearanceConfig& appearance);
|
||||
|
||||
// background image
|
||||
bool UseDesktopBGImage();
|
||||
void UseDesktopBGImage(const bool useDesktop);
|
||||
bool BackgroundImageSettingsVisible();
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> Schemes() { return _Schemes; }
|
||||
void Schemes(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& val) { _Schemes = val; }
|
||||
|
||||
WINRT_PROPERTY(bool, IsDefault, false);
|
||||
WINRT_PROPERTY(IHostedInWindow, WindowRoot, nullptr);
|
||||
|
||||
// These settings are not defined in AppearanceConfig, so we grab them
|
||||
// from the source profile itself. The reason we still want them in the
|
||||
// AppearanceViewModel is so we can continue to have the 'Text' grouping
|
||||
// we currently have in xaml, since that grouping has some settings that
|
||||
// are defined in AppearanceConfig and some that are not.
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontFace);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontSize);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontWeight);
|
||||
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, RetroTerminalEffect);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, CursorShape);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, CursorHeight);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, ColorSchemeName);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, BackgroundImagePath);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, BackgroundImageOpacity);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, BackgroundImageStretchMode);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, BackgroundImageAlignment);
|
||||
|
||||
private:
|
||||
Model::AppearanceConfig _appearance;
|
||||
winrt::hstring _lastBgImagePath;
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> _Schemes;
|
||||
};
|
||||
|
||||
struct Appearances : AppearancesT<Appearances>
|
||||
{
|
||||
public:
|
||||
Appearances();
|
||||
|
||||
// font face
|
||||
Windows::Foundation::IInspectable CurrentFontFace() const;
|
||||
|
||||
// CursorShape visibility logic
|
||||
bool IsVintageCursor() const;
|
||||
|
||||
Model::ColorScheme CurrentColorScheme();
|
||||
void CurrentColorScheme(const Model::ColorScheme& val);
|
||||
|
||||
bool UsingMonospaceFont() const noexcept;
|
||||
bool ShowAllFonts() const noexcept;
|
||||
void ShowAllFonts(const bool& value);
|
||||
|
||||
fire_and_forget BackgroundImage_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void BIAlignment_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void FontFace_SelectionChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& e);
|
||||
|
||||
// manually bind FontWeight
|
||||
Windows::Foundation::IInspectable CurrentFontWeight() const;
|
||||
void CurrentFontWeight(const Windows::Foundation::IInspectable& enumEntry);
|
||||
bool IsCustomFontWeight();
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry>, FontWeightList);
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(CursorShape, Microsoft::Terminal::Core::CursorStyle, Appearance, CursorShape);
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Model::ColorScheme>, ColorSchemeList, nullptr);
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
DEPENDENCY_PROPERTY(Editor::AppearanceViewModel, Appearance);
|
||||
WINRT_PROPERTY(Editor::ProfileViewModel, SourceProfile, nullptr);
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch, Appearance, BackgroundImageStretchMode);
|
||||
|
||||
private:
|
||||
bool _ShowAllFonts;
|
||||
void _UpdateBIAlignmentControl(const int32_t val);
|
||||
std::array<Windows::UI::Xaml::Controls::Primitives::ToggleButton, 9> _BIAlignmentButtons;
|
||||
|
||||
Windows::Foundation::Collections::IMap<uint16_t, Microsoft::Terminal::Settings::Editor::EnumEntry> _FontWeightMap;
|
||||
Editor::EnumEntry _CustomFontWeight{ nullptr };
|
||||
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker;
|
||||
static void _ViewModelChanged(Windows::UI::Xaml::DependencyObject const& d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const& e);
|
||||
void _UpdateWithNewViewModel();
|
||||
};
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Appearances);
|
||||
}
|
72
src/cascadia/TerminalSettingsEditor/Appearances.idl
Normal file
72
src/cascadia/TerminalSettingsEditor/Appearances.idl
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "EnumEntry.idl";
|
||||
import "MainPage.idl";
|
||||
import "Profiles.idl";
|
||||
|
||||
#include "ViewModelHelpers.idl.h"
|
||||
|
||||
#define OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Type, Name) \
|
||||
OBSERVABLE_PROJECTED_SETTING(Type, Name); \
|
||||
Object Name##OverrideSource { get; }
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass Font : Windows.Foundation.IStringable
|
||||
{
|
||||
String Name { get; };
|
||||
String LocalizedName { get; };
|
||||
}
|
||||
|
||||
runtimeclass AppearanceViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
Boolean IsDefault;
|
||||
|
||||
Boolean UseDesktopBGImage;
|
||||
Boolean BackgroundImageSettingsVisible { get; };
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, Microsoft.Terminal.Settings.Model.ColorScheme> Schemes;
|
||||
IHostedInWindow WindowRoot; // necessary to send the right HWND into the file picker dialogs.
|
||||
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, FontFace);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Int32, FontSize);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.UI.Text.FontWeight, FontWeight);
|
||||
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, ColorSchemeName);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Boolean, RetroTerminalEffect);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Core.CursorStyle, CursorShape);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(UInt32, CursorHeight);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, BackgroundImagePath);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Double, BackgroundImageOpacity);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.UI.Xaml.Media.Stretch, BackgroundImageStretchMode);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Settings.Model.ConvergedAlignment, BackgroundImageAlignment);
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Appearances : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
Appearances();
|
||||
AppearanceViewModel Appearance;
|
||||
ProfileViewModel SourceProfile;
|
||||
static Windows.UI.Xaml.DependencyProperty AppearanceProperty { get; };
|
||||
|
||||
Boolean UsingMonospaceFont { get; };
|
||||
Boolean ShowAllFonts;
|
||||
|
||||
IInspectable CurrentCursorShape;
|
||||
Boolean IsVintageCursor { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> CursorShapeList { get; };
|
||||
|
||||
Microsoft.Terminal.Settings.Model.ColorScheme CurrentColorScheme;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Model.ColorScheme> ColorSchemeList { get; };
|
||||
|
||||
IInspectable CurrentBackgroundImageStretchMode;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> BackgroundImageStretchModeList { get; };
|
||||
|
||||
IInspectable CurrentFontWeight;
|
||||
Boolean IsCustomFontWeight { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> FontWeightList { get; };
|
||||
|
||||
IInspectable CurrentFontFace { get; };
|
||||
}
|
||||
}
|
442
src/cascadia/TerminalSettingsEditor/Appearances.xaml
Normal file
442
src/cascadia/TerminalSettingsEditor/Appearances.xaml
Normal file
|
@ -0,0 +1,442 @@
|
|||
<!--
|
||||
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.Settings.Editor.Appearances"
|
||||
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.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
IsTabStop="False"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DataTemplate x:Key="EnumRadioButtonTemplate"
|
||||
x:DataType="local:EnumEntry">
|
||||
<RadioButton Content="{x:Bind EnumName, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="EnumComboBoxItemTemplate"
|
||||
x:DataType="local:EnumEntry">
|
||||
<TextBlock Text="{x:Bind EnumName, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="FontFaceComboBoxItemTemplate"
|
||||
x:DataType="local:Font">
|
||||
<TextBlock FontFamily="{x:Bind Name}"
|
||||
Text="{x:Bind LocalizedName}" />
|
||||
</DataTemplate>
|
||||
|
||||
<local:ColorToBrushConverter x:Key="ColorToBrushConverter" />
|
||||
<local:PercentageConverter x:Key="PercentageConverter" />
|
||||
<local:PercentageSignConverter x:Key="PercentageSignConverter" />
|
||||
<local:FontWeightConverter x:Key="FontWeightConverter" />
|
||||
<local:InvertedBooleanToVisibilityConverter x:Key="InvertedBooleanToVisibilityConverter" />
|
||||
<local:StringIsEmptyConverter x:Key="StringIsEmptyConverter" />
|
||||
<local:PaddingConverter x:Key="PaddingConverter" />
|
||||
<local:StringIsNotDesktopConverter x:Key="StringIsNotDesktopConverter" />
|
||||
<local:DesktopWallpaperToEmptyStringConverter x:Key="DesktopWallpaperToEmptyStringConverter" />
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<!-- Grouping: Text -->
|
||||
<TextBlock x:Uid="Profile_TextHeader"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<!-- Color Scheme -->
|
||||
<local:SettingContainer x:Uid="Profile_ColorScheme"
|
||||
Margin="0"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearColorSchemeName}"
|
||||
HasSettingValue="{x:Bind Appearance.HasColorSchemeName, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.ColorSchemeNameOverrideSource, Mode=OneWay}">
|
||||
<ComboBox ItemsSource="{x:Bind ColorSchemeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentColorScheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:ColorScheme">
|
||||
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Face -->
|
||||
<local:SettingContainer x:Uid="Profile_FontFace"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearFontFace}"
|
||||
HasSettingValue="{x:Bind Appearance.HasFontFace, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.FontFaceOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.IsDefault, Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<!--
|
||||
Binding the ItemsSource to a separate variable that switches between the
|
||||
two font lists causes a crash within the ComboBox code.
|
||||
As a workaround, introduce two ComboBox controls and only display one at a time.
|
||||
-->
|
||||
<ComboBox ItemTemplate="{StaticResource FontFaceComboBoxItemTemplate}"
|
||||
ItemsSource="{x:Bind SourceProfile.MonospaceFontList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentFontFace, Mode=OneWay}"
|
||||
SelectionChanged="FontFace_SelectionChanged"
|
||||
Style="{StaticResource ComboBoxSettingStyle}"
|
||||
Visibility="{x:Bind ShowAllFonts, Mode=OneWay, Converter={StaticResource InvertedBooleanToVisibilityConverter}}" />
|
||||
<ComboBox ItemTemplate="{StaticResource FontFaceComboBoxItemTemplate}"
|
||||
ItemsSource="{x:Bind SourceProfile.CompleteFontList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentFontFace, Mode=OneWay}"
|
||||
SelectionChanged="FontFace_SelectionChanged"
|
||||
Style="{StaticResource ComboBoxSettingStyle}"
|
||||
Visibility="{x:Bind ShowAllFonts, Mode=OneWay}" />
|
||||
<CheckBox x:Name="ShowAllFontsCheckbox"
|
||||
x:Uid="Profile_FontFaceShowAllFonts"
|
||||
IsChecked="{x:Bind ShowAllFonts, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind UsingMonospaceFont, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Size -->
|
||||
<local:SettingContainer x:Uid="Profile_FontSize"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearFontSize}"
|
||||
HasSettingValue="{x:Bind Appearance.HasFontSize, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.FontSizeOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.IsDefault, Mode=OneWay}">
|
||||
<muxc:NumberBox AcceptsExpression="False"
|
||||
LargeChange="10"
|
||||
Maximum="128"
|
||||
Minimum="1"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind Appearance.FontSize, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Weight -->
|
||||
<local:SettingContainer x:Name="FontWeightContainer"
|
||||
x:Uid="Profile_FontWeight"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearFontWeight}"
|
||||
HasSettingValue="{x:Bind Appearance.HasFontWeight, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.FontWeightOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.IsDefault, Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<ComboBox x:Name="FontWeightComboBox"
|
||||
ItemTemplate="{StaticResource EnumComboBoxItemTemplate}"
|
||||
ItemsSource="{x:Bind FontWeightList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentFontWeight, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
|
||||
<!-- Custom Font Weight Control -->
|
||||
<Grid Margin="0,10,0,0"
|
||||
Style="{StaticResource CustomSliderControlGridStyle}"
|
||||
Visibility="{x:Bind IsCustomFontWeight, Mode=OneWay}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Name="FontWeightSlider"
|
||||
Grid.Column="0"
|
||||
Maximum="1000"
|
||||
Minimum="0"
|
||||
TickFrequency="50"
|
||||
TickPlacement="Outside"
|
||||
Value="{x:Bind Appearance.FontWeight, Converter={StaticResource FontWeightConverter}, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Margin="10,0,0,0"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{Binding ElementName=FontWeightSlider, Path=Value, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Retro Terminal Effect -->
|
||||
<local:SettingContainer x:Uid="Profile_RetroTerminalEffect"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearRetroTerminalEffect}"
|
||||
HasSettingValue="{x:Bind Appearance.HasRetroTerminalEffect, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.RetroTerminalEffectOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Appearance.RetroTerminalEffect, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Cursor -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_CursorHeader"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<!-- Cursor Shape -->
|
||||
<local:SettingContainer x:Uid="Profile_CursorShape"
|
||||
Margin="0"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearCursorShape}"
|
||||
HasSettingValue="{x:Bind Appearance.HasCursorShape, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.CursorShapeOverrideSource, Mode=OneWay}">
|
||||
<muxc:RadioButtons ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
|
||||
ItemsSource="{x:Bind CursorShapeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentCursorShape, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Cursor Height -->
|
||||
<local:SettingContainer x:Uid="Profile_CursorHeight"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearCursorHeight}"
|
||||
HasSettingValue="{x:Bind Appearance.HasCursorHeight, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.CursorHeightOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind IsVintageCursor, Mode=OneWay}">
|
||||
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Name="CursorHeightSlider"
|
||||
Grid.Column="0"
|
||||
Maximum="100"
|
||||
Minimum="1"
|
||||
Value="{x:Bind Appearance.CursorHeight, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{Binding ElementName=CursorHeightSlider, Path=Value, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Background -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_BackgroundHeader"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<!-- Background Image -->
|
||||
<local:SettingContainer x:Name="BackgroundImageContainer"
|
||||
x:Uid="Profile_BackgroundImage"
|
||||
Margin="0"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearBackgroundImagePath}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackgroundImagePath, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundImagePathOverrideSource, Mode=OneWay}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox IsEnabled="{x:Bind Appearance.BackgroundImagePath, Mode=OneWay, Converter={StaticResource StringIsNotDesktopConverter}}"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Appearance.BackgroundImagePath, Mode=TwoWay, Converter={StaticResource DesktopWallpaperToEmptyStringConverter}}" />
|
||||
<Button x:Uid="Profile_BackgroundImageBrowse"
|
||||
Click="BackgroundImage_Click"
|
||||
IsEnabled="{x:Bind Appearance.BackgroundImagePath, Mode=OneWay, Converter={StaticResource StringIsNotDesktopConverter}}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="UseDesktopImageCheckBox"
|
||||
x:Uid="Profile_UseDesktopImage"
|
||||
IsChecked="{x:Bind Appearance.UseDesktopBGImage, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Image Stretch Mode -->
|
||||
<local:SettingContainer x:Uid="Profile_BackgroundImageStretchMode"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearBackgroundImageStretchMode}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackgroundImageStretchMode, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundImageStretchModeOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.BackgroundImageSettingsVisible, Mode=OneWay}">
|
||||
<muxc:RadioButtons ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
|
||||
ItemsSource="{x:Bind BackgroundImageStretchModeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentBackgroundImageStretchMode, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Image Alignment -->
|
||||
<local:SettingContainer x:Uid="Profile_BackgroundImageAlignment"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearBackgroundImageAlignment}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackgroundImageAlignment, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundImageAlignmentOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.BackgroundImageSettingsVisible, Mode=OneWay}">
|
||||
<Grid HorizontalAlignment="Left">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style BasedOn="{StaticResource DefaultToggleButtonStyle}"
|
||||
TargetType="ToggleButton">
|
||||
<Setter Property="Margin" Value="2" />
|
||||
<Setter Property="Width" Value="40" />
|
||||
<Setter Property="Height" Value="40" />
|
||||
<Setter Property="ToolTipService.Placement" Value="Mouse" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<!-- Top Row -->
|
||||
<ToggleButton x:Name="BIAlign_TopLeft"
|
||||
x:Uid="Profile_BackgroundImageAlignmentTopLeft"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Left (0x01) -->
|
||||
<x:Int32>17</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="90" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Top"
|
||||
x:Uid="Profile_BackgroundImageAlignmentTop"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Center (0x00) -->
|
||||
<x:Int32>16</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="180" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_TopRight"
|
||||
x:Uid="Profile_BackgroundImageAlignmentTopRight"
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Right (0x02) -->
|
||||
<x:Int32>18</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="270" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
|
||||
<!-- Middle Row -->
|
||||
<ToggleButton x:Name="BIAlign_Left"
|
||||
x:Uid="Profile_BackgroundImageAlignmentLeft"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Left (0x01) -->
|
||||
<x:Int32>1</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Center"
|
||||
x:Uid="Profile_BackgroundImageAlignmentCenter"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Center (0x00) -->
|
||||
<x:Int32>0</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Right"
|
||||
x:Uid="Profile_BackgroundImageAlignmentRight"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Right (0x02) -->
|
||||
<x:Int32>2</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
|
||||
<!-- Bottom Row -->
|
||||
<ToggleButton x:Name="BIAlign_BottomLeft"
|
||||
x:Uid="Profile_BackgroundImageAlignmentBottomLeft"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Bottom (0x20) | Horizontal_Left (0x01) -->
|
||||
<x:Int32>33</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Bottom"
|
||||
x:Uid="Profile_BackgroundImageAlignmentBottom"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Bottom (0x20) | Horizontal_Center (0x00) -->
|
||||
<x:Int32>32</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_BottomRight"
|
||||
x:Uid="Profile_BackgroundImageAlignmentBottomRight"
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x20) | Horizontal_Right (0x02) -->
|
||||
<x:Int32>34</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Image Opacity -->
|
||||
<local:SettingContainer x:Name="BackgroundImageOpacityContainer"
|
||||
x:Uid="Profile_BackgroundImageOpacity"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearBackgroundImageOpacity}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackgroundImageOpacity, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundImageOpacityOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind Appearance.BackgroundImageSettingsVisible, Mode=OneWay}">
|
||||
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Name="BIOpacitySlider"
|
||||
Grid.Column="0"
|
||||
Value="{x:Bind Appearance.BackgroundImageOpacity, Converter={StaticResource PercentageConverter}, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{Binding ElementName=BIOpacitySlider, Path=Value, Mode=OneWay, Converter={StaticResource PercentageSignConverter}}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
|
@ -34,6 +34,7 @@ static const std::wstring_view launchTag{ L"Launch_Nav" };
|
|||
static const std::wstring_view interactionTag{ L"Interaction_Nav" };
|
||||
static const std::wstring_view renderingTag{ L"Rendering_Nav" };
|
||||
static const std::wstring_view actionsTag{ L"Actions_Nav" };
|
||||
static const std::wstring_view globalProfileTag{ L"GlobalProfile_Nav" };
|
||||
static const std::wstring_view addProfileTag{ L"AddProfile" };
|
||||
static const std::wstring_view colorSchemesTag{ L"ColorSchemes_Nav" };
|
||||
static const std::wstring_view globalAppearanceTag{ L"GlobalAppearance_Nav" };
|
||||
|
@ -131,7 +132,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
// refresh the current page using the SelectedItem data we collected before the refresh
|
||||
if (selectedItemTag)
|
||||
{
|
||||
for (const auto& item : menuItemsSTL)
|
||||
for (const auto& item : menuItems)
|
||||
{
|
||||
if (const auto& menuItem{ item.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
{
|
||||
|
@ -168,14 +169,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
}
|
||||
}
|
||||
|
||||
// couldn't find the selected item,
|
||||
// fallback to first menu item
|
||||
const auto& firstItem{ menuItems.GetAt(0) };
|
||||
// Couldn't find the selected item, fallback to first menu item
|
||||
// This happens when the selected item was a profile which doesn't exist in the new configuration
|
||||
// We can use menuItemsSTL here because the only things they miss are profile entries.
|
||||
const auto& firstItem{ menuItemsSTL.at(0).as<MUX::Controls::NavigationViewItem>() };
|
||||
SettingsNav().SelectedItem(firstItem);
|
||||
if (const auto& tag{ SettingsNav().SelectedItem().try_as<MUX::Controls::NavigationViewItem>().Tag() })
|
||||
{
|
||||
_Navigate(unbox_value<hstring>(tag));
|
||||
}
|
||||
_Navigate(unbox_value<hstring>(firstItem.Tag()));
|
||||
}
|
||||
|
||||
void MainPage::SetHostingWindow(uint64_t hostingWindow) noexcept
|
||||
|
@ -310,6 +309,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
contentFrame().Navigate(xaml_typename<Editor::ReadOnlyActions>(), actionsState);
|
||||
}
|
||||
}
|
||||
else if (clickedItemTag == globalProfileTag)
|
||||
{
|
||||
auto profileVM{ _viewModelForProfile(_settingsClone.ProfileDefaults(), _settingsClone) };
|
||||
profileVM.IsBaseLayer(true);
|
||||
_lastProfilesNavState = winrt::make<ProfilePageNavigationState>(profileVM,
|
||||
_settingsClone.GlobalSettings().ColorSchemes(),
|
||||
_lastProfilesNavState,
|
||||
*this);
|
||||
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), _lastProfilesNavState);
|
||||
}
|
||||
else if (clickedItemTag == colorSchemesTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), _colorSchemesNavState);
|
||||
|
@ -471,4 +481,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
SettingsNav().SelectedItem(newSelectedItem);
|
||||
_Navigate(newSelectedItem.try_as<MUX::Controls::NavigationViewItem>().Tag().try_as<Editor::ProfileViewModel>());
|
||||
}
|
||||
|
||||
bool MainPage::ShowBaseLayerMenuItem() const noexcept
|
||||
{
|
||||
return Feature_ShowProfileDefaultsInSettings::IsEnabled();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
bool TryPropagateHostingWindow(IInspectable object) noexcept;
|
||||
uint64_t GetHostingWindow() const noexcept;
|
||||
|
||||
bool ShowBaseLayerMenuItem() const noexcept;
|
||||
|
||||
TYPED_EVENT(OpenJson, Windows::Foundation::IInspectable, Model::SettingsTarget);
|
||||
|
||||
private:
|
||||
|
|
|
@ -23,5 +23,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
// Due to the aforementioned bug, we can't use IInitializeWithWindow _here_ either.
|
||||
// Let's just smuggle the HWND in as a UInt64 :|
|
||||
void SetHostingWindow(UInt64 window);
|
||||
|
||||
Boolean ShowBaseLayerMenuItem { get; };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,15 @@
|
|||
|
||||
<muxc:NavigationViewItemHeader x:Uid="Nav_Profiles" />
|
||||
|
||||
<muxc:NavigationViewItem x:Name="BaseLayerMenuItem"
|
||||
x:Uid="Nav_ProfileDefaults"
|
||||
Tag="GlobalProfile_Nav"
|
||||
Visibility="{x:Bind ShowBaseLayerMenuItem}">
|
||||
<muxc:NavigationViewItem.Icon>
|
||||
<FontIcon Glyph="" />
|
||||
</muxc:NavigationViewItem.Icon>
|
||||
</muxc:NavigationViewItem>
|
||||
|
||||
</muxc:NavigationView.MenuItems>
|
||||
|
||||
<muxc:NavigationView.PaneFooter>
|
||||
|
@ -107,8 +116,9 @@
|
|||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Frame x:Name="contentFrame"
|
||||
Grid.Row="0" />
|
||||
<ScrollViewer Grid.Row="0">
|
||||
<Frame x:Name="contentFrame" />
|
||||
</ScrollViewer>
|
||||
<Grid Grid.Row="1"
|
||||
Height="100"
|
||||
BorderBrush="{ThemeResource SystemBaseLowColor}"
|
||||
|
|
|
@ -99,6 +99,10 @@
|
|||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Appearances.h">
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ReadOnlyActions.h">
|
||||
<DependentUpon>ReadOnlyActions.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
|
@ -143,6 +147,9 @@
|
|||
<Page Include="ReadOnlyActions.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Appearances.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Rendering.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
|
@ -215,6 +222,10 @@
|
|||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Appearances.cpp">
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ReadOnlyActions.cpp">
|
||||
<DependentUpon>ReadOnlyActions.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
|
@ -272,6 +283,10 @@
|
|||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="Appearances.idl">
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SettingContainer.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<Page Include="Launch.xaml" />
|
||||
<Page Include="MainPage.xaml" />
|
||||
<Page Include="Profiles.xaml" />
|
||||
<Page Include="Appearances.xaml" />
|
||||
<Page Include="Rendering.xaml" />
|
||||
<Page Include="Actions.xaml" />
|
||||
<Page Include="SettingContainerStyle.xaml" />
|
||||
|
|
|
@ -23,64 +23,6 @@ static const std::array<winrt::guid, 2> InBoxProfileGuids{
|
|||
winrt::guid{ 0x0caa0dad, 0x35be, 0x5f56, { 0xa8, 0xff, 0xaf, 0xce, 0xee, 0xaa, 0x61, 0x01 } } // Command Prompt
|
||||
};
|
||||
|
||||
// Function Description:
|
||||
// - This function presents a File Open "common dialog" and returns its selected file asynchronously.
|
||||
// Parameters:
|
||||
// - customize: A lambda that receives an IFileDialog* to customize.
|
||||
// Return value:
|
||||
// (async) path to the selected item.
|
||||
template<typename TLambda>
|
||||
static winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> OpenFilePicker(HWND parentHwnd, TLambda&& customize)
|
||||
{
|
||||
auto fileDialog{ winrt::create_instance<IFileDialog>(CLSID_FileOpenDialog) };
|
||||
DWORD flags{};
|
||||
THROW_IF_FAILED(fileDialog->GetOptions(&flags));
|
||||
THROW_IF_FAILED(fileDialog->SetOptions(flags | FOS_FORCEFILESYSTEM | FOS_NOCHANGEDIR | FOS_DONTADDTORECENT)); // filesystem objects only; no recent places
|
||||
customize(fileDialog.get());
|
||||
|
||||
auto hr{ fileDialog->Show(parentHwnd) };
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))
|
||||
{
|
||||
co_return winrt::hstring{};
|
||||
}
|
||||
THROW_HR(hr);
|
||||
}
|
||||
|
||||
winrt::com_ptr<IShellItem> result;
|
||||
THROW_IF_FAILED(fileDialog->GetResult(result.put()));
|
||||
|
||||
wil::unique_cotaskmem_string filePath;
|
||||
THROW_IF_FAILED(result->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
|
||||
|
||||
co_return winrt::hstring{ filePath.get() };
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Helper that opens a file picker pre-seeded with image file types.
|
||||
static winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> OpenImagePicker(HWND parentHwnd)
|
||||
{
|
||||
static constexpr COMDLG_FILTERSPEC supportedImageFileTypes[] = {
|
||||
{ L"All Supported Bitmap Types (*.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico)", L"*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff;*.ico" },
|
||||
{ L"All Files (*.*)", L"*.*" }
|
||||
};
|
||||
|
||||
static constexpr winrt::guid clientGuidImagePicker{ 0x55675F54, 0x74A1, 0x4552, { 0xA3, 0x9D, 0x94, 0xAE, 0x85, 0xD8, 0xF2, 0x7A } };
|
||||
return OpenFilePicker(parentHwnd, [](auto&& dialog) {
|
||||
THROW_IF_FAILED(dialog->SetClientGuid(clientGuidImagePicker));
|
||||
try
|
||||
{
|
||||
auto pictureFolderShellItem{ winrt::capture<IShellItem>(&SHGetKnownFolderItem, FOLDERID_PicturesLibrary, KF_FLAG_DEFAULT, nullptr) };
|
||||
dialog->SetDefaultFolder(pictureFolderShellItem.get());
|
||||
}
|
||||
CATCH_LOG(); // non-fatal
|
||||
THROW_IF_FAILED(dialog->SetFileTypes(ARRAYSIZE(supportedImageFileTypes), supportedImageFileTypes));
|
||||
THROW_IF_FAILED(dialog->SetFileTypeIndex(1)); // the array is 1-indexed
|
||||
THROW_IF_FAILED(dialog->SetDefaultExtension(L"jpg;jpeg;png;bmp;gif;tiff;ico"));
|
||||
});
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
Windows::Foundation::Collections::IObservableVector<Editor::Font> ProfileViewModel::_MonospaceFontList{ nullptr };
|
||||
|
@ -88,26 +30,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
|
||||
ProfileViewModel::ProfileViewModel(const Model::Profile& profile, const Model::CascadiaSettings& appSettings) :
|
||||
_profile{ profile },
|
||||
_defaultAppearanceViewModel{ winrt::make<implementation::AppearanceViewModel>(profile.DefaultAppearance().try_as<AppearanceConfig>()) },
|
||||
_originalProfileGuid{ profile.Guid() },
|
||||
_ShowAllFonts{ false },
|
||||
_appSettings{ appSettings }
|
||||
_appSettings{ appSettings },
|
||||
_unfocusedAppearanceViewModel{ nullptr }
|
||||
{
|
||||
// Add a property changed handler to our own property changed event.
|
||||
// This propagates changes from the settings model to anybody listening to our
|
||||
// unique view model members.
|
||||
PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
|
||||
const auto viewModelProperty{ args.PropertyName() };
|
||||
if (viewModelProperty == L"BackgroundImagePath")
|
||||
{
|
||||
// notify listener that all background image related values might have changed
|
||||
//
|
||||
// We need to do this so if someone manually types "desktopWallpaper"
|
||||
// into the path TextBox, we properly update the checkbox and stored
|
||||
// _lastBgImagePath. Without this, then we'll permanently hide the text
|
||||
// box, prevent it from ever being changed again.
|
||||
_NotifyChanges(L"UseDesktopBGImage", L"BackgroundImageSettingsVisible");
|
||||
}
|
||||
else if (viewModelProperty == L"IsBaseLayer")
|
||||
if (viewModelProperty == L"IsBaseLayer")
|
||||
{
|
||||
// we _always_ want to show the background image settings in base layer
|
||||
_NotifyChanges(L"BackgroundImageSettingsVisible");
|
||||
|
@ -118,25 +51,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
// NOTE: this is similar to what is done with BackgroundImagePath above
|
||||
_NotifyChanges(L"UseParentProcessDirectory", L"UseCustomStartingDirectory");
|
||||
}
|
||||
else if (viewModelProperty == L"FontFace")
|
||||
{
|
||||
// notify listener that all font face related values might have changed
|
||||
if (!UsingMonospaceFont())
|
||||
{
|
||||
_ShowAllFonts = true;
|
||||
}
|
||||
_NotifyChanges(L"ShowAllFonts", L"UsingMonospaceFont");
|
||||
}
|
||||
});
|
||||
|
||||
// Cache the original BG image path. If the user clicks "Use desktop
|
||||
// wallpaper", then un-checks it, this is the string we'll restore to
|
||||
// them.
|
||||
if (BackgroundImagePath() != L"desktopWallpaper")
|
||||
{
|
||||
_lastBgImagePath = BackgroundImagePath();
|
||||
}
|
||||
|
||||
// Do the same for the starting directory
|
||||
if (!StartingDirectory().empty())
|
||||
{
|
||||
|
@ -148,11 +64,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
{
|
||||
UpdateFontList();
|
||||
}
|
||||
|
||||
if (profile.HasUnfocusedAppearance())
|
||||
{
|
||||
_unfocusedAppearanceViewModel = winrt::make<implementation::AppearanceViewModel>(profile.UnfocusedAppearance().try_as<AppearanceConfig>());
|
||||
}
|
||||
|
||||
_defaultAppearanceViewModel.IsDefault(true);
|
||||
}
|
||||
|
||||
Model::TerminalSettings ProfileViewModel::TermSettings() const
|
||||
{
|
||||
return Model::TerminalSettings::CreateWithProfileByID(_appSettings, _profile.Guid(), nullptr).DefaultSettings();
|
||||
return Model::TerminalSettings::CreateWithProfile(_appSettings, _profile, nullptr).DefaultSettings();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -291,41 +214,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
return _MonospaceFontList;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Searches through our list of monospace fonts to determine if the settings model's current font face is a monospace font
|
||||
// - NOTE: This is information stored from DWrite in _UpdateFontList()
|
||||
bool ProfileViewModel::UsingMonospaceFont() const noexcept
|
||||
{
|
||||
bool result{ false };
|
||||
const auto currentFont{ FontFace() };
|
||||
for (const auto& font : _MonospaceFontList)
|
||||
{
|
||||
if (font.LocalizedName() == currentFont)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether we should show the list of all the fonts, or we should just show monospace fonts
|
||||
bool ProfileViewModel::ShowAllFonts() const noexcept
|
||||
{
|
||||
// - _ShowAllFonts is directly bound to the checkbox. So this is the user set value.
|
||||
// - If we are not using a monospace font, show all of the fonts so that the ComboBox is still properly bound
|
||||
return _ShowAllFonts || !UsingMonospaceFont();
|
||||
}
|
||||
|
||||
void ProfileViewModel::ShowAllFonts(const bool& value)
|
||||
{
|
||||
if (_ShowAllFonts != value)
|
||||
{
|
||||
_ShowAllFonts = value;
|
||||
_NotifyChanges(L"ShowAllFonts");
|
||||
}
|
||||
}
|
||||
|
||||
winrt::guid ProfileViewModel::OriginalProfileGuid() const noexcept
|
||||
{
|
||||
return _originalProfileGuid;
|
||||
|
@ -354,33 +242,54 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
}
|
||||
}
|
||||
|
||||
bool ProfileViewModel::UseDesktopBGImage()
|
||||
Editor::AppearanceViewModel ProfileViewModel::DefaultAppearance()
|
||||
{
|
||||
return BackgroundImagePath() == L"desktopWallpaper";
|
||||
return _defaultAppearanceViewModel;
|
||||
}
|
||||
|
||||
void ProfileViewModel::UseDesktopBGImage(const bool useDesktop)
|
||||
bool ProfileViewModel::HasUnfocusedAppearance()
|
||||
{
|
||||
if (useDesktop)
|
||||
return _profile.HasUnfocusedAppearance();
|
||||
}
|
||||
|
||||
bool ProfileViewModel::EditableUnfocusedAppearance()
|
||||
{
|
||||
if constexpr (Feature_EditableUnfocusedAppearance::IsEnabled())
|
||||
{
|
||||
// Stash the current value of BackgroundImagePath. If the user
|
||||
// checks and un-checks the "Use desktop wallpaper" button, we want
|
||||
// the path that we display in the text box to remain unchanged.
|
||||
//
|
||||
// Only stash this value if it's not the special "desktopWallpaper"
|
||||
// value.
|
||||
if (BackgroundImagePath() != L"desktopWallpaper")
|
||||
{
|
||||
_lastBgImagePath = BackgroundImagePath();
|
||||
}
|
||||
BackgroundImagePath(L"desktopWallpaper");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore the path we had previously cached. This might be the
|
||||
// empty string.
|
||||
BackgroundImagePath(_lastBgImagePath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProfileViewModel::ShowUnfocusedAppearance()
|
||||
{
|
||||
return EditableUnfocusedAppearance() && HasUnfocusedAppearance();
|
||||
}
|
||||
|
||||
void ProfileViewModel::CreateUnfocusedAppearance(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& schemes,
|
||||
const IHostedInWindow& windowRoot)
|
||||
{
|
||||
_profile.CreateUnfocusedAppearance();
|
||||
|
||||
_unfocusedAppearanceViewModel = winrt::make<implementation::AppearanceViewModel>(_profile.UnfocusedAppearance().try_as<AppearanceConfig>());
|
||||
_unfocusedAppearanceViewModel.Schemes(schemes);
|
||||
_unfocusedAppearanceViewModel.WindowRoot(windowRoot);
|
||||
|
||||
_NotifyChanges(L"UnfocusedAppearance", L"HasUnfocusedAppearance");
|
||||
}
|
||||
|
||||
void ProfileViewModel::DeleteUnfocusedAppearance()
|
||||
{
|
||||
_profile.DeleteUnfocusedAppearance();
|
||||
|
||||
_unfocusedAppearanceViewModel = nullptr;
|
||||
|
||||
_NotifyChanges(L"HasUnfocusedAppearance");
|
||||
}
|
||||
|
||||
Editor::AppearanceViewModel ProfileViewModel::UnfocusedAppearance()
|
||||
{
|
||||
return _unfocusedAppearanceViewModel;
|
||||
}
|
||||
|
||||
bool ProfileViewModel::UseParentProcessDirectory()
|
||||
|
@ -429,61 +338,34 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
}
|
||||
}
|
||||
|
||||
bool ProfileViewModel::BackgroundImageSettingsVisible()
|
||||
{
|
||||
return IsBaseLayer() || BackgroundImagePath() != L"";
|
||||
}
|
||||
|
||||
void ProfilePageNavigationState::DeleteProfile()
|
||||
{
|
||||
auto deleteProfileArgs{ winrt::make_self<DeleteProfileEventArgs>(_Profile.Guid()) };
|
||||
_DeleteProfileHandlers(*this, *deleteProfileArgs);
|
||||
}
|
||||
|
||||
void ProfilePageNavigationState::CreateUnfocusedAppearance()
|
||||
{
|
||||
_Profile.CreateUnfocusedAppearance(_Schemes, _WindowRoot);
|
||||
}
|
||||
|
||||
void ProfilePageNavigationState::DeleteUnfocusedAppearance()
|
||||
{
|
||||
_Profile.DeleteUnfocusedAppearance();
|
||||
}
|
||||
|
||||
Profiles::Profiles() :
|
||||
_ColorSchemeList{ single_threaded_observable_vector<ColorScheme>() },
|
||||
_previewControl{ Control::TermControl(Model::TerminalSettings{}, make<PreviewConnection>()) }
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(CursorShape, CursorStyle, winrt::Microsoft::Terminal::Core::CursorStyle, L"Profile_CursorShape", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING_REVERSE_ORDER(BackgroundImageStretchMode, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch, L"Profile_BackgroundImageStretchMode", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(AntiAliasingMode, TextAntialiasingMode, winrt::Microsoft::Terminal::Control::TextAntialiasingMode, L"Profile_AntialiasingMode", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING_REVERSE_ORDER(CloseOnExitMode, CloseOnExitMode, winrt::Microsoft::Terminal::Settings::Model::CloseOnExitMode, L"Profile_CloseOnExit", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(ScrollState, ScrollbarState, winrt::Microsoft::Terminal::Control::ScrollbarState, L"Profile_ScrollbarVisibility", L"Content");
|
||||
|
||||
// manually add Custom FontWeight option. Don't add it to the Map
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(FontWeight, FontWeight, uint16_t, L"Profile_FontWeight", L"Content");
|
||||
_CustomFontWeight = winrt::make<EnumEntry>(RS_(L"Profile_FontWeightCustom/Content"), winrt::box_value<uint16_t>(0u));
|
||||
_FontWeightList.Append(_CustomFontWeight);
|
||||
|
||||
// manually keep track of all the Background Image Alignment buttons
|
||||
_BIAlignmentButtons.at(0) = BIAlign_TopLeft();
|
||||
_BIAlignmentButtons.at(1) = BIAlign_Top();
|
||||
_BIAlignmentButtons.at(2) = BIAlign_TopRight();
|
||||
_BIAlignmentButtons.at(3) = BIAlign_Left();
|
||||
_BIAlignmentButtons.at(4) = BIAlign_Center();
|
||||
_BIAlignmentButtons.at(5) = BIAlign_Right();
|
||||
_BIAlignmentButtons.at(6) = BIAlign_BottomLeft();
|
||||
_BIAlignmentButtons.at(7) = BIAlign_Bottom();
|
||||
_BIAlignmentButtons.at(8) = BIAlign_BottomRight();
|
||||
|
||||
// apply automation properties to more complex setting controls
|
||||
for (const auto& biButton : _BIAlignmentButtons)
|
||||
{
|
||||
const auto tooltip{ ToolTipService::GetToolTip(biButton) };
|
||||
Automation::AutomationProperties::SetName(biButton, unbox_value<hstring>(tooltip));
|
||||
}
|
||||
|
||||
const auto startingDirCheckboxTooltip{ ToolTipService::GetToolTip(StartingDirectoryUseParentCheckbox()) };
|
||||
Automation::AutomationProperties::SetFullDescription(StartingDirectoryUseParentCheckbox(), unbox_value<hstring>(startingDirCheckboxTooltip));
|
||||
|
||||
const auto backgroundImgCheckboxTooltip{ ToolTipService::GetToolTip(UseDesktopImageCheckBox()) };
|
||||
Automation::AutomationProperties::SetFullDescription(UseDesktopImageCheckBox(), unbox_value<hstring>(backgroundImgCheckboxTooltip));
|
||||
|
||||
const auto showAllFontsCheckboxTooltip{ ToolTipService::GetToolTip(ShowAllFontsCheckbox()) };
|
||||
Automation::AutomationProperties::SetFullDescription(ShowAllFontsCheckbox(), unbox_value<hstring>(showAllFontsCheckboxTooltip));
|
||||
|
||||
Automation::AutomationProperties::SetName(DeleteButton(), RS_(L"Profile_DeleteButton/Text"));
|
||||
|
||||
_previewControl.IsEnabled(false);
|
||||
|
@ -491,38 +373,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
ControlPreview().Child(_previewControl);
|
||||
}
|
||||
|
||||
IInspectable Profiles::CurrentFontFace() const
|
||||
{
|
||||
// look for the current font in our shown list of fonts
|
||||
const auto& profileVM{ State().Profile() };
|
||||
const auto profileFontFace{ profileVM.FontFace() };
|
||||
const auto& currentFontList{ profileVM.ShowAllFonts() ? profileVM.CompleteFontList() : profileVM.MonospaceFontList() };
|
||||
IInspectable fallbackFont;
|
||||
for (const auto& font : currentFontList)
|
||||
{
|
||||
if (font.LocalizedName() == profileFontFace)
|
||||
{
|
||||
return box_value(font);
|
||||
}
|
||||
else if (font.LocalizedName() == L"Cascadia Mono")
|
||||
{
|
||||
fallbackFont = box_value(font);
|
||||
}
|
||||
}
|
||||
|
||||
// we couldn't find the desired font, set to "Cascadia Mono" since that ships by default
|
||||
return fallbackFont;
|
||||
}
|
||||
|
||||
void Profiles::FontFace_SelectionChanged(IInspectable const& /*sender*/, SelectionChangedEventArgs const& e)
|
||||
{
|
||||
// NOTE: We need to hook up a selection changed event handler here instead of directly binding to the profile view model.
|
||||
// A two way binding to the view model causes an infinite loop because both combo boxes keep fighting over which one's right.
|
||||
const auto selectedItem{ e.AddedItems().GetAt(0) };
|
||||
const auto newFontFace{ unbox_value<Editor::Font>(selectedItem) };
|
||||
State().Profile().FontFace(newFontFace.LocalizedName());
|
||||
}
|
||||
|
||||
void Profiles::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
{
|
||||
_State = e.Parameter().as<Editor::ProfilePageNavigationState>();
|
||||
|
@ -533,18 +383,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
ProfileViewModel::UpdateFontList();
|
||||
}
|
||||
|
||||
const auto& colorSchemeMap{ _State.Schemes() };
|
||||
for (const auto& pair : colorSchemeMap)
|
||||
{
|
||||
_ColorSchemeList.Append(pair.Value());
|
||||
}
|
||||
|
||||
const auto& biAlignmentVal{ static_cast<int32_t>(_State.Profile().BackgroundImageAlignment()) };
|
||||
for (const auto& biButton : _BIAlignmentButtons)
|
||||
{
|
||||
biButton.IsChecked(biButton.Tag().as<int32_t>() == biAlignmentVal);
|
||||
}
|
||||
|
||||
// Set the text disclaimer for the text box
|
||||
hstring disclaimer{};
|
||||
const auto guid{ _State.Profile().Guid() };
|
||||
|
@ -571,16 +409,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
// and propagate those changes to the UI
|
||||
_ViewModelChangedRevoker = _State.Profile().PropertyChanged(winrt::auto_revoke, [=](auto&&, const PropertyChangedEventArgs& args) {
|
||||
const auto settingName{ args.PropertyName() };
|
||||
if (settingName == L"CursorShape")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentCursorShape" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsVintageCursor" });
|
||||
}
|
||||
else if (settingName == L"BackgroundImageStretchMode")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentBackgroundImageStretchMode" });
|
||||
}
|
||||
else if (settingName == L"AntialiasingMode")
|
||||
if (settingName == L"AntialiasingMode")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentAntiAliasingMode" });
|
||||
}
|
||||
|
@ -596,23 +425,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentScrollState" });
|
||||
}
|
||||
else if (settingName == L"FontWeight")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentFontWeight" });
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsCustomFontWeight" });
|
||||
}
|
||||
else if (settingName == L"ColorSchemeName")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentColorScheme" });
|
||||
}
|
||||
else if (settingName == L"FontFace" || settingName == L"CurrentFontList")
|
||||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentFontFace" });
|
||||
}
|
||||
else if (settingName == L"BackgroundImageAlignment")
|
||||
{
|
||||
_UpdateBIAlignmentControl(static_cast<int32_t>(_State.Profile().BackgroundImageAlignment()));
|
||||
}
|
||||
_previewControl.Settings(_State.Profile().TermSettings());
|
||||
_previewControl.UpdateSettings();
|
||||
});
|
||||
|
||||
// The Appearances object handles updating the values in the settings UI, but
|
||||
// we still need to listen to the changes here just to update the preview control
|
||||
_AppearanceViewModelChangedRevoker = _State.Profile().DefaultAppearance().PropertyChanged(winrt::auto_revoke, [=](auto&&, const PropertyChangedEventArgs& /*args*/) {
|
||||
_previewControl.Settings(_State.Profile().TermSettings());
|
||||
_previewControl.UpdateSettings();
|
||||
});
|
||||
|
@ -632,26 +451,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
void Profiles::OnNavigatedFrom(const NavigationEventArgs& /*e*/)
|
||||
{
|
||||
_ViewModelChangedRevoker.revoke();
|
||||
}
|
||||
|
||||
ColorScheme Profiles::CurrentColorScheme()
|
||||
{
|
||||
const auto schemeName{ _State.Profile().ColorSchemeName() };
|
||||
if (const auto scheme{ _State.Schemes().TryLookup(schemeName) })
|
||||
{
|
||||
return scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This Profile points to a color scheme that was renamed or deleted.
|
||||
// Fallback to Campbell.
|
||||
return _State.Schemes().TryLookup(L"Campbell");
|
||||
}
|
||||
}
|
||||
|
||||
void Profiles::CurrentColorScheme(const ColorScheme& val)
|
||||
{
|
||||
_State.Profile().ColorSchemeName(val.Name());
|
||||
_AppearanceViewModelChangedRevoker.revoke();
|
||||
}
|
||||
|
||||
bool Profiles::IsBellStyleFlagSet(const uint32_t flag)
|
||||
|
@ -686,16 +486,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
state->DeleteProfile();
|
||||
}
|
||||
|
||||
fire_and_forget Profiles::BackgroundImage_Click(IInspectable const&, RoutedEventArgs const&)
|
||||
void Profiles::CreateUnfocusedAppearance_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
auto lifetime = get_strong();
|
||||
_State.CreateUnfocusedAppearance();
|
||||
}
|
||||
|
||||
const auto parentHwnd{ reinterpret_cast<HWND>(_State.WindowRoot().GetHostingWindow()) };
|
||||
auto file = co_await OpenImagePicker(parentHwnd);
|
||||
if (!file.empty())
|
||||
{
|
||||
_State.Profile().BackgroundImagePath(file);
|
||||
}
|
||||
void Profiles::DeleteUnfocusedAppearance_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
_State.DeleteUnfocusedAppearance();
|
||||
}
|
||||
|
||||
fire_and_forget Profiles::Icon_Click(IInspectable const&, RoutedEventArgs const&)
|
||||
|
@ -765,76 +563,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
}
|
||||
}
|
||||
|
||||
IInspectable Profiles::CurrentFontWeight() const
|
||||
{
|
||||
// if no value was found, we have a custom value
|
||||
const auto maybeEnumEntry{ _FontWeightMap.TryLookup(_State.Profile().FontWeight().Weight) };
|
||||
return maybeEnumEntry ? maybeEnumEntry : _CustomFontWeight;
|
||||
}
|
||||
|
||||
void Profiles::CurrentFontWeight(const IInspectable& enumEntry)
|
||||
{
|
||||
if (auto ee = enumEntry.try_as<Editor::EnumEntry>())
|
||||
{
|
||||
if (ee != _CustomFontWeight)
|
||||
{
|
||||
const auto weight{ winrt::unbox_value<uint16_t>(ee.EnumValue()) };
|
||||
const Windows::UI::Text::FontWeight setting{ weight };
|
||||
_State.Profile().FontWeight(setting);
|
||||
|
||||
// Profile does not have observable properties
|
||||
// So the TwoWay binding doesn't update on the State --> Slider direction
|
||||
FontWeightSlider().Value(weight);
|
||||
}
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"IsCustomFontWeight" });
|
||||
}
|
||||
}
|
||||
|
||||
bool Profiles::IsCustomFontWeight()
|
||||
{
|
||||
// Use SelectedItem instead of CurrentFontWeight.
|
||||
// CurrentFontWeight converts the Profile's value to the appropriate enum entry,
|
||||
// whereas SelectedItem identifies which one was selected by the user.
|
||||
return FontWeightComboBox().SelectedItem() == _CustomFontWeight;
|
||||
}
|
||||
|
||||
void Profiles::BIAlignment_Click(IInspectable const& sender, RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
if (const auto& button{ sender.try_as<Primitives::ToggleButton>() })
|
||||
{
|
||||
if (const auto& tag{ button.Tag().try_as<int32_t>() })
|
||||
{
|
||||
// Update the Profile's value and the control
|
||||
_State.Profile().BackgroundImageAlignment(static_cast<ConvergedAlignment>(*tag));
|
||||
_UpdateBIAlignmentControl(*tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resets all of the buttons to unchecked, and checks the one with the provided tag
|
||||
// Arguments:
|
||||
// - val - the background image alignment (ConvergedAlignment) that we want to represent in the control
|
||||
void Profiles::_UpdateBIAlignmentControl(const int32_t val)
|
||||
{
|
||||
for (const auto& biButton : _BIAlignmentButtons)
|
||||
{
|
||||
if (const auto& biButtonAlignment{ biButton.Tag().try_as<int32_t>() })
|
||||
{
|
||||
biButton.IsChecked(biButtonAlignment == val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Profiles::IsVintageCursor() const
|
||||
{
|
||||
return _State.Profile().CursorShape() == Core::CursorStyle::Vintage;
|
||||
}
|
||||
|
||||
void Profiles::Pivot_SelectionChanged(Windows::Foundation::IInspectable const& /*sender*/,
|
||||
RoutedEventArgs const& /*e*/)
|
||||
{
|
||||
_State.LastActivePivot(static_cast<Editor::ProfilesPivots>(ProfilesPivot().SelectedIndex()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,37 +3,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Font.g.h"
|
||||
#include "Profiles.g.h"
|
||||
#include "ProfilePageNavigationState.g.h"
|
||||
#include "DeleteProfileEventArgs.g.h"
|
||||
#include "ProfileViewModel.g.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
#include "Appearances.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct FontComparator
|
||||
{
|
||||
bool operator()(const Font& lhs, const Font& rhs) const
|
||||
{
|
||||
return lhs.LocalizedName() < rhs.LocalizedName();
|
||||
}
|
||||
};
|
||||
|
||||
struct Font : FontT<Font>
|
||||
{
|
||||
public:
|
||||
Font(std::wstring name, std::wstring localizedName) :
|
||||
_Name{ name },
|
||||
_LocalizedName{ localizedName } {};
|
||||
|
||||
hstring ToString() { return _LocalizedName; }
|
||||
|
||||
WINRT_PROPERTY(hstring, Name);
|
||||
WINRT_PROPERTY(hstring, LocalizedName);
|
||||
};
|
||||
|
||||
struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>, ViewModelHelper<ProfileViewModel>
|
||||
{
|
||||
public:
|
||||
|
@ -41,11 +20,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
|
||||
Model::TerminalSettings TermSettings() const;
|
||||
|
||||
// background image
|
||||
bool UseDesktopBGImage();
|
||||
void UseDesktopBGImage(const bool useDesktop);
|
||||
bool BackgroundImageSettingsVisible();
|
||||
|
||||
// starting directory
|
||||
bool UseParentProcessDirectory();
|
||||
void UseParentProcessDirectory(const bool useParent);
|
||||
|
@ -55,13 +29,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
static void UpdateFontList() noexcept;
|
||||
Windows::Foundation::Collections::IObservableVector<Editor::Font> CompleteFontList() const noexcept;
|
||||
Windows::Foundation::Collections::IObservableVector<Editor::Font> MonospaceFontList() const noexcept;
|
||||
bool UsingMonospaceFont() const noexcept;
|
||||
bool ShowAllFonts() const noexcept;
|
||||
void ShowAllFonts(const bool& value);
|
||||
|
||||
// general profile knowledge
|
||||
winrt::guid OriginalProfileGuid() const noexcept;
|
||||
bool CanDeleteProfile() const;
|
||||
Editor::AppearanceViewModel DefaultAppearance();
|
||||
Editor::AppearanceViewModel UnfocusedAppearance();
|
||||
bool HasUnfocusedAppearance();
|
||||
bool EditableUnfocusedAppearance();
|
||||
bool ShowUnfocusedAppearance();
|
||||
|
||||
void CreateUnfocusedAppearance(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& schemes,
|
||||
const IHostedInWindow& windowRoot);
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
WINRT_PROPERTY(bool, IsBaseLayer, false);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid);
|
||||
|
@ -77,21 +58,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
OBSERVABLE_PROJECTED_SETTING(_profile, UseAcrylic);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AcrylicOpacity);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, ScrollState);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.FontInfo(), FontFace);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.FontInfo(), FontSize);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.FontInfo(), FontWeight);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, Padding);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), BackgroundImagePath);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), BackgroundImageOpacity);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), BackgroundImageStretchMode);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), BackgroundImageAlignment);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), RetroTerminalEffect);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, ForceFullRepaintRendering);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, SoftwareRendering);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), ColorSchemeName);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Foreground);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Background);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), SelectionBackground);
|
||||
|
@ -99,8 +71,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
OBSERVABLE_PROJECTED_SETTING(_profile, HistorySize);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, SnapOnInput);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AltGrAliasing);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), CursorShape);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), CursorHeight);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, BellStyle);
|
||||
|
||||
private:
|
||||
|
@ -108,7 +78,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
winrt::guid _originalProfileGuid;
|
||||
winrt::hstring _lastBgImagePath;
|
||||
winrt::hstring _lastStartingDirectoryPath;
|
||||
bool _ShowAllFonts;
|
||||
Editor::AppearanceViewModel _defaultAppearanceViewModel;
|
||||
|
||||
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _MonospaceFontList;
|
||||
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _FontList;
|
||||
|
@ -116,6 +86,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
static Editor::Font _GetFont(com_ptr<IDWriteLocalizedStrings> localizedFamilyNames);
|
||||
|
||||
Model::CascadiaSettings _appSettings;
|
||||
Editor::AppearanceViewModel _unfocusedAppearanceViewModel;
|
||||
};
|
||||
|
||||
struct DeleteProfileEventArgs :
|
||||
|
@ -147,13 +118,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
{
|
||||
_LastActivePivot = lastState.LastActivePivot();
|
||||
}
|
||||
viewModel.DefaultAppearance().Schemes(schemes);
|
||||
viewModel.DefaultAppearance().WindowRoot(windowRoot);
|
||||
|
||||
if (viewModel.UnfocusedAppearance())
|
||||
{
|
||||
viewModel.UnfocusedAppearance().Schemes(schemes);
|
||||
viewModel.UnfocusedAppearance().WindowRoot(windowRoot);
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteProfile();
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> Schemes() { return _Schemes; }
|
||||
void Schemes(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& val) { _Schemes = val; }
|
||||
|
||||
TYPED_EVENT(DeleteProfile, Editor::ProfilePageNavigationState, Editor::DeleteProfileEventArgs);
|
||||
WINRT_PROPERTY(IHostedInWindow, WindowRoot, nullptr);
|
||||
WINRT_PROPERTY(Editor::ProfilesPivots, LastActivePivot, Editor::ProfilesPivots::General);
|
||||
|
@ -168,45 +148,26 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
public:
|
||||
Profiles();
|
||||
|
||||
// font face
|
||||
Windows::Foundation::IInspectable CurrentFontFace() const;
|
||||
|
||||
void OnNavigatedTo(const Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
void OnNavigatedFrom(const Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
Model::ColorScheme CurrentColorScheme();
|
||||
void CurrentColorScheme(const Model::ColorScheme& val);
|
||||
|
||||
// bell style bits
|
||||
bool IsBellStyleFlagSet(const uint32_t flag);
|
||||
void SetBellStyleAudible(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetBellStyleWindow(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
fire_and_forget BackgroundImage_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
fire_and_forget Commandline_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
fire_and_forget StartingDirectory_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
fire_and_forget Icon_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void BIAlignment_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void DeleteConfirmation_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void Pivot_SelectionChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void FontFace_SelectionChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& e);
|
||||
|
||||
// CursorShape visibility logic
|
||||
bool IsVintageCursor() const;
|
||||
|
||||
// manually bind FontWeight
|
||||
Windows::Foundation::IInspectable CurrentFontWeight() const;
|
||||
void CurrentFontWeight(const Windows::Foundation::IInspectable& enumEntry);
|
||||
bool IsCustomFontWeight();
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry>, FontWeightList);
|
||||
void CreateUnfocusedAppearance_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void DeleteUnfocusedAppearance_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
||||
WINRT_PROPERTY(Editor::ProfilePageNavigationState, State, nullptr);
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Model::ColorScheme>, ColorSchemeList, nullptr);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CursorShape, Microsoft::Terminal::Core::CursorStyle, State().Profile, CursorShape);
|
||||
GETSET_BINDABLE_ENUM_SETTING(BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch, State().Profile, BackgroundImageStretchMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AntiAliasingMode, Microsoft::Terminal::Control::TextAntialiasingMode, State().Profile, AntialiasingMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CloseOnExitMode, Microsoft::Terminal::Settings::Model::CloseOnExitMode, State().Profile, CloseOnExit);
|
||||
GETSET_BINDABLE_ENUM_SETTING(ScrollState, Microsoft::Terminal::Control::ScrollbarState, State().Profile, ScrollState);
|
||||
|
@ -214,10 +175,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
private:
|
||||
void _UpdateBIAlignmentControl(const int32_t val);
|
||||
|
||||
Windows::Foundation::Collections::IMap<uint16_t, Microsoft::Terminal::Settings::Editor::EnumEntry> _FontWeightMap;
|
||||
Editor::EnumEntry _CustomFontWeight{ nullptr };
|
||||
std::array<Windows::UI::Xaml::Controls::Primitives::ToggleButton, 9> _BIAlignmentButtons;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _AppearanceViewModelChangedRevoker;
|
||||
|
||||
Microsoft::Terminal::Control::TermControl _previewControl;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import "EnumEntry.idl";
|
||||
import "MainPage.idl";
|
||||
import "Appearances.idl";
|
||||
|
||||
#include "ViewModelHelpers.idl.h"
|
||||
|
||||
|
@ -12,12 +13,6 @@ import "MainPage.idl";
|
|||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass Font : Windows.Foundation.IStringable
|
||||
{
|
||||
String Name { get; };
|
||||
String LocalizedName { get; };
|
||||
}
|
||||
|
||||
runtimeclass ProfileViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
Windows.Foundation.Collections.IObservableVector<Font> CompleteFontList { get; };
|
||||
|
@ -25,14 +20,18 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
Microsoft.Terminal.Settings.Model.TerminalSettings TermSettings { get; };
|
||||
|
||||
Boolean CanDeleteProfile { get; };
|
||||
Boolean UsingMonospaceFont { get; };
|
||||
Boolean IsBaseLayer;
|
||||
Boolean UseDesktopBGImage;
|
||||
Boolean UseParentProcessDirectory;
|
||||
Boolean ShowAllFonts;
|
||||
Boolean UseCustomStartingDirectory { get; };
|
||||
Boolean BackgroundImageSettingsVisible { get; };
|
||||
AppearanceViewModel DefaultAppearance { get; };
|
||||
Guid OriginalProfileGuid { get; };
|
||||
Boolean HasUnfocusedAppearance { get; };
|
||||
Boolean EditableUnfocusedAppearance { get; };
|
||||
Boolean ShowUnfocusedAppearance { get; };
|
||||
AppearanceViewModel UnfocusedAppearance { get; };
|
||||
|
||||
void CreateUnfocusedAppearance(Windows.Foundation.Collections.IMapView<String, Microsoft.Terminal.Settings.Model.ColorScheme> Schemes, IHostedInWindow WindowRoot);
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Name);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, Guid);
|
||||
|
@ -47,21 +46,12 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, UseAcrylic);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Double, AcrylicOpacity);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.ScrollbarState, ScrollState);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, FontFace);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, FontSize);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.UI.Text.FontWeight, FontWeight);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Padding);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Commandline);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, StartingDirectory);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, BackgroundImagePath);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Double, BackgroundImageOpacity);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.UI.Xaml.Media.Stretch, BackgroundImageStretchMode);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.ConvergedAlignment, BackgroundImageAlignment);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.TextAntialiasingMode, AntialiasingMode);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RetroTerminalEffect);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ForceFullRepaintRendering);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SoftwareRendering);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, ColorSchemeName);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Foreground);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Background);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, SelectionBackground);
|
||||
|
@ -69,8 +59,6 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, HistorySize);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SnapOnInput);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AltGrAliasing);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Core.CursorStyle, CursorShape);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(UInt32, CursorHeight);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.BellStyle, BellStyle);
|
||||
}
|
||||
|
||||
|
@ -88,12 +76,14 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
|
||||
runtimeclass ProfilePageNavigationState
|
||||
{
|
||||
Windows.Foundation.Collections.IMapView<String, Microsoft.Terminal.Settings.Model.ColorScheme> Schemes;
|
||||
IHostedInWindow WindowRoot; // necessary to send the right HWND into the file picker dialogs.
|
||||
|
||||
ProfileViewModel Profile;
|
||||
ProfilesPivots LastActivePivot;
|
||||
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<ProfilePageNavigationState, DeleteProfileEventArgs> DeleteProfile;
|
||||
};
|
||||
|
||||
|
@ -107,13 +97,6 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
void SetBellStyleWindow(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
IInspectable CurrentCursorShape;
|
||||
Boolean IsVintageCursor { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> CursorShapeList { get; };
|
||||
|
||||
IInspectable CurrentBackgroundImageStretchMode;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> BackgroundImageStretchModeList { get; };
|
||||
|
||||
IInspectable CurrentAntiAliasingMode;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AntiAliasingModeList { get; };
|
||||
|
||||
|
@ -122,14 +105,5 @@ namespace Microsoft.Terminal.Settings.Editor
|
|||
|
||||
IInspectable CurrentScrollState;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> ScrollStateList { get; };
|
||||
|
||||
IInspectable CurrentFontWeight;
|
||||
Boolean IsCustomFontWeight { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> FontWeightList { get; };
|
||||
|
||||
Microsoft.Terminal.Settings.Model.ColorScheme CurrentColorScheme;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Model.ColorScheme> ColorSchemeList { get; };
|
||||
|
||||
IInspectable CurrentFontFace { get; };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<TextBlock FontFamily="{x:Bind Name}"
|
||||
Text="{x:Bind LocalizedName}" />
|
||||
</DataTemplate>
|
||||
|
||||
<local:ColorToBrushConverter x:Key="ColorToBrushConverter" />
|
||||
<local:PercentageConverter x:Key="PercentageConverter" />
|
||||
<local:PercentageSignConverter x:Key="PercentageSignConverter" />
|
||||
|
@ -237,400 +238,17 @@
|
|||
<PivotItem x:Uid="Profile_Appearance">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<!-- Control Preview -->
|
||||
<Border x:Name="ControlPreview"
|
||||
Width="350"
|
||||
Height="160"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="1" />
|
||||
<!-- Control Preview -->
|
||||
<Border x:Name="ControlPreview"
|
||||
Width="350"
|
||||
Height="160"
|
||||
Margin="0,0,0,12"
|
||||
HorizontalAlignment="Left"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="1" />
|
||||
|
||||
<!-- Grouping: Text -->
|
||||
<TextBlock x:Uid="Profile_TextHeader"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<!-- Color Scheme -->
|
||||
<local:SettingContainer x:Uid="Profile_ColorScheme"
|
||||
Margin="0"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearColorSchemeName}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasColorSchemeName, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.ColorSchemeNameOverrideSource, Mode=OneWay}">
|
||||
<ComboBox ItemsSource="{x:Bind ColorSchemeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentColorScheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:ColorScheme">
|
||||
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Face -->
|
||||
<local:SettingContainer x:Uid="Profile_FontFace"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearFontFace}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasFontFace, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.FontFaceOverrideSource, Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<!--
|
||||
Binding the ItemsSource to a separate variable that switches between the
|
||||
two font lists causes a crash within the ComboBox code.
|
||||
As a workaround, introduce two ComboBox controls and only display one at a time.
|
||||
-->
|
||||
<ComboBox ItemTemplate="{StaticResource FontFaceComboBoxItemTemplate}"
|
||||
ItemsSource="{x:Bind State.Profile.MonospaceFontList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentFontFace, Mode=OneWay}"
|
||||
SelectionChanged="FontFace_SelectionChanged"
|
||||
Style="{StaticResource ComboBoxSettingStyle}"
|
||||
Visibility="{x:Bind State.Profile.ShowAllFonts, Mode=OneWay, Converter={StaticResource InvertedBooleanToVisibilityConverter}}" />
|
||||
<ComboBox ItemTemplate="{StaticResource FontFaceComboBoxItemTemplate}"
|
||||
ItemsSource="{x:Bind State.Profile.CompleteFontList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentFontFace, Mode=OneWay}"
|
||||
SelectionChanged="FontFace_SelectionChanged"
|
||||
Style="{StaticResource ComboBoxSettingStyle}"
|
||||
Visibility="{x:Bind State.Profile.ShowAllFonts, Mode=OneWay}" />
|
||||
<CheckBox x:Name="ShowAllFontsCheckbox"
|
||||
x:Uid="Profile_FontFaceShowAllFonts"
|
||||
IsChecked="{x:Bind State.Profile.ShowAllFonts, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind State.Profile.UsingMonospaceFont, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Size -->
|
||||
<local:SettingContainer x:Uid="Profile_FontSize"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearFontSize}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasFontSize, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.FontSizeOverrideSource, Mode=OneWay}">
|
||||
<muxc:NumberBox AcceptsExpression="False"
|
||||
LargeChange="10"
|
||||
Maximum="128"
|
||||
Minimum="1"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind State.Profile.FontSize, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Font Weight -->
|
||||
<local:SettingContainer x:Name="FontWeightContainer"
|
||||
x:Uid="Profile_FontWeight"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearFontWeight}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasFontWeight, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.FontWeightOverrideSource, Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<ComboBox x:Name="FontWeightComboBox"
|
||||
ItemTemplate="{StaticResource EnumComboBoxItemTemplate}"
|
||||
ItemsSource="{x:Bind FontWeightList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentFontWeight, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
|
||||
<!-- Custom Font Weight Control -->
|
||||
<Grid Margin="0,10,0,0"
|
||||
Style="{StaticResource CustomSliderControlGridStyle}"
|
||||
Visibility="{x:Bind IsCustomFontWeight, Mode=OneWay}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Name="FontWeightSlider"
|
||||
Grid.Column="0"
|
||||
Maximum="1000"
|
||||
Minimum="0"
|
||||
TickFrequency="50"
|
||||
TickPlacement="Outside"
|
||||
Value="{x:Bind State.Profile.FontWeight, Converter={StaticResource FontWeightConverter}, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Margin="10,0,0,0"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{Binding ElementName=FontWeightSlider, Path=Value, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Retro Terminal Effect -->
|
||||
<local:SettingContainer x:Uid="Profile_RetroTerminalEffect"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearRetroTerminalEffect}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasRetroTerminalEffect, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.RetroTerminalEffectOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind State.Profile.RetroTerminalEffect, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Cursor -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_CursorHeader"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<!-- Cursor Shape -->
|
||||
<local:SettingContainer x:Uid="Profile_CursorShape"
|
||||
Margin="0"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearCursorShape}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasCursorShape, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.CursorShapeOverrideSource, Mode=OneWay}">
|
||||
<muxc:RadioButtons ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
|
||||
ItemsSource="{x:Bind CursorShapeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentCursorShape, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Cursor Height -->
|
||||
<local:SettingContainer x:Uid="Profile_CursorHeight"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearCursorHeight}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasCursorHeight, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.CursorHeightOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind IsVintageCursor, Mode=OneWay}">
|
||||
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Name="CursorHeightSlider"
|
||||
Grid.Column="0"
|
||||
Maximum="100"
|
||||
Minimum="1"
|
||||
Value="{x:Bind State.Profile.CursorHeight, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{Binding ElementName=CursorHeightSlider, Path=Value, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Background -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_BackgroundHeader"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<!-- Background Image -->
|
||||
<local:SettingContainer x:Name="BackgroundImageContainer"
|
||||
x:Uid="Profile_BackgroundImage"
|
||||
Margin="0"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearBackgroundImagePath}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasBackgroundImagePath, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.BackgroundImagePathOverrideSource, Mode=OneWay}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox IsEnabled="{x:Bind State.Profile.BackgroundImagePath, Mode=OneWay, Converter={StaticResource StringIsNotDesktopConverter}}"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind State.Profile.BackgroundImagePath, Mode=TwoWay, Converter={StaticResource DesktopWallpaperToEmptyStringConverter}}" />
|
||||
<Button x:Uid="Profile_BackgroundImageBrowse"
|
||||
Click="BackgroundImage_Click"
|
||||
IsEnabled="{x:Bind State.Profile.BackgroundImagePath, Mode=OneWay, Converter={StaticResource StringIsNotDesktopConverter}}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="UseDesktopImageCheckBox"
|
||||
x:Uid="Profile_UseDesktopImage"
|
||||
IsChecked="{x:Bind State.Profile.UseDesktopBGImage, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Image Stretch Mode -->
|
||||
<local:SettingContainer x:Uid="Profile_BackgroundImageStretchMode"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearBackgroundImageStretchMode}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasBackgroundImageStretchMode, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.BackgroundImageStretchModeOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind State.Profile.BackgroundImageSettingsVisible, Mode=OneWay}">
|
||||
<muxc:RadioButtons ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
|
||||
ItemsSource="{x:Bind BackgroundImageStretchModeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentBackgroundImageStretchMode, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Image Alignment -->
|
||||
<local:SettingContainer x:Uid="Profile_BackgroundImageAlignment"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearBackgroundImageAlignment}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasBackgroundImageAlignment, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.BackgroundImageAlignmentOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind State.Profile.BackgroundImageSettingsVisible, Mode=OneWay}">
|
||||
<Grid HorizontalAlignment="Left">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style BasedOn="{StaticResource DefaultToggleButtonStyle}"
|
||||
TargetType="ToggleButton">
|
||||
<Setter Property="Margin" Value="2" />
|
||||
<Setter Property="Width" Value="40" />
|
||||
<Setter Property="Height" Value="40" />
|
||||
<Setter Property="ToolTipService.Placement" Value="Mouse" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<!-- Top Row -->
|
||||
<ToggleButton x:Name="BIAlign_TopLeft"
|
||||
x:Uid="Profile_BackgroundImageAlignmentTopLeft"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Left (0x01) -->
|
||||
<x:Int32>17</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="90" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Top"
|
||||
x:Uid="Profile_BackgroundImageAlignmentTop"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Center (0x00) -->
|
||||
<x:Int32>16</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="180" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_TopRight"
|
||||
x:Uid="Profile_BackgroundImageAlignmentTopRight"
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Right (0x02) -->
|
||||
<x:Int32>18</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="270" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
|
||||
<!-- Middle Row -->
|
||||
<ToggleButton x:Name="BIAlign_Left"
|
||||
x:Uid="Profile_BackgroundImageAlignmentLeft"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Left (0x01) -->
|
||||
<x:Int32>1</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Center"
|
||||
x:Uid="Profile_BackgroundImageAlignmentCenter"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Center (0x00) -->
|
||||
<x:Int32>0</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Right"
|
||||
x:Uid="Profile_BackgroundImageAlignmentRight"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Right (0x02) -->
|
||||
<x:Int32>2</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
|
||||
<!-- Bottom Row -->
|
||||
<ToggleButton x:Name="BIAlign_BottomLeft"
|
||||
x:Uid="Profile_BackgroundImageAlignmentBottomLeft"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Bottom (0x20) | Horizontal_Left (0x01) -->
|
||||
<x:Int32>33</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_Bottom"
|
||||
x:Uid="Profile_BackgroundImageAlignmentBottom"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Bottom (0x20) | Horizontal_Center (0x00) -->
|
||||
<x:Int32>32</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="BIAlign_BottomRight"
|
||||
x:Uid="Profile_BackgroundImageAlignmentBottomRight"
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
Click="BIAlignment_Click">
|
||||
<ToggleButton.Tag>
|
||||
<!-- ConvergedAlignment: Vertical_Top (0x20) | Horizontal_Right (0x02) -->
|
||||
<x:Int32>34</x:Int32>
|
||||
</ToggleButton.Tag>
|
||||
<ToggleButton.Content>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Image Opacity -->
|
||||
<local:SettingContainer x:Name="BackgroundImageOpacityContainer"
|
||||
x:Uid="Profile_BackgroundImageOpacity"
|
||||
ClearSettingValue="{x:Bind State.Profile.ClearBackgroundImageOpacity}"
|
||||
HasSettingValue="{x:Bind State.Profile.HasBackgroundImageOpacity, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind State.Profile.BackgroundImageOpacityOverrideSource, Mode=OneWay}"
|
||||
Visibility="{x:Bind State.Profile.BackgroundImageSettingsVisible, Mode=OneWay}">
|
||||
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Name="BIOpacitySlider"
|
||||
Grid.Column="0"
|
||||
Value="{x:Bind State.Profile.BackgroundImageOpacity, Converter={StaticResource PercentageConverter}, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{Binding ElementName=BIOpacitySlider, Path=Value, Mode=OneWay, Converter={StaticResource PercentageSignConverter}}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
<local:Appearances Appearance="{x:Bind State.Profile.DefaultAppearance, Mode=OneWay}"
|
||||
SourceProfile="{x:Bind State.Profile, Mode=OneWay}" />
|
||||
|
||||
<!-- Grouping: Acrylic -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
|
@ -706,6 +324,84 @@
|
|||
SelectedItem="{x:Bind CurrentScrollState, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Visibility="{x:Bind State.Profile.EditableUnfocusedAppearance, Mode=OneWay}">
|
||||
<TextBlock x:Uid="Profile_UnfocusedAppearanceTextBlock"
|
||||
Style="{StaticResource TitleTextBlockStyle}" />
|
||||
<Button x:Uid="Profile_CreateUnfocusedAppearanceButton"
|
||||
Margin="32,0,0,0"
|
||||
Click="CreateUnfocusedAppearance_Click"
|
||||
Style="{StaticResource BaseButtonStyle}"
|
||||
Visibility="{x:Bind State.Profile.HasUnfocusedAppearance, Mode=OneWay, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Uid="Profile_DeleteUnfocusedAppearanceButton"
|
||||
Margin="32,0,0,0"
|
||||
Click="DeleteUnfocusedAppearance_Click"
|
||||
Style="{StaticResource BaseButtonStyle}"
|
||||
Visibility="{x:Bind State.Profile.HasUnfocusedAppearance, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<SolidColorBrush x:Key="ButtonBackground"
|
||||
Color="Firebrick" />
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
|
||||
Color="#C23232" />
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed"
|
||||
Color="#A21212" />
|
||||
<SolidColorBrush x:Key="ButtonForeground"
|
||||
Color="White" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
|
||||
Color="White" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed"
|
||||
Color="White" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<SolidColorBrush x:Key="ButtonBackground"
|
||||
Color="Firebrick" />
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
|
||||
Color="#C23232" />
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed"
|
||||
Color="#A21212" />
|
||||
<SolidColorBrush x:Key="ButtonForeground"
|
||||
Color="White" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
|
||||
Color="White" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed"
|
||||
Color="White" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<SolidColorBrush x:Key="ButtonBackground"
|
||||
Color="{ThemeResource SystemColorButtonFaceColor}" />
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
|
||||
Color="{ThemeResource SystemColorHighlightColor}" />
|
||||
<SolidColorBrush x:Key="ButtonBackgroundPressed"
|
||||
Color="{ThemeResource SystemColorHighlightColor}" />
|
||||
<SolidColorBrush x:Key="ButtonForeground"
|
||||
Color="{ThemeResource SystemColorButtonTextColor}" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
|
||||
Color="{ThemeResource SystemColorHighlightTextColor}" />
|
||||
<SolidColorBrush x:Key="ButtonForegroundPressed"
|
||||
Color="{ThemeResource SystemColorHighlightTextColor}" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Button.Resources>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<local:Appearances Appearance="{x:Bind State.Profile.UnfocusedAppearance, Mode=OneWay}"
|
||||
SourceProfile="{x:Bind State.Profile, Mode=OneWay}"
|
||||
Visibility="{x:Bind State.Profile.ShowUnfocusedAppearance, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
|
|
|
@ -452,8 +452,8 @@
|
|||
<comment>Header for a menu item. This opens the JSON file that is used to log the app's settings.</comment>
|
||||
</data>
|
||||
<data name="Nav_ProfileDefaults.Content" xml:space="preserve">
|
||||
<value>Base layer</value>
|
||||
<comment>Header for the "base layer" menu item. This navigates to a page that lets you see and modify settings that affect profiles. The base layer is the lowest layer of profile settings that all other profile settings are based on. If a profile doesn't define a setting, base layer is responsible for figuring out what that setting is supposed to be.</comment>
|
||||
<value>Defaults</value>
|
||||
<comment>Header for the "defaults" menu item. This navigates to a page that lets you see and modify settings that affect profiles. This is the lowest layer of profile settings that all other profile settings are based on. If a profile doesn't define a setting, this page is responsible for figuring out what that setting is supposed to be.</comment>
|
||||
</data>
|
||||
<data name="Nav_Rendering.Content" xml:space="preserve">
|
||||
<value>Rendering</value>
|
||||
|
@ -791,6 +791,10 @@
|
|||
<value>Replaces the profile name as the title to pass to the shell on startup.</value>
|
||||
<comment>A description for what the "tab title" setting does. Presented near "Profile_TabTitle".</comment>
|
||||
</data>
|
||||
<data name="Profile_UnfocusedAppearanceTextBlock.Text" xml:space="preserve">
|
||||
<value>Unfocused Appearance</value>
|
||||
<comment>The header for the section where the unfocused appearance settings can be changed.</comment>
|
||||
</data>
|
||||
<data name="Profile_UseAcrylic.Header" xml:space="preserve">
|
||||
<value>Enable acrylic</value>
|
||||
<comment>Header for a control to toggle the acrylic-like rendering of the background. The acrylic material creates a translucent texture.</comment>
|
||||
|
@ -1012,7 +1016,7 @@
|
|||
</data>
|
||||
<data name="Profile_BaseLayerDisclaimer.Text" xml:space="preserve">
|
||||
<value>Settings defined here will apply to all profiles unless they are overridden by a profile's settings.</value>
|
||||
<comment>A disclaimer presented at the top of a page. See "Nav_ProfileDefaults.Content" for a description on what the base layer does in the app.</comment>
|
||||
<comment>A disclaimer presented at the top of a page. See "Nav_ProfileDefaults.Content" for a description on what the defaults layer does in the app.</comment>
|
||||
</data>
|
||||
<data name="Profile_DeleteConfirmationButton.Content" xml:space="preserve">
|
||||
<value>Yes, delete profile</value>
|
||||
|
@ -1087,8 +1091,8 @@
|
|||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
</data>
|
||||
<data name="SettingContainer_OverrideMessageBaseLayer" xml:space="preserve">
|
||||
<value>Reset to base layer value.</value>
|
||||
<comment>"base layer" should match Nav_ProfileDefaults.Content's text. This is a text label on a button.</comment>
|
||||
<value>Reset to inherited value.</value>
|
||||
<comment>This button will remove a user's customization from a given setting, restoring it to the value that the profile inherited. This is a text label on a button.</comment>
|
||||
</data>
|
||||
<data name="ColorScheme_TerminalColorsHeader.Text" xml:space="preserve">
|
||||
<value>Terminal colors</value>
|
||||
|
@ -1110,6 +1114,14 @@
|
|||
<value>If checked, show all installed fonts in the list above. Otherwise, only show the list of monospace fonts.</value>
|
||||
<comment>A description for what the supplementary "show all fonts" setting does. Presented near "Profile_FontFaceShowAllFonts".</comment>
|
||||
</data>
|
||||
<data name="Profile_CreateUnfocusedAppearanceButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Create an unfocused appearance for this profile. This will be the appearance of the profile when it is inactive.</value>
|
||||
<comment>A description for what the create unfocused appearance button does.</comment>
|
||||
</data>
|
||||
<data name="Profile_DeleteUnfocusedAppearanceButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Delete the unfocused appearance for this profile.</value>
|
||||
<comment>A description for what the delete unfocused appearance button does.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteConfirmationButton.Content" xml:space="preserve">
|
||||
<value>Yes, delete key binding</value>
|
||||
<comment>Button label that confirms deletion of a key binding entry.</comment>
|
||||
|
|
|
@ -57,9 +57,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
_SettingOverrideSourceProperty =
|
||||
DependencyProperty::Register(
|
||||
L"SettingOverrideSource",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingContainer>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingContainer::_OnHasSettingValueChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,17 +152,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
// We want to be smart about showing the override system.
|
||||
// Don't just show it if the user explicitly set the setting.
|
||||
// If the tooltip is empty, we'll hide the entire override system.
|
||||
hstring tooltip{};
|
||||
|
||||
const auto& settingSrc{ SettingOverrideSource() };
|
||||
if (const auto& profile{ settingSrc.try_as<Model::Profile>() })
|
||||
{
|
||||
tooltip = _GenerateOverrideMessage(profile);
|
||||
}
|
||||
else if (const auto& appearanceConfig{ settingSrc.try_as<Model::AppearanceConfig>() })
|
||||
{
|
||||
tooltip = _GenerateOverrideMessage(appearanceConfig.SourceProfile());
|
||||
}
|
||||
const auto tooltip{ _GenerateOverrideMessage(settingSrc) };
|
||||
|
||||
Controls::ToolTipService::SetToolTip(button, box_value(tooltip));
|
||||
button.Visibility(tooltip.empty() ? Visibility::Collapsed : Visibility::Visible);
|
||||
|
@ -182,35 +174,43 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
// - profile: the profile that defines the setting (aka SettingOverrideSource)
|
||||
// Return Value:
|
||||
// - text specifying where the setting was defined. If empty, we don't want to show the system.
|
||||
hstring SettingContainer::_GenerateOverrideMessage(const Model::Profile& profile)
|
||||
hstring SettingContainer::_GenerateOverrideMessage(const IInspectable& settingOrigin)
|
||||
{
|
||||
const auto originTag{ profile.Origin() };
|
||||
if (originTag == Model::OriginTag::InBox)
|
||||
// We only get here if the user had an override in place.
|
||||
Model::OriginTag originTag{ Model::OriginTag::None };
|
||||
winrt::hstring source;
|
||||
|
||||
if (const auto& profile{ settingOrigin.try_as<Model::Profile>() })
|
||||
{
|
||||
// in-box profile
|
||||
return {};
|
||||
source = profile.Source();
|
||||
originTag = profile.Origin();
|
||||
}
|
||||
else if (originTag == Model::OriginTag::Generated)
|
||||
else if (const auto& appearanceConfig{ settingOrigin.try_as<Model::AppearanceConfig>() })
|
||||
{
|
||||
// from a dynamic profile generator
|
||||
return {};
|
||||
const auto profile = appearanceConfig.SourceProfile();
|
||||
source = profile.Source();
|
||||
originTag = profile.Origin();
|
||||
}
|
||||
else if (originTag == Model::OriginTag::Fragment)
|
||||
|
||||
if constexpr (Feature_ShowProfileDefaultsInSettings::IsEnabled())
|
||||
{
|
||||
// EXPERIMENTAL FEATURE
|
||||
// We will display arrows for all origins, and informative tooltips for Fragments and Generated
|
||||
if (originTag == Model::OriginTag::Fragment || originTag == Model::OriginTag::Generated)
|
||||
{
|
||||
// from a fragment extension or generated profile
|
||||
return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, source) };
|
||||
}
|
||||
return RS_(L"SettingContainer_OverrideMessageBaseLayer");
|
||||
}
|
||||
|
||||
// STABLE FEATURE
|
||||
// We will only display arrows and informative tooltips for Fragments
|
||||
if (originTag == Model::OriginTag::Fragment)
|
||||
{
|
||||
// from a fragment extension
|
||||
return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, profile.Source()) };
|
||||
}
|
||||
else
|
||||
{
|
||||
// base layer
|
||||
// TODO GH#3818: When we add profile inheritance as a setting,
|
||||
// we'll need an extra conditional check to see if this
|
||||
// is the base layer or some other profile
|
||||
|
||||
// GH#9539: Base Layer has been removed from the Settings UI.
|
||||
// In the event that the Base Layer comes back,
|
||||
// return RS_(L"SettingContainer_OverrideMessageBaseLayer") instead
|
||||
return {};
|
||||
return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, source) };
|
||||
}
|
||||
return {}; // no tooltip
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnHasSettingValueChanged(Windows::UI::Xaml::DependencyObject const& d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const& e);
|
||||
static hstring _GenerateOverrideMessage(const Model::Profile& profile);
|
||||
static hstring _GenerateOverrideMessage(const IInspectable& settingOrigin);
|
||||
void _UpdateOverrideSystem();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,30 @@ using namespace winrt::Windows::UI::Xaml;
|
|||
|
||||
UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.Settings.Editor/Resources");
|
||||
|
||||
// Function Description:
|
||||
// - Helper that opens a file picker pre-seeded with image file types.
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> OpenImagePicker(HWND parentHwnd)
|
||||
{
|
||||
static constexpr COMDLG_FILTERSPEC supportedImageFileTypes[] = {
|
||||
{ L"All Supported Bitmap Types (*.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico)", L"*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff;*.ico" },
|
||||
{ L"All Files (*.*)", L"*.*" }
|
||||
};
|
||||
|
||||
static constexpr winrt::guid clientGuidImagePicker{ 0x55675F54, 0x74A1, 0x4552, { 0xA3, 0x9D, 0x94, 0xAE, 0x85, 0xD8, 0xF2, 0x7A } };
|
||||
return OpenFilePicker(parentHwnd, [](auto&& dialog) {
|
||||
THROW_IF_FAILED(dialog->SetClientGuid(clientGuidImagePicker));
|
||||
try
|
||||
{
|
||||
auto pictureFolderShellItem{ winrt::capture<IShellItem>(&SHGetKnownFolderItem, FOLDERID_PicturesLibrary, KF_FLAG_DEFAULT, nullptr) };
|
||||
dialog->SetDefaultFolder(pictureFolderShellItem.get());
|
||||
}
|
||||
CATCH_LOG(); // non-fatal
|
||||
THROW_IF_FAILED(dialog->SetFileTypes(ARRAYSIZE(supportedImageFileTypes), supportedImageFileTypes));
|
||||
THROW_IF_FAILED(dialog->SetFileTypeIndex(1)); // the array is 1-indexed
|
||||
THROW_IF_FAILED(dialog->SetDefaultExtension(L"jpg;jpeg;png;bmp;gif;tiff;ico"));
|
||||
});
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings
|
||||
{
|
||||
hstring GetSelectedItemTag(winrt::Windows::Foundation::IInspectable const& comboBoxAsInspectable)
|
||||
|
|
|
@ -11,33 +11,39 @@
|
|||
// being its localized name, and also initializes the enum to EnumEntry
|
||||
// map that's required to tell XAML what enum value the currently active
|
||||
// setting has.
|
||||
#define INITIALIZE_BINDABLE_ENUM_SETTING(name, enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List; \
|
||||
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \
|
||||
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::##enumMappingsName(); \
|
||||
for (auto [key, value] : enumMapping##name) \
|
||||
{ \
|
||||
auto enumName = LocalizedNameForEnumName(resourceSectionAndType, key, resourceProperty); \
|
||||
auto entry = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::EnumEntry>(enumName, winrt::box_value<enumType>(value)); \
|
||||
name##List.emplace_back(entry); \
|
||||
_##name##Map.Insert(value, entry); \
|
||||
} \
|
||||
std::sort(begin(name##List), end(name##List), EnumEntryComparator<enumType>()); \
|
||||
_##name##List = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(std::move(name##List));
|
||||
#define INITIALIZE_BINDABLE_ENUM_SETTING(name, enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
|
||||
do \
|
||||
{ \
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List; \
|
||||
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \
|
||||
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::enumMappingsName(); \
|
||||
for (auto [key, value] : enumMapping##name) \
|
||||
{ \
|
||||
auto enumName = LocalizedNameForEnumName(resourceSectionAndType, key, resourceProperty); \
|
||||
auto entry = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::EnumEntry>(enumName, winrt::box_value<enumType>(value)); \
|
||||
name##List.emplace_back(entry); \
|
||||
_##name##Map.Insert(value, entry); \
|
||||
} \
|
||||
std::sort(name##List.begin(), name##List.end(), EnumEntryComparator<enumType>()); \
|
||||
_##name##List = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(std::move(name##List)); \
|
||||
} while (0);
|
||||
|
||||
#define INITIALIZE_BINDABLE_ENUM_SETTING_REVERSE_ORDER(name, enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List; \
|
||||
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \
|
||||
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::##enumMappingsName(); \
|
||||
for (auto [key, value] : enumMapping##name) \
|
||||
{ \
|
||||
auto enumName = LocalizedNameForEnumName(resourceSectionAndType, key, resourceProperty); \
|
||||
auto entry = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::EnumEntry>(enumName, winrt::box_value<enumType>(value)); \
|
||||
name##List.emplace_back(entry); \
|
||||
_##name##Map.Insert(value, entry); \
|
||||
} \
|
||||
std::sort(begin(name##List), end(name##List), EnumEntryReverseComparator<enumType>()); \
|
||||
_##name##List = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(std::move(name##List));
|
||||
#define INITIALIZE_BINDABLE_ENUM_SETTING_REVERSE_ORDER(name, enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
|
||||
do \
|
||||
{ \
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List; \
|
||||
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \
|
||||
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::enumMappingsName(); \
|
||||
for (auto [key, value] : enumMapping##name) \
|
||||
{ \
|
||||
auto enumName = LocalizedNameForEnumName(resourceSectionAndType, key, resourceProperty); \
|
||||
auto entry = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::EnumEntry>(enumName, winrt::box_value<enumType>(value)); \
|
||||
name##List.emplace_back(entry); \
|
||||
_##name##Map.Insert(value, entry); \
|
||||
} \
|
||||
std::sort(name##List.begin(), name##List.end(), EnumEntryReverseComparator<enumType>()); \
|
||||
_##name##List = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(std::move(name##List)); \
|
||||
} while (0);
|
||||
|
||||
// This macro must be used alongside INITIALIZE_BINDABLE_ENUM_SETTING.
|
||||
// It declares the needed data structures, getters, and setters to make
|
||||
|
@ -45,29 +51,29 @@
|
|||
// of EnumEntries so that we may display all possible values of the given
|
||||
// enum type and its localized names. It also provides a getter and setter
|
||||
// for the setting we wish to bind to.
|
||||
#define GETSET_BINDABLE_ENUM_SETTING(name, enumType, settingsModelName, settingNameInModel) \
|
||||
public: \
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>##name##List() \
|
||||
{ \
|
||||
return _##name##List; \
|
||||
} \
|
||||
\
|
||||
winrt::Windows::Foundation::IInspectable Current##name() \
|
||||
{ \
|
||||
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_##name##Map.Lookup(##settingsModelName().##settingNameInModel())); \
|
||||
} \
|
||||
\
|
||||
void Current##name(const winrt::Windows::Foundation::IInspectable& enumEntry) \
|
||||
{ \
|
||||
if (auto ee = enumEntry.try_as<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>()) \
|
||||
{ \
|
||||
auto setting = winrt::unbox_value<enumType>(ee.EnumValue()); \
|
||||
##settingsModelName().##settingNameInModel(setting); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _##name##List; \
|
||||
#define GETSET_BINDABLE_ENUM_SETTING(name, enumType, settingsModelName, settingNameInModel) \
|
||||
public: \
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List() \
|
||||
{ \
|
||||
return _##name##List; \
|
||||
} \
|
||||
\
|
||||
winrt::Windows::Foundation::IInspectable Current##name() \
|
||||
{ \
|
||||
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_##name##Map.Lookup(settingsModelName().settingNameInModel())); \
|
||||
} \
|
||||
\
|
||||
void Current##name(const winrt::Windows::Foundation::IInspectable& enumEntry) \
|
||||
{ \
|
||||
if (auto ee = enumEntry.try_as<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>()) \
|
||||
{ \
|
||||
auto setting = winrt::unbox_value<enumType>(ee.EnumValue()); \
|
||||
settingsModelName().settingNameInModel(setting); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _##name##List; \
|
||||
winrt::Windows::Foundation::Collections::IMap<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _##name##Map;
|
||||
|
||||
// This macro defines a dependency property for a WinRT class.
|
||||
|
@ -91,6 +97,42 @@ public: \
|
|||
private: \
|
||||
static winrt::Windows::UI::Xaml::DependencyProperty _##name##Property;
|
||||
|
||||
// Function Description:
|
||||
// - This function presents a File Open "common dialog" and returns its selected file asynchronously.
|
||||
// Parameters:
|
||||
// - customize: A lambda that receives an IFileDialog* to customize.
|
||||
// Return value:
|
||||
// (async) path to the selected item.
|
||||
template<typename TLambda>
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> OpenFilePicker(HWND parentHwnd, TLambda&& customize)
|
||||
{
|
||||
auto fileDialog{ winrt::create_instance<IFileDialog>(CLSID_FileOpenDialog) };
|
||||
DWORD flags{};
|
||||
THROW_IF_FAILED(fileDialog->GetOptions(&flags));
|
||||
THROW_IF_FAILED(fileDialog->SetOptions(flags | FOS_FORCEFILESYSTEM | FOS_NOCHANGEDIR | FOS_DONTADDTORECENT)); // filesystem objects only; no recent places
|
||||
customize(fileDialog.get());
|
||||
|
||||
auto hr{ fileDialog->Show(parentHwnd) };
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))
|
||||
{
|
||||
co_return winrt::hstring{};
|
||||
}
|
||||
THROW_HR(hr);
|
||||
}
|
||||
|
||||
winrt::com_ptr<IShellItem> result;
|
||||
THROW_IF_FAILED(fileDialog->GetResult(result.put()));
|
||||
|
||||
wil::unique_cotaskmem_string filePath;
|
||||
THROW_IF_FAILED(result->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
|
||||
|
||||
co_return winrt::hstring{ filePath.get() };
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> OpenImagePicker(HWND parentHwnd);
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings
|
||||
{
|
||||
winrt::hstring GetSelectedItemTag(winrt::Windows::Foundation::IInspectable const& comboBoxAsInspectable);
|
||||
|
|
|
@ -48,7 +48,7 @@ public: \
|
|||
if (name() != value) \
|
||||
{ \
|
||||
target.name(value); \
|
||||
_NotifyChanges(L"Has" #name, L#name); \
|
||||
_NotifyChanges(L"Has" #name, L## #name); \
|
||||
} \
|
||||
} \
|
||||
bool Has##name() { return target.Has##name(); }
|
||||
|
@ -63,7 +63,7 @@ public: \
|
|||
target.Clear##name(); \
|
||||
if (hadValue) \
|
||||
{ \
|
||||
_NotifyChanges(L"Has" #name, L#name); \
|
||||
_NotifyChanges(L"Has" #name, L## #name); \
|
||||
} \
|
||||
} \
|
||||
auto name##OverrideSource() { return target.name##OverrideSource(); }
|
||||
|
@ -84,7 +84,7 @@ public: \
|
|||
if (_##name != value) \
|
||||
{ \
|
||||
_##name = value; \
|
||||
_NotifyChanges(L#name); \
|
||||
_NotifyChanges(L## #name); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
|
|
|
@ -601,6 +601,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
winrt::hstring GlobalSummonArgs::GenerateName() const
|
||||
{
|
||||
// GH#10210 - Is this action literally the same thing as the `quakeMode`
|
||||
// action? That has a special name.
|
||||
static const auto quakeModeArgs{ std::get<0>(GlobalSummonArgs::QuakeModeFromJson(Json::Value::null)) };
|
||||
if (quakeModeArgs.Equals(*this))
|
||||
{
|
||||
return RS_(L"QuakeModeCommandKey");
|
||||
}
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << std::wstring_view(RS_(L"GlobalSummonCommandKey"));
|
||||
|
||||
|
|
|
@ -77,8 +77,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
void DeleteKeyBinding(Control::KeyChord const& keys);
|
||||
void RegisterKeyBinding(Control::KeyChord keys, Model::ActionAndArgs action);
|
||||
|
||||
static Windows::System::VirtualKeyModifiers ConvertVKModifiers(Control::KeyModifiers modifiers);
|
||||
|
||||
private:
|
||||
std::optional<Model::Command> _GetActionByID(const InternalActionID actionID) const;
|
||||
std::optional<Model::Command> _GetActionByKeyChordInternal(Control::KeyChord const& keys) const;
|
||||
|
|
|
@ -96,33 +96,4 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
return actionList;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Takes the KeyModifier flags from Terminal and maps them to the Windows WinRT types
|
||||
// Return Value:
|
||||
// - a Windows::System::VirtualKeyModifiers object with the flags of which modifiers used.
|
||||
Windows::System::VirtualKeyModifiers ActionMap::ConvertVKModifiers(KeyModifiers modifiers)
|
||||
{
|
||||
Windows::System::VirtualKeyModifiers keyModifiers = Windows::System::VirtualKeyModifiers::None;
|
||||
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Ctrl))
|
||||
{
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Control;
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Shift))
|
||||
{
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Shift;
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Alt))
|
||||
{
|
||||
// note: Menu is the Alt VK_MENU
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Menu;
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Windows))
|
||||
{
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Windows;
|
||||
}
|
||||
|
||||
return keyModifiers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::CreateNew
|
|||
// - source: the Profile object we are duplicating (must not be null)
|
||||
// Return Value:
|
||||
// - a reference to the new profile
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::DuplicateProfile(Model::Profile source)
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source)
|
||||
{
|
||||
THROW_HR_IF_NULL(E_INVALIDARG, source);
|
||||
|
||||
|
@ -289,25 +289,24 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::Duplicate
|
|||
}
|
||||
duplicated->Name(winrt::hstring(newName));
|
||||
|
||||
#define DUPLICATE_SETTING_MACRO(settingName) \
|
||||
if (source.Has##settingName() || \
|
||||
(source.##settingName##OverrideSource() != nullptr && source.##settingName##OverrideSource().Origin() != OriginTag::ProfilesDefaults)) \
|
||||
{ \
|
||||
duplicated->##settingName(source.##settingName()); \
|
||||
const auto isProfilesDefaultsOrigin = [](const auto& profile) -> bool {
|
||||
return profile && profile.Origin() != OriginTag::ProfilesDefaults;
|
||||
};
|
||||
|
||||
const auto isProfilesDefaultsOriginSub = [=](const auto& sub) -> bool {
|
||||
return sub && isProfilesDefaultsOrigin(sub.SourceProfile());
|
||||
};
|
||||
|
||||
#define DUPLICATE_SETTING_MACRO(settingName) \
|
||||
if (source.Has##settingName() || isProfilesDefaultsOrigin(source.settingName##OverrideSource())) \
|
||||
{ \
|
||||
duplicated->settingName(source.settingName()); \
|
||||
}
|
||||
|
||||
#define DUPLICATE_FONT_SETTING_MACRO(settingName) \
|
||||
if (source.FontInfo().Has##settingName() || \
|
||||
(source.FontInfo().##settingName##OverrideSource() != nullptr && source.FontInfo().##settingName##OverrideSource().SourceProfile().Origin() != OriginTag::ProfilesDefaults)) \
|
||||
{ \
|
||||
duplicated->FontInfo().##settingName(source.FontInfo().##settingName()); \
|
||||
}
|
||||
|
||||
#define DUPLICATE_APPEARANCE_SETTING_MACRO(settingName) \
|
||||
if (source.DefaultAppearance().Has##settingName() || \
|
||||
(source.DefaultAppearance().##settingName##OverrideSource() != nullptr && source.DefaultAppearance().##settingName##OverrideSource().SourceProfile().Origin() != OriginTag::ProfilesDefaults)) \
|
||||
{ \
|
||||
duplicated->DefaultAppearance().##settingName(source.DefaultAppearance().##settingName()); \
|
||||
#define DUPLICATE_SETTING_MACRO_SUB(source, target, settingName) \
|
||||
if (source.Has##settingName() || isProfilesDefaultsOriginSub(source.settingName##OverrideSource())) \
|
||||
{ \
|
||||
target.settingName(source.settingName()); \
|
||||
}
|
||||
|
||||
DUPLICATE_SETTING_MACRO(Hidden);
|
||||
|
@ -330,23 +329,31 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::Duplicate
|
|||
DUPLICATE_SETTING_MACRO(AltGrAliasing);
|
||||
DUPLICATE_SETTING_MACRO(BellStyle);
|
||||
|
||||
DUPLICATE_FONT_SETTING_MACRO(FontFace);
|
||||
DUPLICATE_FONT_SETTING_MACRO(FontSize);
|
||||
DUPLICATE_FONT_SETTING_MACRO(FontWeight);
|
||||
{
|
||||
const auto font = source.FontInfo();
|
||||
auto target = duplicated->FontInfo();
|
||||
DUPLICATE_SETTING_MACRO_SUB(font, target, FontFace);
|
||||
DUPLICATE_SETTING_MACRO_SUB(font, target, FontSize);
|
||||
DUPLICATE_SETTING_MACRO_SUB(font, target, FontWeight);
|
||||
}
|
||||
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(ColorSchemeName);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(Foreground);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(Background);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(SelectionBackground);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(CursorColor);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(PixelShaderPath);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(BackgroundImagePath);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(BackgroundImageOpacity);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(BackgroundImageStretchMode);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(BackgroundImageAlignment);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(RetroTerminalEffect);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(CursorShape);
|
||||
DUPLICATE_APPEARANCE_SETTING_MACRO(CursorHeight);
|
||||
{
|
||||
const auto appearance = source.DefaultAppearance();
|
||||
auto target = duplicated->DefaultAppearance();
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, ColorSchemeName);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, Foreground);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, Background);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, SelectionBackground);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, CursorColor);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, PixelShaderPath);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, BackgroundImagePath);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, BackgroundImageOpacity);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, BackgroundImageStretchMode);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, BackgroundImageAlignment);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, RetroTerminalEffect);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, CursorShape);
|
||||
DUPLICATE_SETTING_MACRO_SUB(appearance, target, CursorHeight);
|
||||
}
|
||||
|
||||
// UnfocusedAppearance is treated as a single setting,
|
||||
// but requires a little more legwork to duplicate properly
|
||||
|
|
|
@ -98,7 +98,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
winrt::guid GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const;
|
||||
|
||||
Model::Profile DuplicateProfile(Model::Profile source);
|
||||
Model::Profile DuplicateProfile(const Model::Profile& source);
|
||||
void RefreshDefaultTerminals();
|
||||
|
||||
static bool IsDefaultTerminalAvailable() noexcept;
|
||||
|
|
|
@ -530,14 +530,20 @@ void CascadiaSettings::_ParseAndLayerFragmentFiles(const std::unordered_set<std:
|
|||
auto matchingProfile = _FindMatchingProfile(profileStub);
|
||||
if (matchingProfile)
|
||||
{
|
||||
// We found a matching profile, create a child of it and put the modifications there
|
||||
// (we add a new inheritance layer)
|
||||
auto childImpl{ matchingProfile->CreateChild() };
|
||||
childImpl->LayerJson(profileStub);
|
||||
childImpl->Origin(OriginTag::Fragment);
|
||||
try
|
||||
{
|
||||
// We found a matching profile, create a child of it and put the modifications there
|
||||
// (we add a new inheritance layer)
|
||||
auto childImpl{ matchingProfile->CreateChild() };
|
||||
childImpl->LayerJson(profileStub);
|
||||
childImpl->Origin(OriginTag::Fragment);
|
||||
|
||||
// replace parent in _profiles with child
|
||||
_allProfiles.SetAt(_FindMatchingProfileIndex(matchingProfile->ToJson()).value(), *childImpl);
|
||||
// replace parent in _profiles with child
|
||||
_allProfiles.SetAt(_FindMatchingProfileIndex(matchingProfile->ToJson()).value(), *childImpl);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -546,13 +552,19 @@ void CascadiaSettings::_ParseAndLayerFragmentFiles(const std::unordered_set<std:
|
|||
// (it must have at least a name)
|
||||
if (profileStub.isMember(JsonKey(NameKey)))
|
||||
{
|
||||
auto newProfile = Profile::FromJson(profileStub);
|
||||
// Make sure to give the new profile a source, then we add it to our list of profiles
|
||||
// We don't make modifications to the user's settings file yet, that will happen when
|
||||
// _AppendDynamicProfilesToUserSettings() is called later
|
||||
newProfile->Source(source);
|
||||
newProfile->Origin(OriginTag::Fragment);
|
||||
_allProfiles.Append(*newProfile);
|
||||
try
|
||||
{
|
||||
auto newProfile = Profile::FromJson(profileStub);
|
||||
// Make sure to give the new profile a source, then we add it to our list of profiles
|
||||
// We don't make modifications to the user's settings file yet, that will happen when
|
||||
// _AppendDynamicProfilesToUserSettings() is called later
|
||||
newProfile->Source(source);
|
||||
newProfile->Origin(OriginTag::Fragment);
|
||||
_allProfiles.Append(*newProfile);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -850,6 +862,7 @@ void CascadiaSettings::LayerJson(const Json::Value& json)
|
|||
void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
|
||||
{
|
||||
// Layer the json on top of an existing profile, if we have one:
|
||||
winrt::com_ptr<implementation::Profile> profile{ nullptr };
|
||||
auto profileIndex{ _FindMatchingProfileIndex(profileJson) };
|
||||
if (profileIndex)
|
||||
{
|
||||
|
@ -862,6 +875,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
|
|||
// When we loaded Profile.Defaults, we created an empty child already.
|
||||
// So this just populates the empty child
|
||||
parent->LayerJson(profileJson);
|
||||
profile.copy_from(parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -871,6 +885,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
|
|||
|
||||
// replace parent in _profiles with child
|
||||
_allProfiles.SetAt(*profileIndex, *childImpl);
|
||||
profile = std::move(childImpl);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -880,7 +895,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
|
|||
// `source`. Dynamic profiles _must_ be layered on an existing profile.
|
||||
if (!Profile::IsDynamicProfileObject(profileJson))
|
||||
{
|
||||
auto profile{ winrt::make_self<Profile>() };
|
||||
profile = winrt::make_self<Profile>();
|
||||
|
||||
// GH#2325: If we have a set of default profile settings, set that as my parent.
|
||||
// We _won't_ have these settings yet for defaults, dynamic profiles.
|
||||
|
@ -893,6 +908,12 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
|
|||
_allProfiles.Append(*profile);
|
||||
}
|
||||
}
|
||||
|
||||
if (profile && _userDefaultProfileSettings)
|
||||
{
|
||||
// If we've loaded defaults{} we're in the "user settings" phase for sure
|
||||
profile->Origin(OriginTag::User);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -5,94 +5,75 @@
|
|||
#include "KeyChordSerialization.h"
|
||||
#include "KeyChordSerialization.g.cpp"
|
||||
|
||||
#include <til/static_map.h>
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace Microsoft::Terminal::Settings::Model::JsonUtils;
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
|
||||
static constexpr std::wstring_view CTRL_KEY{ L"ctrl" };
|
||||
static constexpr std::wstring_view SHIFT_KEY{ L"shift" };
|
||||
static constexpr std::wstring_view ALT_KEY{ L"alt" };
|
||||
static constexpr std::wstring_view WIN_KEY{ L"win" };
|
||||
constexpr std::wstring_view CTRL_KEY{ L"ctrl" };
|
||||
constexpr std::wstring_view SHIFT_KEY{ L"shift" };
|
||||
constexpr std::wstring_view ALT_KEY{ L"alt" };
|
||||
constexpr std::wstring_view WIN_KEY{ L"win" };
|
||||
|
||||
static constexpr int MAX_CHORD_PARTS = 5; // win+ctrl+alt+shift+key
|
||||
|
||||
// clang-format off
|
||||
static const std::unordered_map<std::wstring_view, int32_t> vkeyNamePairs {
|
||||
{ L"app" , VK_APPS },
|
||||
{ L"backspace" , VK_BACK },
|
||||
{ L"tab" , VK_TAB },
|
||||
{ L"enter" , VK_RETURN },
|
||||
{ L"esc" , VK_ESCAPE },
|
||||
{ L"escape" , VK_ESCAPE },
|
||||
{ L"menu" , VK_APPS },
|
||||
{ L"space" , VK_SPACE },
|
||||
{ L"pgup" , VK_PRIOR },
|
||||
{ L"pageup" , VK_PRIOR },
|
||||
{ L"pgdn" , VK_NEXT },
|
||||
{ L"pagedown" , VK_NEXT },
|
||||
{ L"end" , VK_END },
|
||||
{ L"home" , VK_HOME },
|
||||
{ L"left" , VK_LEFT },
|
||||
{ L"up" , VK_UP },
|
||||
{ L"right" , VK_RIGHT },
|
||||
{ L"down" , VK_DOWN },
|
||||
{ L"insert" , VK_INSERT },
|
||||
{ L"delete" , VK_DELETE },
|
||||
{ L"numpad_0" , VK_NUMPAD0 },
|
||||
{ L"numpad0" , VK_NUMPAD0 },
|
||||
{ L"numpad_1" , VK_NUMPAD1 },
|
||||
{ L"numpad1" , VK_NUMPAD1 },
|
||||
{ L"numpad_2" , VK_NUMPAD2 },
|
||||
{ L"numpad2" , VK_NUMPAD2 },
|
||||
{ L"numpad_3" , VK_NUMPAD3 },
|
||||
{ L"numpad3" , VK_NUMPAD3 },
|
||||
{ L"numpad_4" , VK_NUMPAD4 },
|
||||
{ L"numpad4" , VK_NUMPAD4 },
|
||||
{ L"numpad_5" , VK_NUMPAD5 },
|
||||
{ L"numpad5" , VK_NUMPAD5 },
|
||||
{ L"numpad_6" , VK_NUMPAD6 },
|
||||
{ L"numpad6" , VK_NUMPAD6 },
|
||||
{ L"numpad_7" , VK_NUMPAD7 },
|
||||
{ L"numpad7" , VK_NUMPAD7 },
|
||||
{ L"numpad_8" , VK_NUMPAD8 },
|
||||
{ L"numpad8" , VK_NUMPAD8 },
|
||||
{ L"numpad_9" , VK_NUMPAD9 },
|
||||
{ L"numpad9" , VK_NUMPAD9 },
|
||||
{ L"numpad_multiply" , VK_MULTIPLY },
|
||||
{ L"numpad_plus" , VK_ADD },
|
||||
{ L"numpad_add" , VK_ADD },
|
||||
{ L"numpad_minus" , VK_SUBTRACT },
|
||||
{ L"numpad_subtract" , VK_SUBTRACT },
|
||||
{ L"numpad_period" , VK_DECIMAL },
|
||||
{ L"numpad_decimal" , VK_DECIMAL },
|
||||
{ L"numpad_divide" , VK_DIVIDE },
|
||||
{ L"f1" , VK_F1 },
|
||||
{ L"f2" , VK_F2 },
|
||||
{ L"f3" , VK_F3 },
|
||||
{ L"f4" , VK_F4 },
|
||||
{ L"f5" , VK_F5 },
|
||||
{ L"f6" , VK_F6 },
|
||||
{ L"f7" , VK_F7 },
|
||||
{ L"f8" , VK_F8 },
|
||||
{ L"f9" , VK_F9 },
|
||||
{ L"f10" , VK_F10 },
|
||||
{ L"f11" , VK_F11 },
|
||||
{ L"f12" , VK_F12 },
|
||||
{ L"f13" , VK_F13 },
|
||||
{ L"f14" , VK_F14 },
|
||||
{ L"f15" , VK_F15 },
|
||||
{ L"f16" , VK_F16 },
|
||||
{ L"f17" , VK_F17 },
|
||||
{ L"f18" , VK_F18 },
|
||||
{ L"f19" , VK_F19 },
|
||||
{ L"f20" , VK_F20 },
|
||||
{ L"f21" , VK_F21 },
|
||||
{ L"f22" , VK_F22 },
|
||||
{ L"f23" , VK_F23 },
|
||||
{ L"f24" , VK_F24 },
|
||||
{ L"plus" , VK_OEM_PLUS }
|
||||
};
|
||||
// clang-format on
|
||||
#define VKEY_NAME_PAIRS(XX) \
|
||||
XX(VK_RETURN, L"enter") \
|
||||
XX(VK_TAB, L"tab") \
|
||||
XX(VK_SPACE, L"space") \
|
||||
XX(VK_BACK, L"backspace") \
|
||||
XX(VK_APPS, L"menu", L"app") \
|
||||
XX(VK_INSERT, L"insert") \
|
||||
XX(VK_DELETE, L"delete") \
|
||||
XX(VK_HOME, L"home") \
|
||||
XX(VK_END, L"end") \
|
||||
XX(VK_NEXT, L"pgdn", L"pagedown") \
|
||||
XX(VK_PRIOR, L"pgup", L"pageup") \
|
||||
XX(VK_ESCAPE, L"esc", L"escape") \
|
||||
XX(VK_LEFT, L"left") \
|
||||
XX(VK_RIGHT, L"right") \
|
||||
XX(VK_UP, L"up") \
|
||||
XX(VK_DOWN, L"down") \
|
||||
XX(VK_F1, L"f1") \
|
||||
XX(VK_F2, L"f2") \
|
||||
XX(VK_F3, L"f3") \
|
||||
XX(VK_F4, L"f4") \
|
||||
XX(VK_F5, L"f5") \
|
||||
XX(VK_F6, L"f6") \
|
||||
XX(VK_F7, L"f7") \
|
||||
XX(VK_F8, L"f8") \
|
||||
XX(VK_F9, L"f9") \
|
||||
XX(VK_F10, L"f10") \
|
||||
XX(VK_F11, L"f11") \
|
||||
XX(VK_F12, L"f12") \
|
||||
XX(VK_F13, L"f13") \
|
||||
XX(VK_F14, L"f14") \
|
||||
XX(VK_F15, L"f15") \
|
||||
XX(VK_F16, L"f16") \
|
||||
XX(VK_F17, L"f17") \
|
||||
XX(VK_F18, L"f18") \
|
||||
XX(VK_F19, L"f19") \
|
||||
XX(VK_F20, L"f20") \
|
||||
XX(VK_F21, L"f21") \
|
||||
XX(VK_F22, L"f22") \
|
||||
XX(VK_F23, L"f23") \
|
||||
XX(VK_F24, L"f24") \
|
||||
XX(VK_ADD, L"numpad_plus", L"numpad_add") \
|
||||
XX(VK_SUBTRACT, L"numpad_minus", L"numpad_subtract") \
|
||||
XX(VK_MULTIPLY, L"numpad_multiply") \
|
||||
XX(VK_DIVIDE, L"numpad_divide") \
|
||||
XX(VK_DECIMAL, L"numpad_period", L"numpad_decimal") \
|
||||
XX(VK_NUMPAD0, L"numpad0", L"numpad_0") \
|
||||
XX(VK_NUMPAD1, L"numpad1", L"numpad_1") \
|
||||
XX(VK_NUMPAD2, L"numpad2", L"numpad_2") \
|
||||
XX(VK_NUMPAD3, L"numpad3", L"numpad_3") \
|
||||
XX(VK_NUMPAD4, L"numpad4", L"numpad_4") \
|
||||
XX(VK_NUMPAD5, L"numpad5", L"numpad_5") \
|
||||
XX(VK_NUMPAD6, L"numpad6", L"numpad_6") \
|
||||
XX(VK_NUMPAD7, L"numpad7", L"numpad_7") \
|
||||
XX(VK_NUMPAD8, L"numpad8", L"numpad_8") \
|
||||
XX(VK_NUMPAD9, L"numpad9", L"numpad_9") \
|
||||
XX(VK_OEM_PLUS, L"plus")
|
||||
|
||||
// Function Description:
|
||||
// - Deserializes the given string into a new KeyChord instance. If this
|
||||
|
@ -105,108 +86,93 @@ static const std::unordered_map<std::wstring_view, int32_t> vkeyNamePairs {
|
|||
// - hstr: the string to parse into a keychord.
|
||||
// Return Value:
|
||||
// - a newly constructed KeyChord
|
||||
static KeyChord _fromString(const std::wstring_view& wstr)
|
||||
static KeyChord _fromString(std::wstring_view wstr)
|
||||
{
|
||||
// Split the string on '+'
|
||||
std::wstring temp;
|
||||
std::vector<std::wstring> parts;
|
||||
std::wstringstream wss;
|
||||
wss << wstr;
|
||||
using nameToVkeyPair = std::pair<std::wstring_view, int32_t>;
|
||||
static const til::static_map nameToVkey{
|
||||
// The above VKEY_NAME_PAIRS macro contains a list of key-binding names for each virtual key.
|
||||
// This god-awful macro inverts VKEY_NAME_PAIRS and creates a static map of key-binding names to virtual keys.
|
||||
// clang-format off
|
||||
#define GENERATOR_1(vkey, name1) nameToVkeyPair{ name1, vkey },
|
||||
#define GENERATOR_2(vkey, name1, name2) nameToVkeyPair{ name1, vkey }, nameToVkeyPair{ name2, vkey },
|
||||
#define GENERATOR_3(vkey, name1, name2, name3) nameToVkeyPair{ name1, vkey }, nameToVkeyPair{ name2, vkey }, nameToVkeyPair{ name3, vkey },
|
||||
#define GENERATOR_N(vkey, name1, name2, name3, MACRO, ...) MACRO
|
||||
#define GENERATOR(...) GENERATOR_N(__VA_ARGS__, GENERATOR_3, GENERATOR_2, GENERATOR_1)(__VA_ARGS__)
|
||||
VKEY_NAME_PAIRS(GENERATOR)
|
||||
#undef GENERATOR_1
|
||||
#undef GENERATOR_2
|
||||
#undef GENERATOR_3
|
||||
#undef GENERATOR_N
|
||||
#undef GENERATOR
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
while (std::getline(wss, temp, L'+'))
|
||||
{
|
||||
parts.push_back(temp);
|
||||
|
||||
// If we have > 4, something's wrong.
|
||||
if (parts.size() > MAX_CHORD_PARTS)
|
||||
{
|
||||
throw winrt::hresult_invalid_argument();
|
||||
}
|
||||
}
|
||||
|
||||
KeyModifiers modifiers = KeyModifiers::None;
|
||||
VirtualKeyModifiers modifiers = VirtualKeyModifiers::None;
|
||||
int32_t vkey = 0;
|
||||
|
||||
// Look for ctrl, shift, alt. Anything else might be a key
|
||||
for (const auto& part : parts)
|
||||
while (!wstr.empty())
|
||||
{
|
||||
std::wstring lowercase = part;
|
||||
std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(), std::towlower);
|
||||
if (lowercase == CTRL_KEY)
|
||||
const auto part = til::prefix_split(wstr, L"+");
|
||||
|
||||
if (til::equals_insensitive_ascii(part, CTRL_KEY))
|
||||
{
|
||||
modifiers |= KeyModifiers::Ctrl;
|
||||
modifiers |= VirtualKeyModifiers::Control;
|
||||
}
|
||||
else if (lowercase == ALT_KEY)
|
||||
else if (til::equals_insensitive_ascii(part, ALT_KEY))
|
||||
{
|
||||
modifiers |= KeyModifiers::Alt;
|
||||
modifiers |= VirtualKeyModifiers::Menu;
|
||||
}
|
||||
else if (lowercase == SHIFT_KEY)
|
||||
else if (til::equals_insensitive_ascii(part, SHIFT_KEY))
|
||||
{
|
||||
modifiers |= KeyModifiers::Shift;
|
||||
modifiers |= VirtualKeyModifiers::Shift;
|
||||
}
|
||||
else if (lowercase == WIN_KEY)
|
||||
else if (til::equals_insensitive_ascii(part, WIN_KEY))
|
||||
{
|
||||
modifiers |= KeyModifiers::Windows;
|
||||
modifiers |= VirtualKeyModifiers::Windows;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool foundKey = false;
|
||||
// For potential keys, look through the pairs of strings and vkeys
|
||||
if (vkey)
|
||||
{
|
||||
// Key bindings like Ctrl+A+B are not valid.
|
||||
throw winrt::hresult_invalid_argument();
|
||||
}
|
||||
|
||||
// Characters 0-9, a-z, A-Z directly map to virtual keys.
|
||||
if (part.size() == 1)
|
||||
{
|
||||
const wchar_t wch = part.at(0);
|
||||
// Quick lookup: ranges of vkeys that correlate directly to a key.
|
||||
if (wch >= L'0' && wch <= L'9')
|
||||
const auto wch = til::toupper_ascii(part[0]);
|
||||
if ((wch >= L'0' && wch <= L'9') || (wch >= L'A' && wch <= L'Z'))
|
||||
{
|
||||
vkey = static_cast<int32_t>(wch);
|
||||
foundKey = true;
|
||||
}
|
||||
else if (wch >= L'a' && wch <= L'z')
|
||||
{
|
||||
// subtract 0x20 to shift to uppercase
|
||||
vkey = static_cast<int32_t>(wch - 0x20);
|
||||
foundKey = true;
|
||||
}
|
||||
else if (wch >= L'A' && wch <= L'Z')
|
||||
{
|
||||
vkey = static_cast<int32_t>(wch);
|
||||
foundKey = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find the key with a quick lookup, search the
|
||||
// table to see if we have a matching name.
|
||||
if (!foundKey && vkeyNamePairs.find(part) != vkeyNamePairs.end())
|
||||
// nameToVkey contains a few more mappings like "F11".
|
||||
if (const auto it = nameToVkey.find(part); it != nameToVkey.end())
|
||||
{
|
||||
vkey = vkeyNamePairs.at(part);
|
||||
foundKey = true;
|
||||
break;
|
||||
vkey = it->second;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we haven't found a key, attempt a keyboard mapping
|
||||
if (!foundKey && part.size() == 1)
|
||||
if (part.size() == 1)
|
||||
{
|
||||
auto oemVk = VkKeyScanW(part[0]);
|
||||
const auto oemVk = VkKeyScanW(part[0]);
|
||||
if (oemVk != -1)
|
||||
{
|
||||
vkey = oemVk & 0xFF;
|
||||
auto oemModifiers = (oemVk & 0xFF00) >> 8;
|
||||
// We're using WI_SetFlagIf instead of WI_UpdateFlag because we want to be strictly additive
|
||||
// to the user's specified modifiers. ctrl+| should be the same as ctrl+shift+\,
|
||||
// but if we used WI_UpdateFlag, ctrl+shift+\ would turn _off_ Shift because \ doesn't
|
||||
// require it.
|
||||
WI_SetFlagIf(modifiers, KeyModifiers::Shift, WI_IsFlagSet(oemModifiers, 1U));
|
||||
WI_SetFlagIf(modifiers, KeyModifiers::Ctrl, WI_IsFlagSet(oemModifiers, 2U));
|
||||
WI_SetFlagIf(modifiers, KeyModifiers::Alt, WI_IsFlagSet(oemModifiers, 4U));
|
||||
foundKey = true;
|
||||
vkey = oemVk & 0xff;
|
||||
const auto oemModifiers = oemVk >> 8;
|
||||
// NOTE: WI_UpdateFlag _replaces_ a bit. This code _adds_ a bit.
|
||||
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Shift, WI_IsFlagSet(oemModifiers, 1U));
|
||||
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Control, WI_IsFlagSet(oemModifiers, 2U));
|
||||
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Menu, WI_IsFlagSet(oemModifiers, 4U));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we weren't able to find a match, throw an exception.
|
||||
if (!foundKey)
|
||||
{
|
||||
throw winrt::hresult_invalid_argument();
|
||||
}
|
||||
throw winrt::hresult_invalid_argument();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,82 +188,67 @@ static KeyChord _fromString(const std::wstring_view& wstr)
|
|||
// - a string which is an equivalent serialization of this object.
|
||||
static std::wstring _toString(const KeyChord& chord)
|
||||
{
|
||||
using vkeyToNamePair = std::pair<int32_t, std::wstring_view>;
|
||||
static const til::static_map vkeyToName{
|
||||
// The above VKEY_NAME_PAIRS macro contains a list of key-binding strings for each virtual key.
|
||||
// This macro picks the first (most preferred) name and creates a static map of virtual keys to key-binding names.
|
||||
#define GENERATOR(vkey, name1, ...) vkeyToNamePair{ vkey, name1 },
|
||||
VKEY_NAME_PAIRS(GENERATOR)
|
||||
#undef GENERATOR
|
||||
};
|
||||
|
||||
if (!chord)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool serializedSuccessfully = false;
|
||||
const auto modifiers = chord.Modifiers();
|
||||
const auto vkey = chord.Vkey();
|
||||
|
||||
std::wstring buffer{ L"" };
|
||||
std::wstring buffer;
|
||||
|
||||
// Add modifiers
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Windows))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Windows))
|
||||
{
|
||||
buffer += WIN_KEY;
|
||||
buffer += L"+";
|
||||
buffer.append(WIN_KEY);
|
||||
buffer.push_back(L'+');
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Ctrl))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Control))
|
||||
{
|
||||
buffer += CTRL_KEY;
|
||||
buffer += L"+";
|
||||
buffer.append(CTRL_KEY);
|
||||
buffer.push_back(L'+');
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Alt))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Menu))
|
||||
{
|
||||
buffer += ALT_KEY;
|
||||
buffer += L"+";
|
||||
buffer.append(ALT_KEY);
|
||||
buffer.push_back(L'+');
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, KeyModifiers::Shift))
|
||||
if (WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift))
|
||||
{
|
||||
buffer += SHIFT_KEY;
|
||||
buffer += L"+";
|
||||
buffer.append(SHIFT_KEY);
|
||||
buffer.push_back(L'+');
|
||||
}
|
||||
|
||||
// Quick lookup: ranges of vkeys that correlate directly to a key.
|
||||
if (vkey >= L'0' && vkey <= L'9')
|
||||
if ((vkey >= L'0' && vkey <= L'9') || (vkey >= L'A' && vkey <= L'Z'))
|
||||
{
|
||||
buffer += std::wstring(1, static_cast<wchar_t>(vkey));
|
||||
serializedSuccessfully = true;
|
||||
}
|
||||
else if (vkey >= L'A' && vkey <= L'Z')
|
||||
{
|
||||
// add 0x20 to shift to lowercase
|
||||
buffer += std::wstring(1, static_cast<wchar_t>(vkey + 0x20));
|
||||
serializedSuccessfully = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool foundKey = false;
|
||||
for (const auto& pair : vkeyNamePairs)
|
||||
{
|
||||
if (pair.second == vkey)
|
||||
{
|
||||
buffer += pair.first;
|
||||
serializedSuccessfully = true;
|
||||
foundKey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundKey)
|
||||
{
|
||||
auto mappedChar = MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR);
|
||||
if (mappedChar != 0)
|
||||
{
|
||||
wchar_t mappedWch = gsl::narrow_cast<wchar_t>(mappedChar);
|
||||
buffer += std::wstring_view{ &mappedWch, 1 };
|
||||
serializedSuccessfully = true;
|
||||
}
|
||||
}
|
||||
buffer.push_back(til::tolower_ascii(gsl::narrow_cast<wchar_t>(vkey)));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
if (!serializedSuccessfully)
|
||||
if (const auto it = vkeyToName.find(vkey); it != vkeyToName.end())
|
||||
{
|
||||
buffer = L"";
|
||||
buffer.append(it->second);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
const auto mappedChar = MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR);
|
||||
if (mappedChar != 0)
|
||||
{
|
||||
buffer.push_back(gsl::narrow_cast<wchar_t>(mappedChar));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
KeyChord KeyChordSerialization::FromString(const winrt::hstring& hstr)
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DefaultTerminal.h" >
|
||||
<DependentUpon>DefaultTerminal.idl</DependentUpon>
|
||||
<ClInclude Include="DefaultTerminal.h">
|
||||
<DependentUpon>DefaultTerminal.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IconPathConverter.h">
|
||||
<DependentUpon>IconPathConverter.idl</DependentUpon>
|
||||
|
@ -82,8 +82,8 @@
|
|||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DefaultTerminal.cpp">
|
||||
<DependentUpon>DefaultTerminal.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<DependentUpon>DefaultTerminal.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IconPathConverter.cpp">
|
||||
<DependentUpon>IconPathConverter.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
<ClCompile Include="WslDistroGenerator.cpp">
|
||||
<Filter>profileGeneration</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyMappingSerialization.cpp" />
|
||||
<ClCompile Include="CascadiaSettings.cpp" />
|
||||
<ClCompile Include="CascadiaSettingsSerialization.cpp" />
|
||||
<ClCompile Include="GlobalAppSettings.cpp" />
|
||||
|
@ -34,6 +33,7 @@
|
|||
<ClCompile Include="init.cpp" />
|
||||
<ClCompile Include="IconPathConverter.cpp" />
|
||||
<ClCompile Include="DefaultTerminal.cpp" />
|
||||
<ClCompile Include="FileUtils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
|
@ -66,6 +66,8 @@
|
|||
<ClInclude Include="IInheritable.h" />
|
||||
<ClInclude Include="IconPathConverter.h" />
|
||||
<ClInclude Include="DefaultTerminal.h" />
|
||||
<ClInclude Include="FileUtils.h" />
|
||||
<ClInclude Include="HashUtils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="ActionArgs.idl" />
|
||||
|
@ -84,6 +86,7 @@
|
|||
<Midl Include="IAppearanceConfig.idl" />
|
||||
<Midl Include="FontConfig.idl" />
|
||||
<Midl Include="DefaultTerminal.idl" />
|
||||
<Midl Include="ApplicationState.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
@ -59,6 +59,27 @@ Profile::Profile(guid guid) :
|
|||
{
|
||||
}
|
||||
|
||||
void Profile::CreateUnfocusedAppearance()
|
||||
{
|
||||
if (!_UnfocusedAppearance)
|
||||
{
|
||||
auto unfocusedAppearance{ winrt::make_self<implementation::AppearanceConfig>(weak_ref<Model::Profile>(*this)) };
|
||||
|
||||
// If an unfocused appearance is defined in this profile, any undefined parameters are
|
||||
// taken from this profile's default appearance, so add it as a parent
|
||||
com_ptr<AppearanceConfig> parentCom;
|
||||
parentCom.copy_from(winrt::get_self<implementation::AppearanceConfig>(_DefaultAppearance));
|
||||
unfocusedAppearance->InsertParent(parentCom);
|
||||
|
||||
_UnfocusedAppearance = *unfocusedAppearance;
|
||||
}
|
||||
}
|
||||
|
||||
void Profile::DeleteUnfocusedAppearance()
|
||||
{
|
||||
_UnfocusedAppearance = std::nullopt;
|
||||
}
|
||||
|
||||
winrt::com_ptr<Profile> Profile::CopySettings(winrt::com_ptr<Profile> source)
|
||||
{
|
||||
auto profile{ winrt::make_self<Profile>() };
|
||||
|
|
|
@ -79,6 +79,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
Profile();
|
||||
Profile(guid guid);
|
||||
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
hstring ToString()
|
||||
{
|
||||
return Name();
|
||||
|
@ -103,7 +106,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
void _FinalizeInheritance() override;
|
||||
|
||||
WINRT_PROPERTY(OriginTag, Origin, OriginTag::Custom);
|
||||
WINRT_PROPERTY(OriginTag, Origin, OriginTag::None);
|
||||
|
||||
INHERITABLE_SETTING(Model::Profile, guid, Guid, _GenerateGuidForProfile(Name(), Source()));
|
||||
INHERITABLE_SETTING(Model::Profile, hstring, Name, L"Default");
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
// This tag is used to identify the context in which the Profile was created
|
||||
enum OriginTag
|
||||
{
|
||||
Custom = 0,
|
||||
None = 0,
|
||||
User,
|
||||
InBox,
|
||||
Generated,
|
||||
Fragment,
|
||||
|
@ -42,6 +43,9 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
Profile();
|
||||
Profile(Guid guid);
|
||||
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
OriginTag Origin { get; };
|
||||
|
||||
INHERITABLE_PROFILE_SETTING(String, Name);
|
||||
|
|
|
@ -62,14 +62,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
// Return Value:
|
||||
// - A TerminalSettingsCreateResult, which contains a pair of TerminalSettings objects,
|
||||
// one for when the terminal is focused and the other for when the terminal is unfocused
|
||||
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfileByID(const Model::CascadiaSettings& appSettings, winrt::guid profileGuid, const IKeyBindings& keybindings)
|
||||
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const IKeyBindings& keybindings)
|
||||
{
|
||||
auto settings{ winrt::make_self<TerminalSettings>() };
|
||||
settings->_KeyBindings = keybindings;
|
||||
|
||||
const auto profile = appSettings.FindProfile(profileGuid);
|
||||
THROW_HR_IF_NULL(E_INVALIDARG, profile);
|
||||
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
settings->_ApplyProfileSettings(profile);
|
||||
settings->_ApplyGlobalSettings(globals);
|
||||
|
@ -86,6 +83,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
return winrt::make<TerminalSettingsCreateResult>(*settings, child);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a TerminalSettingsCreateResult for the provided profile guid. We'll
|
||||
// use the guid to look up the profile that should be used to
|
||||
// create these TerminalSettings. Then, we'll apply settings contained in the
|
||||
// global and profile settings to the instance.
|
||||
// Arguments:
|
||||
// - appSettings: the set of settings being used to construct the new terminal
|
||||
// - profileGuid: the unique identifier (guid) of the profile
|
||||
// - keybindings: the keybinding handler
|
||||
// Return Value:
|
||||
// - A TerminalSettingsCreateResult, which contains a pair of TerminalSettings objects,
|
||||
// one for when the terminal is focused and the other for when the terminal is unfocused
|
||||
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfileByID(const Model::CascadiaSettings& appSettings, winrt::guid profileGuid, const IKeyBindings& keybindings)
|
||||
{
|
||||
const auto profile = appSettings.FindProfile(profileGuid);
|
||||
THROW_HR_IF_NULL(E_INVALIDARG, profile);
|
||||
return CreateWithProfile(appSettings, profile, keybindings);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a TerminalSettings object for the provided newTerminalArgs. We'll
|
||||
// use the newTerminalArgs to look up the profile that should be used to
|
||||
|
|
|
@ -53,6 +53,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
{
|
||||
TerminalSettings() = default;
|
||||
|
||||
static Model::TerminalSettingsCreateResult CreateWithProfile(const Model::CascadiaSettings& appSettings,
|
||||
const Model::Profile& profile,
|
||||
const Control::IKeyBindings& keybindings);
|
||||
|
||||
static Model::TerminalSettingsCreateResult CreateWithProfileByID(const Model::CascadiaSettings& appSettings,
|
||||
guid profileGuid,
|
||||
const Control::IKeyBindings& keybindings);
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
{
|
||||
TerminalSettings();
|
||||
|
||||
static TerminalSettingsCreateResult CreateWithProfile(CascadiaSettings appSettings, Profile profile, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
static TerminalSettingsCreateResult CreateWithProfileByID(CascadiaSettings appSettings, Guid profileGuid, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(CascadiaSettings appSettings, NewTerminalArgs newTerminalArgs, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
static TerminalSettingsCreateResult CreateWithParent(TerminalSettingsCreateResult parent);
|
||||
|
|
|
@ -16,24 +16,6 @@ using namespace WEX::Common;
|
|||
using namespace winrt;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
|
||||
// These are some gross macros that let us call a private ctor for
|
||||
// Monarch/Peasant. We can't just use make_self, because that doesn't let us
|
||||
// call a private ctor. We can use com_ptr::attach, but since we're allocating
|
||||
// the thing on the stack, we need to make sure to call detach before the object
|
||||
// is destructed.
|
||||
|
||||
#define MAKE_MONARCH(name, pid) \
|
||||
Remoting::implementation::Monarch _local_##name##{ pid }; \
|
||||
com_ptr<Remoting::implementation::Monarch> name; \
|
||||
name.attach(&_local_##name##); \
|
||||
auto cleanup_##name## = wil::scope_exit([&]() { name.detach(); });
|
||||
|
||||
#define MAKE_PEASANT(name, pid) \
|
||||
Remoting::implementation::Peasant _local_##name##{ pid }; \
|
||||
com_ptr<Remoting::implementation::Peasant> name; \
|
||||
name.attach(&_local_##name##); \
|
||||
auto cleanup_##name## = wil::scope_exit([&]() { name.detach(); });
|
||||
|
||||
namespace RemotingUnitTests
|
||||
{
|
||||
struct MockDesktopManager : implements<MockDesktopManager, IVirtualDesktopManager>
|
||||
|
@ -161,6 +143,15 @@ namespace RemotingUnitTests
|
|||
|
||||
static void _findTargetWindowByNameHelper(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
|
||||
|
||||
// This template that lets us call a private ctor for Monarch/Peasant, unlike make_self.
|
||||
// Currently I use a private implementation detail of winrt::make_self,
|
||||
// which is bad, but I didn't want to deal with the alternatives.
|
||||
template<typename T, typename... Args>
|
||||
static winrt::com_ptr<T> make_private(Args&&... args)
|
||||
{
|
||||
return { new winrt::impl::heap_implements<T>(std::forward<Args>(args)...), winrt::take_ownership_from_abi };
|
||||
}
|
||||
};
|
||||
|
||||
// Helper to replace the specified peasant in a monarch with a
|
||||
|
@ -174,9 +165,7 @@ namespace RemotingUnitTests
|
|||
return;
|
||||
}
|
||||
|
||||
com_ptr<DeadPeasant> tombstone;
|
||||
tombstone.attach(new DeadPeasant());
|
||||
m->_peasants[peasantID] = *tombstone;
|
||||
m->_peasants[peasantID] = winrt::make<DeadPeasant>();
|
||||
}
|
||||
|
||||
// Helper to get the first argument out of the commandline, and try to
|
||||
|
@ -207,8 +196,7 @@ namespace RemotingUnitTests
|
|||
|
||||
void RemotingTests::CreateMonarch()
|
||||
{
|
||||
auto m1 = winrt::make_self<Remoting::implementation::Monarch>();
|
||||
VERIFY_IS_NOT_NULL(m1);
|
||||
auto m1 = make_private<Remoting::implementation::Monarch>();
|
||||
VERIFY_ARE_EQUAL(GetCurrentProcessId(),
|
||||
m1->GetPID(),
|
||||
L"A Monarch without an explicit PID should use the current PID");
|
||||
|
@ -216,9 +204,7 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"That's what we need for window process management, but for tests, it'll be more useful to fake the PIDs.");
|
||||
|
||||
auto expectedFakePID = 1234u;
|
||||
MAKE_MONARCH(m2, expectedFakePID);
|
||||
|
||||
VERIFY_IS_NOT_NULL(m2);
|
||||
auto m2 = make_private<Remoting::implementation::Monarch>(expectedFakePID);
|
||||
VERIFY_ARE_EQUAL(expectedFakePID,
|
||||
m2->GetPID(),
|
||||
L"A Monarch with an explicit PID should use the one we provided");
|
||||
|
@ -226,8 +212,7 @@ namespace RemotingUnitTests
|
|||
|
||||
void RemotingTests::CreatePeasant()
|
||||
{
|
||||
auto p1 = winrt::make_self<Remoting::implementation::Peasant>();
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>();
|
||||
VERIFY_ARE_EQUAL(GetCurrentProcessId(),
|
||||
p1->GetPID(),
|
||||
L"A Peasant without an explicit PID should use the current PID");
|
||||
|
@ -235,9 +220,7 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"That's what we need for window process management, but for tests, it'll be more useful to fake the PIDs.");
|
||||
|
||||
auto expectedFakePID = 2345u;
|
||||
MAKE_PEASANT(p2, expectedFakePID);
|
||||
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Monarch>(expectedFakePID);
|
||||
VERIFY_ARE_EQUAL(expectedFakePID,
|
||||
p2->GetPID(),
|
||||
L"A Peasant with an explicit PID should use the one we provided");
|
||||
|
@ -247,19 +230,14 @@ namespace RemotingUnitTests
|
|||
{
|
||||
Log::Comment(L"The same thing as the above test, but with `new` instead of insanity on the stack");
|
||||
|
||||
auto p1 = winrt::make_self<Remoting::implementation::Peasant>();
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>();
|
||||
VERIFY_ARE_EQUAL(GetCurrentProcessId(),
|
||||
p1->GetPID(),
|
||||
L"A Peasant without an explicit PID should use the current PID");
|
||||
|
||||
auto expectedFakePID = 2345u;
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
VERIFY_IS_NULL(p2);
|
||||
p2.attach(new Remoting::implementation::Peasant(expectedFakePID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(expectedFakePID);
|
||||
VERIFY_ARE_EQUAL(expectedFakePID,
|
||||
p2->GetPID(),
|
||||
L"A Peasant with an explicit PID should use the one we provided");
|
||||
|
@ -271,18 +249,9 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||
|
@ -300,18 +269,9 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||
|
@ -323,11 +283,9 @@ namespace RemotingUnitTests
|
|||
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||
|
||||
auto maybeP1 = m0->_getPeasant(1);
|
||||
VERIFY_IS_NOT_NULL(maybeP1);
|
||||
VERIFY_ARE_EQUAL(peasant1PID, maybeP1.GetPID());
|
||||
|
||||
auto maybeP2 = m0->_getPeasant(2);
|
||||
VERIFY_IS_NOT_NULL(maybeP2);
|
||||
VERIFY_ARE_EQUAL(peasant2PID, maybeP2.GetPID());
|
||||
}
|
||||
|
||||
|
@ -338,22 +296,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant2PID = 34567u;
|
||||
const auto monarch3PID = 45678u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m3;
|
||||
m3.attach(new Remoting::implementation::Monarch(monarch3PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
VERIFY_IS_NOT_NULL(m3);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
auto m3 = make_private<Remoting::implementation::Monarch>(monarch3PID);
|
||||
|
||||
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||
|
@ -377,18 +323,9 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||
|
@ -405,7 +342,6 @@ namespace RemotingUnitTests
|
|||
RemotingTests::_killPeasant(m0, p1->GetID());
|
||||
|
||||
auto maybeP2 = m0->_getPeasant(2);
|
||||
VERIFY_IS_NOT_NULL(maybeP2);
|
||||
VERIFY_ARE_EQUAL(peasant2PID, maybeP2.GetPID());
|
||||
|
||||
auto maybeP1 = m0->_getPeasant(1);
|
||||
|
@ -420,9 +356,7 @@ namespace RemotingUnitTests
|
|||
|
||||
const auto monarch0PID = 12345u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
std::vector<winrt::hstring> args{};
|
||||
|
@ -434,9 +368,7 @@ namespace RemotingUnitTests
|
|||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
Log::Comment(L"Propose the same args again after adding a peasant - we should still return {create new window, no ID}");
|
||||
|
@ -450,16 +382,12 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"Test proposing a commandline for a window that currently exists");
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
p1->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) {
|
||||
|
@ -480,16 +408,12 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"Test proposing a commandline for an invalid window ID, like -1");
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
{
|
||||
|
@ -514,16 +438,12 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"Test proposing a commandline for the current window (ID=0)");
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
p1->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) {
|
||||
Log::Comment(L"Commandline dispatched to p1");
|
||||
|
@ -552,9 +472,7 @@ namespace RemotingUnitTests
|
|||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
p2->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) {
|
||||
Log::Comment(L"Commandline dispatched to p2");
|
||||
|
@ -594,16 +512,12 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"Test proposing a commandline for an ID that doesn't have a current peasant");
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
{
|
||||
|
@ -631,16 +545,12 @@ namespace RemotingUnitTests
|
|||
Log::Comment(L"Test proposing a commandline for a peasant that previously died");
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
p1->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& /*cmdlineArgs*/) {
|
||||
Log::Comment(L"Commandline dispatched to p1");
|
||||
|
@ -649,9 +559,7 @@ namespace RemotingUnitTests
|
|||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
p2->ExecuteCommandlineRequested([&](auto&&, const Remoting::CommandlineArgs& cmdlineArgs) {
|
||||
Log::Comment(L"Commandline dispatched to p2");
|
||||
|
@ -702,23 +610,17 @@ namespace RemotingUnitTests
|
|||
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
|
||||
{
|
||||
|
@ -759,23 +661,17 @@ namespace RemotingUnitTests
|
|||
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
|
||||
{
|
||||
|
@ -798,9 +694,7 @@ namespace RemotingUnitTests
|
|||
|
||||
Log::Comment(L"Add a third peasant");
|
||||
const auto peasant3PID = 45678u;
|
||||
com_ptr<Remoting::implementation::Peasant> p3;
|
||||
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||
VERIFY_IS_NOT_NULL(p3);
|
||||
auto p3 = make_private<Remoting::implementation::Peasant>(peasant3PID);
|
||||
m0->AddPeasant(*p3);
|
||||
{
|
||||
Log::Comment(L"Activate the third peasant, first desktop");
|
||||
|
@ -836,23 +730,17 @@ namespace RemotingUnitTests
|
|||
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
|
||||
{
|
||||
|
@ -875,9 +763,7 @@ namespace RemotingUnitTests
|
|||
|
||||
Log::Comment(L"Add a third peasant");
|
||||
const auto peasant3PID = 45678u;
|
||||
com_ptr<Remoting::implementation::Peasant> p3;
|
||||
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||
VERIFY_IS_NOT_NULL(p3);
|
||||
auto p3 = make_private<Remoting::implementation::Peasant>(peasant3PID);
|
||||
m0->AddPeasant(*p3);
|
||||
{
|
||||
Log::Comment(L"Activate the third peasant, first desktop");
|
||||
|
@ -937,23 +823,17 @@ namespace RemotingUnitTests
|
|||
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
|
||||
{
|
||||
|
@ -974,9 +854,7 @@ namespace RemotingUnitTests
|
|||
|
||||
Log::Comment(L"Add a third peasant");
|
||||
const auto peasant3PID = 45678u;
|
||||
com_ptr<Remoting::implementation::Peasant> p3;
|
||||
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||
VERIFY_IS_NOT_NULL(p3);
|
||||
auto p3 = make_private<Remoting::implementation::Peasant>(peasant3PID);
|
||||
m0->AddPeasant(*p3);
|
||||
{
|
||||
Log::Comment(L"Activate the third peasant, first desktop");
|
||||
|
@ -1006,23 +884,17 @@ namespace RemotingUnitTests
|
|||
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||
|
||||
const auto monarch0PID = 12345u;
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowHelper);
|
||||
|
||||
Log::Comment(L"Add a peasant");
|
||||
const auto peasant1PID = 23456u;
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
m0->AddPeasant(*p1);
|
||||
|
||||
Log::Comment(L"Add a second peasant");
|
||||
const auto peasant2PID = 34567u;
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
m0->AddPeasant(*p2);
|
||||
|
||||
{
|
||||
|
@ -1066,18 +938,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"_quake");
|
||||
|
||||
|
@ -1165,18 +1029,9 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
@ -1214,22 +1069,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant2PID = 34567u;
|
||||
const auto monarch3PID = 45678u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m3;
|
||||
m3.attach(new Remoting::implementation::Monarch(monarch3PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
VERIFY_IS_NOT_NULL(m3);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
auto m3 = make_private<Remoting::implementation::Monarch>(monarch3PID);
|
||||
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
@ -1271,18 +1114,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1323,18 +1158,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1377,18 +1204,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1437,20 +1256,11 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
m0->FindTargetWindowRequested(&RemotingTests::_findTargetWindowByNameHelper);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1515,18 +1325,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1561,18 +1363,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1605,18 +1399,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1659,18 +1445,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1746,18 +1524,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1816,18 +1586,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1892,18 +1654,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
|
||||
|
@ -1992,22 +1746,11 @@ namespace RemotingUnitTests
|
|||
constexpr auto peasant2PID = 34567u;
|
||||
constexpr auto peasant3PID = 45678u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
auto p3 = make_private<Remoting::implementation::Peasant>(peasant3PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p3;
|
||||
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
VERIFY_IS_NOT_NULL(p3);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
p3->WindowName(L"three");
|
||||
|
@ -2069,8 +1812,7 @@ namespace RemotingUnitTests
|
|||
}
|
||||
|
||||
Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop");
|
||||
winrt::com_ptr<MockDesktopManager> manager;
|
||||
manager.attach(new MockDesktopManager());
|
||||
auto manager = winrt::make_self<MockDesktopManager>();
|
||||
m0->_desktopManager = manager.try_as<IVirtualDesktopManager>();
|
||||
|
||||
auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||
|
@ -2255,22 +1997,11 @@ namespace RemotingUnitTests
|
|||
constexpr auto peasant2PID = 34567u;
|
||||
constexpr auto peasant3PID = 45678u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
auto p3 = make_private<Remoting::implementation::Peasant>(peasant3PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p3;
|
||||
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
VERIFY_IS_NOT_NULL(p3);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
p3->WindowName(L"three");
|
||||
|
@ -2332,8 +2063,7 @@ namespace RemotingUnitTests
|
|||
}
|
||||
|
||||
Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop");
|
||||
winrt::com_ptr<MockDesktopManager> manager;
|
||||
manager.attach(new MockDesktopManager());
|
||||
auto manager = winrt::make_self<MockDesktopManager>();
|
||||
m0->_desktopManager = manager.try_as<IVirtualDesktopManager>();
|
||||
|
||||
auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||
|
@ -2408,22 +2138,11 @@ namespace RemotingUnitTests
|
|||
constexpr auto peasant2PID = 34567u;
|
||||
constexpr auto peasant3PID = 45678u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
auto p3 = make_private<Remoting::implementation::Peasant>(peasant3PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p3;
|
||||
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
VERIFY_IS_NOT_NULL(p3);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"two");
|
||||
p3->WindowName(L"three");
|
||||
|
@ -2485,8 +2204,7 @@ namespace RemotingUnitTests
|
|||
}
|
||||
|
||||
Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop");
|
||||
winrt::com_ptr<MockDesktopManager> manager;
|
||||
manager.attach(new MockDesktopManager());
|
||||
auto manager = winrt::make_self<MockDesktopManager>();
|
||||
m0->_desktopManager = manager.try_as<IVirtualDesktopManager>();
|
||||
|
||||
auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||
|
@ -2541,18 +2259,10 @@ namespace RemotingUnitTests
|
|||
const auto peasant1PID = 23456u;
|
||||
const auto peasant2PID = 34567u;
|
||||
|
||||
com_ptr<Remoting::implementation::Monarch> m0;
|
||||
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||
auto m0 = make_private<Remoting::implementation::Monarch>(monarch0PID);
|
||||
auto p1 = make_private<Remoting::implementation::Peasant>(peasant1PID);
|
||||
auto p2 = make_private<Remoting::implementation::Peasant>(peasant2PID);
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p1;
|
||||
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||
|
||||
com_ptr<Remoting::implementation::Peasant> p2;
|
||||
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||
|
||||
VERIFY_IS_NOT_NULL(m0);
|
||||
VERIFY_IS_NOT_NULL(p1);
|
||||
VERIFY_IS_NOT_NULL(p2);
|
||||
p1->WindowName(L"one");
|
||||
p2->WindowName(L"_quake");
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ using namespace WEX::Common;
|
|||
namespace TerminalCoreUnitTests
|
||||
{
|
||||
#define WCS(x) WCSHELPER(x)
|
||||
#define WCSHELPER(x) L#x
|
||||
#define WCSHELPER(x) L## #x
|
||||
|
||||
class ScreenSizeLimitsTest
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ using namespace WEX::TestExecution;
|
|||
namespace TerminalCoreUnitTests
|
||||
{
|
||||
#define WCS(x) WCSHELPER(x)
|
||||
#define WCSHELPER(x) L#x
|
||||
#define WCSHELPER(x) L## #x
|
||||
|
||||
class TerminalApiTest
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
|||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
|
||||
|
||||
#define XAML_HOSTING_WINDOW_CLASS_NAME L"CASCADIA_HOSTING_WINDOW_CLASS"
|
||||
|
||||
|
@ -1009,10 +1010,10 @@ void IslandWindow::SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal
|
|||
{
|
||||
const auto modifiers = hotkey.Modifiers();
|
||||
const auto hotkeyFlags = MOD_NOREPEAT |
|
||||
(WI_IsFlagSet(modifiers, KeyModifiers::Windows) ? MOD_WIN : 0) |
|
||||
(WI_IsFlagSet(modifiers, KeyModifiers::Alt) ? MOD_ALT : 0) |
|
||||
(WI_IsFlagSet(modifiers, KeyModifiers::Ctrl) ? MOD_CONTROL : 0) |
|
||||
(WI_IsFlagSet(modifiers, KeyModifiers::Shift) ? MOD_SHIFT : 0);
|
||||
(WI_IsFlagSet(modifiers, VirtualKeyModifiers::Windows) ? MOD_WIN : 0) |
|
||||
(WI_IsFlagSet(modifiers, VirtualKeyModifiers::Menu) ? MOD_ALT : 0) |
|
||||
(WI_IsFlagSet(modifiers, VirtualKeyModifiers::Control) ? MOD_CONTROL : 0) |
|
||||
(WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift) ? MOD_SHIFT : 0);
|
||||
|
||||
// TODO GH#8888: We should display a warning of some kind if this fails.
|
||||
// This can fail if something else already bound this hotkey.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}</ProjectGuid>
|
||||
|
@ -116,15 +116,15 @@
|
|||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets'))" />
|
||||
</Target>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.2" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.3.210521003" targetFramework="native" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
|
@ -88,15 +88,15 @@
|
|||
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.2" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
|
||||
</packages>
|
|
@ -54,10 +54,10 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="TE.Managed, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\TE.Managed.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\TE.Managed.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="TE.Model.Managed, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\TE.Model.Managed.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\TE.Model.Managed.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UIAutomationClient" />
|
||||
<Reference Include="UIAutomationTypes" />
|
||||
|
@ -68,10 +68,10 @@
|
|||
<HintPath>..\..\..\packages\Selenium.Support.3.5.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Wex.Common.Managed, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\Wex.Common.Managed.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\Wex.Common.Managed.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Wex.Logger.Interop, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\Wex.Logger.Interop.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\Wex.Logger.Interop.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
|
@ -122,11 +122,11 @@
|
|||
<PropertyGroup>
|
||||
<PostBuildEvent>copy $(SolutionDir)\dep\WinAppDriver\* $(OutDir)\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets" Condition="Exists('..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets" Condition="Exists('..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -5,5 +5,5 @@
|
|||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
|
||||
<package id="Selenium.Support" version="3.5.0" targetFramework="net45" />
|
||||
<package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" />
|
||||
<package id="Microsoft.Taef" version="10.58.210305002" targetFramework="net45" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="net45" />
|
||||
</packages>
|
|
@ -114,23 +114,23 @@ private: \
|
|||
// private _setName() method, that the class can internally use to change the
|
||||
// value when it _knows_ it doesn't need to raise the PropertyChanged event
|
||||
// (like when the class is being initialized).
|
||||
#define WINRT_OBSERVABLE_PROPERTY(type, name, event, ...) \
|
||||
public: \
|
||||
type name() const noexcept { return _##name; }; \
|
||||
void name(const type& value) \
|
||||
{ \
|
||||
if (_##name != value) \
|
||||
{ \
|
||||
_##name = value; \
|
||||
event(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L#name }); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
private: \
|
||||
type _##name{ __VA_ARGS__ }; \
|
||||
void _set##name(const type& value) \
|
||||
{ \
|
||||
const_cast<type&>(_##name) = value; \
|
||||
#define WINRT_OBSERVABLE_PROPERTY(type, name, event, ...) \
|
||||
public: \
|
||||
type name() const noexcept { return _##name; }; \
|
||||
void name(const type& value) \
|
||||
{ \
|
||||
if (_##name != value) \
|
||||
{ \
|
||||
_##name = value; \
|
||||
event(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L## #name }); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
private: \
|
||||
type _##name{ __VA_ARGS__ }; \
|
||||
void _set##name(const type& value) \
|
||||
{ \
|
||||
_##name = value; \
|
||||
};
|
||||
|
||||
// Use this macro for quickly defining the factory_implementation part of a
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<PreprocessorDefinitions>INLINE_TEST_METHOD_MARKUP;UNIT_TESTING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets" Condition="Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets')" />
|
||||
<Import Project="$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets" Condition="Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets'))" />
|
||||
<Error Condition="!Exists('$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -72,8 +72,10 @@
|
|||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
|
||||
<!-- All new code should be in non-permissive mode. Big objects for C++/WinRT. -->
|
||||
<AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /Zc:twoPhase-</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<UseStandardPreprocessor>true</UseStandardPreprocessor>
|
||||
<AdditionalOptions>%(AdditionalOptions) /bigobj /Zc:twoPhase-</AdditionalOptions>
|
||||
<DisableSpecificWarnings>5104;5105;28204;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
<alwaysDisabledReleaseTokens/>
|
||||
</feature>
|
||||
|
||||
<feature>
|
||||
<name>Feature_EditableUnfocusedAppearance</name>
|
||||
<description>The unfocused appearance section in profiles in the SUI that allows users to create and edit unfocused appearances.</description>
|
||||
<stage>AlwaysEnabled</stage>
|
||||
<alwaysDisabledReleaseTokens/>
|
||||
</feature>
|
||||
|
||||
<feature>
|
||||
<name>Feature_AttemptHandoff</name>
|
||||
<description>conhost should try to hand connections over to OpenConsole</description>
|
||||
|
@ -56,4 +63,13 @@
|
|||
<brandingToken>WindowsInbox</brandingToken>
|
||||
</alwaysEnabledBrandingTokens>
|
||||
</feature>
|
||||
|
||||
<feature>
|
||||
<name>Feature_ShowProfileDefaultsInSettings</name>
|
||||
<description>Whether to show the "defaults" page in the Terminal settings UI</description>
|
||||
<id>10430</id>
|
||||
<stage>AlwaysEnabled</stage>
|
||||
<!-- This feature will not ship to Stable until it is complete. -->
|
||||
<alwaysDisabledReleaseTokens />
|
||||
</feature>
|
||||
</featureStaging>
|
||||
|
|
|
@ -70,7 +70,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo)
|
|||
auto& buffer = ScreenInfo.GetTextBuffer();
|
||||
auto& cursor = buffer.GetCursor();
|
||||
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
auto* const _pAccessibilityNotifier = ServiceLocator::LocateAccessibilityNotifier();
|
||||
auto* const pAccessibilityNotifier = ServiceLocator::LocateAccessibilityNotifier();
|
||||
|
||||
if (!WI_IsFlagSet(gci.Flags, CONSOLE_HAS_FOCUS))
|
||||
{
|
||||
|
@ -78,7 +78,8 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo)
|
|||
}
|
||||
|
||||
// Update the cursor pos in USER so accessibility will work.
|
||||
if (cursor.HasMoved())
|
||||
// Don't do all this work or send events if we don't have a notifier target.
|
||||
if (pAccessibilityNotifier && cursor.HasMoved())
|
||||
{
|
||||
// Convert the buffer position to the equivalent screen coordinates
|
||||
// required by the notifier, taking line rendition into account.
|
||||
|
@ -93,7 +94,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo)
|
|||
rc.right = rc.left + fontSize.X;
|
||||
rc.bottom = rc.top + fontSize.Y;
|
||||
|
||||
_pAccessibilityNotifier->NotifyConsoleCaretEvent(rc);
|
||||
pAccessibilityNotifier->NotifyConsoleCaretEvent(rc);
|
||||
|
||||
// Send accessibility information
|
||||
{
|
||||
|
@ -109,7 +110,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo)
|
|||
flags = IAccessibilityNotifier::ConsoleCaretEventFlags::CaretVisible;
|
||||
}
|
||||
|
||||
_pAccessibilityNotifier->NotifyConsoleCaretEvent(flags, MAKELONG(position.X, position.Y));
|
||||
pAccessibilityNotifier->NotifyConsoleCaretEvent(flags, MAKELONG(position.X, position.Y));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,10 +224,13 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||
|
||||
cellsModified = done.GetCellDistance(it);
|
||||
|
||||
// Notify accessibility
|
||||
auto endingCoordinate = startingCoordinate;
|
||||
bufferSize.MoveInBounds(cellsModified, endingCoordinate);
|
||||
screenBuffer.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
||||
if (screenBuffer.HasAccessibilityEventing())
|
||||
{
|
||||
// Notify accessibility
|
||||
auto endingCoordinate = startingCoordinate;
|
||||
bufferSize.MoveInBounds(cellsModified, endingCoordinate);
|
||||
screenBuffer.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
||||
}
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
|
@ -284,9 +287,12 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||
cellsModified = done.GetInputDistance(it);
|
||||
|
||||
// Notify accessibility
|
||||
auto endingCoordinate = startingCoordinate;
|
||||
bufferSize.MoveInBounds(cellsModified, endingCoordinate);
|
||||
screenInfo.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
||||
if (screenInfo.HasAccessibilityEventing())
|
||||
{
|
||||
auto endingCoordinate = startingCoordinate;
|
||||
bufferSize.MoveInBounds(cellsModified, endingCoordinate);
|
||||
screenInfo.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
||||
}
|
||||
|
||||
// GH#3126 - This is a shim for powershell's `Clear-Host` function. In
|
||||
// the vintage console, `Clear-Host` is supposed to clear the entire
|
||||
|
|
|
@ -557,7 +557,10 @@ constexpr unsigned int LOCAL_BUFFER_SIZE = 100;
|
|||
const auto itEnd = screenInfo.Write(it);
|
||||
|
||||
// Notify accessibility
|
||||
screenInfo.NotifyAccessibilityEventing(CursorPosition.X, CursorPosition.Y, CursorPosition.X + gsl::narrow<SHORT>(i - 1), CursorPosition.Y);
|
||||
if (screenInfo.HasAccessibilityEventing())
|
||||
{
|
||||
screenInfo.NotifyAccessibilityEventing(CursorPosition.X, CursorPosition.Y, CursorPosition.X + gsl::narrow<SHORT>(i - 1), CursorPosition.Y);
|
||||
}
|
||||
|
||||
// The number of "spaces" or "cells" we have consumed needs to be reported and stored for later
|
||||
// when/if we need to erase the command line.
|
||||
|
|
|
@ -376,7 +376,10 @@ std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(con
|
|||
area.Paint();
|
||||
|
||||
// Notify accessibility that we have updated the text in this display region within the viewport.
|
||||
screenInfo.NotifyAccessibilityEventing(insertionPos.X, insertionPos.Y, gsl::narrow<SHORT>(insertionPos.X + lineVec.size() - 1), insertionPos.Y);
|
||||
if (screenInfo.HasAccessibilityEventing())
|
||||
{
|
||||
screenInfo.NotifyAccessibilityEventing(insertionPos.X, insertionPos.Y, gsl::narrow<SHORT>(insertionPos.X + lineVec.size() - 1), insertionPos.Y);
|
||||
}
|
||||
|
||||
// Hand back the iterator representing the end of what we used to be fed into the beginning of the next call.
|
||||
return lineEnd;
|
||||
|
|
|
@ -53,10 +53,10 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="TE.Managed, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\TE.Managed.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\TE.Managed.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="TE.Model.Managed, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\TE.Model.Managed.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\TE.Model.Managed.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UIAutomationClient" />
|
||||
<Reference Include="UIAutomationTypes" />
|
||||
|
@ -67,10 +67,10 @@
|
|||
<HintPath>..\..\..\packages\Selenium.Support.3.5.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Wex.Common.Managed, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\Wex.Common.Managed.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\Wex.Common.Managed.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Wex.Logger.Interop, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.58.210305002\lib\net45\Wex.Logger.Interop.dll</HintPath>
|
||||
<HintPath>..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\Wex.Logger.Interop.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
|
@ -145,11 +145,11 @@
|
|||
<PropertyGroup>
|
||||
<PostBuildEvent>copy $(SolutionDir)\dep\WinAppDriver\* $(OutDir)\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets" Condition="Exists('..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets" Condition="Exists('..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Taef.10.58.210305002\build\Microsoft.Taef.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Taef.10.60.210621002\build\Microsoft.Taef.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -5,5 +5,5 @@
|
|||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
|
||||
<package id="Selenium.Support" version="3.5.0" targetFramework="net45" />
|
||||
<package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" />
|
||||
<package id="Microsoft.Taef" version="10.58.210305002" targetFramework="net45" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="net45" />
|
||||
</packages>
|
|
@ -2210,10 +2210,14 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo)
|
|||
screenInfo.Write(fillData, startPosition, false);
|
||||
|
||||
// Notify accessibility
|
||||
auto endPosition = startPosition;
|
||||
const auto bufferSize = screenInfo.GetBufferSize();
|
||||
bufferSize.MoveInBounds(fillLength - 1, endPosition);
|
||||
screenInfo.NotifyAccessibilityEventing(startPosition.X, startPosition.Y, endPosition.X, endPosition.Y);
|
||||
if (screenInfo.HasAccessibilityEventing())
|
||||
{
|
||||
auto endPosition = startPosition;
|
||||
const auto bufferSize = screenInfo.GetBufferSize();
|
||||
bufferSize.MoveInBounds(fillLength - 1, endPosition);
|
||||
screenInfo.NotifyAccessibilityEventing(startPosition.X, startPosition.Y, endPosition.X, endPosition.Y);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
|
|
@ -344,7 +344,16 @@ bool ConhostInternalGetSet::PrivateShowCursor(const bool show) noexcept
|
|||
bool ConhostInternalGetSet::PrivateAllowCursorBlinking(const bool fEnable)
|
||||
{
|
||||
DoSrvPrivateAllowCursorBlinking(_io.GetActiveOutputBuffer(), fEnable);
|
||||
return true;
|
||||
|
||||
bool isPty;
|
||||
DoSrvIsConsolePty(isPty);
|
||||
// If we are connected to a pty, return that we could not handle this
|
||||
// so that the VT sequence gets flushed to terminal.
|
||||
// Note: we technically don't need to handle it ourselves at all if
|
||||
// we are connected to a pty (i.e. we could have just returned false
|
||||
// immediately without needing to call DoSrvPrivateAllowCursorBlinking),
|
||||
// but we call it anyway for consistency, just in case.
|
||||
return !isPty;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue