Compare commits

..

46 Commits

Author SHA1 Message Date
Mike Griese
f75166e87a chef kiss 2026-03-04 13:03:12 -06:00
Mike Griese
9e0ff8835f save when the workspace closes 2026-03-04 12:27:33 -06:00
Mike Griese
fd5ddfb4c0 some menu touch up 2026-03-04 08:29:11 -06:00
Mike Griese
d2fcfdc6b3 oh my fucking god 2026-03-03 16:51:34 -06:00
Mike Griese
34b3029fb1 tests 2026-03-03 12:48:50 -06:00
Mike Griese
45ddf94067 is that really everything? 2026-03-03 11:04:15 -06:00
Mike Griese
abb06e1918 todos 2026-03-03 06:10:34 -06:00
Mike Griese
eb2899e267 yea i guess 2026-03-02 14:23:16 -06:00
Dustin L. Howett
0a3fbdefb3 conpty: Make sure ConDrv is loaded before doing ConPTY things (#19901)
Fixes #4750
2026-02-24 21:48:00 +01:00
Dustin L. Howett
9f0cd70ae9 Reflect OS PR 14647503 (#19900)
Who knows why they do what they do?
2026-02-24 20:24:08 +01:00
PankajBhojwani
127775118d Check for command palette's visibility before responding to search text changes (#19885)
Only respond to any search changes in the command palette if the command
palette is visible. Without this check, a previewable action's preview
can appear after the command palette is closed.

## Validation Steps Performed
Preview no longer appears after the command palette is closed

## PR Checklist
Closes #18737
2026-02-24 18:34:57 +00:00
Windows Console Service Bot
343db95021 Localization Updates - main - 02/23/2026 (#19891)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2026-02-23 20:28:00 +00:00
Carlos Zamora
f20c549d15 Implement search in Settings UI (#19519)
## Summary of the Pull Request
Adds search functionality to the settings UI. This is added to an
`AutoSuggestBox` in the main `NavigationView`. Invoking a result
navigates to the proper location in the settings UI and focuses the
setting, when possible.

## References and Relevant Issues
Based on https://github.com/microsoft/PowerToys/pull/41285

## Detailed Description of the Pull Request / Additional comments
- tools/GenerateSettingsIndex.ps1: parses all the XAML files in the
settings UI for SettingsContainers and builds a search index from them
- XAML changes: ensures all SettingContainer objects have an `x:Name` so
that we can navigate to them and bring them into view.
- TerminalSettingsEditor/Utils.h: implements `BringIntoViewWhenLoaded()`
which navigates to the relevant part of the UI. This is called in
`OnNavigatedTo()` for each page.
- fzf was moved out of TerminalApp so that TerminalSettingsEditor can
access it
- There's a few main components to searching, all of it is in
`MainPage`:
- `MainPage::_UpdateSearchIndex()`|`SearchIndex::Reset()`: loads the
search index generated by `GenerateSettingsIndex.ps1`; provides
additional localization, if needed
   - `MainPage::SettingsSearchBox_TextChanged`:
      - detect that text changed in the search box
- perform the actual search in `SearchIndex::SearchAsync()`. This is a
HEFTY async function that can be cancelled. It needs a lot of context
passed in to expand the search index appropriately (i.e. build awareness
of "PowerShell" profile and generate results appropriately). This is
also where fzf is used to perform weighted matching.
- the weighted matching itself is pretty complicated, but all the
associated bonus weights are at the top of SearchIndex.cpp.
- `SettingsSearchBox_QuerySubmitted`: extract the search index metadata
and call the correct `_Navigate()` function

## Validation Steps Performed
Search for...
- settings that don't change at runtime:
   - [x] global settings
   - [x] settings in profile.defaults
   - [x] "add new profile" page
- settings that may change at runtime:
   - [x] settings in a profile
   - [x] individual color schemes
   - [x] actions (main actions page + edit action subpage)
   - [x] new tab menu folders
   - [x] extensions
- misc. corner cases:
- [x] terminal chat (blocked in indexing script; requires minor changes
in feature branch)
   - [x] settings in appearance objects

To test fzf matching and weighted results, I specifically tested these
scenarios:
- "PowerShell" --> prioritize the PowerShell profile page(s)
- "font size" --> prioritize profile defaults entry
- "font size powershell" --> prioritize PowerShell > font size

## PR Checklist
Closes #12949 

## Follow-ups
- search by JSON key: need a way to add JSON keys to index entries.
`GetSearchableFields()` should make the rest pretty easy.
- search by keywords: need to define keywords. `GetSearchableFields()`
should make the rest pretty easy.
2026-02-20 15:04:45 -08:00
Windows Console Service Bot
300bc2b513 Localization Updates - main - 02/20/2026 03:04:49 (#19863)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2026-02-19 21:48:46 -06:00
Carlos Zamora
b6375cc028 Fix pasting text via mouse when broadcast input is enabled (#19879)
## Summary of the Pull Request
Pretty straightforward. Does exactly what it says on the tin.

## Validation Steps Performed
Pasting works when broadcast input is enabled...
 paste w/ mouse
 paste w/ keyboard (untouched)

Closes #18821
2026-02-19 15:19:24 -08:00
Dustin L. Howett
67669a35c5 atlas: turn AtlasEngine on in WindowsInbox builds (#19888)
This pull request removes the feature flag blocking Atlas from being
built into conhost, and introduces a new one preventing Atlas from using
_custom shaders_ in conhost.

This prevents us from taking a new dependency on `d3dcompiler_47.dll`.

It also adds all the build rules necessary to link Atlas in properly.

It is worth noting that Atlas does not work in WinPE, because there's no
DXGI/D2D or anything of note.
2026-02-19 21:23:17 +00:00
Dustin L. Howett
e20e1f7bf9 Restore downlevel operation (#19876)
- `SetThreadpoolTimer` is equivalent in every way to
`SetThreadpoolTimerEx` for our use case (we throw away the return value)
- `SetThreadDescription` is optional
2026-02-17 14:14:24 -08:00
Leonard Hecker
c81c66b406 Implement the Kitty Keyboard Protocol (#19817)
This essentially rewrites `TerminalInput` from scratch.
There's significant overlap between what kind of information
the Kitty protocol needs from the OS and our existing code.
The rewrite allows us to share large parts of the implementation.

Closes #11509

## Validation Steps Performed
* `kitten show-key -m kitty` 
* US Intern. " + ' produces `\'` 
* Hebrew base keys produce Unicode 
* Hebrew AltGr combinations produce Unicode 
* French AltGr+Space produces U+00A0 
* German AltGr+Decimals produce []{}... 
2026-02-16 19:53:49 -06:00
PankajBhojwani
83b9569ce0 Show additional keybinding count if there are additional keybindings on the top-level Actions page (#19865)
On the top-level actions page, display an indicator if there are
additional keybindings other than the one displayed

Closes #19830
2026-02-13 17:58:41 -06:00
PankajBhojwani
830935d500 Update actions page and edit actions page with better alignment (#19822)
- Actions page: entries now stretch across the screen horizontally (to a
max of 1000) to be consistent with other settings pages
- Edit action page:
- `Keybindings` and `Additional arguments` are now top-aligned headers
- All arg templates now also stretch across the screen horizontally to
match how expanders look in the rest of the settings UI

## Validation Steps Performed
Everything still works. Screenshots below.
2026-02-13 14:52:49 -08:00
Dustin L. Howett
bc4e6129ef Disable the creation of issues without using a template (#19808)
We've seen an uptick in "language model" "people" submitting issues
without using the template. Easy fix.
2026-02-13 14:01:31 -06:00
Benedikt Johannes
d9d824a840 Fix stale weak pointer access (#19856)
Closes #19855
2026-02-13 19:15:17 +01:00
PankajBhojwani
c310e0280f When a new keybinding is added, focus the KeyChordListener (#19862) 2026-02-12 21:12:34 -06:00
PankajBhojwani
1f85191baf Use sentence case for actions' additional argument resource strings (#19861)
From the feedback received in #19822,
update the multi-word additional argument resource entries to use
sentence case.
2026-02-13 02:25:08 +00:00
Dustin L. Howett
ed5b59d248 render: stop calculating lineWrapped for PaintBufferLine (#19858)
This was a holdover from VtEngine. None of the existing renderers care.
2026-02-12 19:11:17 -06:00
PankajBhojwani
527b369de7 Allow searching through the available shortcut actions in the EditAction page (#19827)
Similar to the `FontFaceBox`, show all the available shortcut actions
when the user clicks the `ShortcutActionBox`, and filter the results
based on the user's search query
2026-02-12 19:09:14 -06:00
Benedikt Johannes
7798d2e958 Fix camelCase "isBrightColor" in TerminalPage.cpp (#19854)
Closes #19853
2026-02-11 22:02:55 +00:00
Benedikt Johannes
0c5ec71e62 Remove one of the double "using namespace" statements (#19852)
Remove one of the double "using namespace" statements

Closes #19851
2026-02-11 21:44:32 +00:00
Dustin L. Howett
497bb2f7d1 Fix tests which were failing in Windows (#19849)
We do not have good test coverage for the `WindowsInbox` build.

- ClipboardTest regressed with #19511
- DECRQCRA tests were not written for WindowsInbox
- FTCS marks tests were not written for WindowsInbox

After this PR:

Summary: Total=7182, Passed=7160, Failed=3, Blocked=0, Not Run=0,
Skipped=19

The 3 failing tests are in the integrity level FT, and they fail because
they expect to be run in an empty console window (the test reads buffer
output starting from 0, 0.)
2026-02-11 17:42:34 +00:00
Dustin L. Howett
c05cb107e5 chore: update vcpkg dependencies (#19838)
fmt 11.4 -> 12.1
cmark 0.30 -> 0.31
CLI11 2.4 -> 2.6

This commit retains the addition of `FMT_PEDANTIC` so that we remain
compliant with Microsoft's security requirements.
2026-02-11 10:18:02 -06:00
Dustin L. Howett
5f1ecb005a atlas: build with Windows Razzle; fix inbox build (#19848) 2026-02-11 08:45:44 -06:00
Windows Console Service Bot
692f06beb6 Localization Updates - main - 02/07/2026 03:09:25 (#19840)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2026-02-11 03:40:12 +00:00
Carlos Zamora
21754fabf2 Standardize use of NavigateToPageArgs in SUI (#19831)
Replaces usage of `NavigateToXArgs` in the `TerminalSettingsEditor` with
`NavigateToPageArgs`. They all did pretty much the same thing anyways.

Refs #19826
Refs #19519
2026-02-10 20:31:19 +00:00
Dustin L. Howett
8e4642dc13 vcpkg: move to jsoncpp 1.9.6, import an upstream whitespace patch (#19836)
The maintainers of jsoncpp chose to decline
open-source-parsers/jsoncpp#1154 until they make a new major release.
We are not burdened by that requirement.

Closes #10887
Refs #19834
2026-02-09 14:41:26 -06:00
Windows Console Service Bot
3e912e78a7 Localization Updates - main - 02/04/2026 03:20:35 (#19828)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2026-02-06 15:55:12 -06:00
Ivan Pešić
61f86e1116 Update the Serbian localization (#19833) 2026-02-06 12:06:57 -06:00
Carlos Zamora
27aae1f245 Fix WindowRoot memory leak in SUI (#19826)
## Summary of the Pull Request
Fixes a memory leak for `IHostedInWindow` in the TerminalSettingsEditor.

The memory leak occurs from `MainPage` creating an object that stores
reference to back to `MainPage` as `IHostedInWindow`. With `IconPicker`
specifically, the cycle would look like `MainPage` --> `NewTabMenu` -->
`IconPicker` --> `MainPage`.

I've audited uses of `IHostedInWindow` in the TerminalSettingsEditor and
replaced them as weak references. I also checked areas that
`WindowRoot()` was called and added a null-check for safety.

## Validation Steps Performed
Verified `MainPage` and `NewTabMenu` dtors are called when the settings
UI closes from...
 Launch page (base case - it doesn't have an `IHostedInWindow`)
 New Tab Menu page
2026-02-03 14:25:25 -08:00
Dustin L. Howett
89d82638ab Use the version of clang-format that comes with Visual Studio (#19821)
This pull request also (necessarily) reformats the code to match the
current version.

Visual Studio 2022 17.14 comes with Clang 19's `clang-format`.
2026-02-02 13:45:11 -06:00
Carlos Zamora
a449899789 Add IconPicker to New Tab Menu folders in SUI (#19591)
## Summary of the Pull Request
This PR pulls out the icon picker used in Profiles_Base.xaml to be its
own control. Then it's reused as a way to set an icon on folders in the
new tab menu.

As a part of pulling out the icon picker into its own control, some
minor code-health polish was added (i.e. lazy loading icon types and
built in icons).

The new tab menu didn't have a `NavigateToPageArgs`, so I took the
declaration from #19519 and moved it here. I chose to do that instead of
creating a `NavigateToNewTabMenuArgs` since that's more strict and it
would be removed as a part of #19519 anyways.

Aside from that, the PR is pretty straightforward.

## References and Relevant Issues
Part of #18281

## Validation Steps Performed
- Profile icon picker
   - [x] set none
   - [x] set built-in icon
   - [x] set emoji
   - [x] set file
   - [x] loads icons properly (for all of the scenarios above)
- New tab menu folder icon picker
   - [x] set none
   - [x] set built-in icon
   - [x] set emoji
   - [x] set file
   - [x] loads icons properly (for all of the scenarios above)
2026-02-02 11:35:42 -08:00
Dustin L. Howett
cdf4bd9209 Revert "Disable PGO for nightly builds (#17749)" (#19816)
This reverts commit 408f3e2bfd.

Now that we have #19810, it works again!
2026-01-29 23:01:45 +00:00
Dustin L. Howett
8f3d1d8d01 build: make the PGO build work again; upgrade nuget (#19810)
Two main changes:

- the build was failing for ARM64 because the build agents run out of
memory downloading artifacts; this is a known issue that nobody cares to
fix (and it pertains to using the x64 emulated agent host on native
arm64 machines)
   - deleting the PDBs shrinks the build output by 2500MB :P
- we had to switch to a new type of identity for publishing nuget
packages to our cross-org feed

I've verified that we get counts _and_ can even produce final PGO count
packages for both architectures!
2026-01-29 12:44:36 -08:00
Dustin L. Howett
3ec372c176 vpack: ensure that we put the right version number in (#19793)
I just submitted a vpack to Windows and it turned out to be version
"0.0.5". Whoops.
2026-01-28 12:27:05 -06:00
Leonard Hecker
71409f84f7 Avoid scrolling when the search is open (#19775)
When text scrolls in and out of view, depending on the length
of the scrollback and latency of input, `GetSearchHighlightFocused`
would change which would trigger a `ScrollToSearchHighlight` call.

This PR changes the behavior such that only actively changing the
search mask triggers a search (typing text or pressing enter).

Closes #19754

## Validation Steps Performed
* Brining text in and out of view doesn't scroll 
* Toggling the aA button scrolls results into view 
2026-01-23 18:33:18 -06:00
PankajBhojwani
6723ca2239 Delete the KeyChordViewModel if we leave edit mode with no keys (#19778)
There was an issue where if the user adds a new keybinding and then hits
"cancel changes", the KeyChordViewModel is left in the keybinding list
with an empty value. Nothing gets saved to the json, but visually there
was an empty keychord box left behind. This commit fixes that.

## Validation Steps Performed
Adding a new keybinding and cancelling changes deletes the keybinding.
2026-01-23 18:25:43 -06:00
Vallabh Mahajan
c8549bebed sgr: consider ITU T.416 colors with color space 0 valid (#19768)
This PR fixes an issue where SGR color sequences containing a Color
Space ID of 0 (e.g., \e[38:2:0:r:g:bm) were incorrectly rejected as
invalid.

According to ITU T.416, the Color Space ID parameter is defined, and a
value of 0 is implementation-defined. It is widely accepted by other
terminal emulators (like XTerm) as the default RGB color space. This
change modifies the check to explicitly allow an ID of 0 while still
rejecting other non-standard IDs, ensuring compatibility with tools that
emit fully qualified T.416 sequences.

Closes #19547
2026-01-23 17:21:55 +00:00
William Zhang
8d94edd7b0 Dim the caption buttons for unfocused windows (#19668)
This PR closes #12632 by dimming the caption controls in the titlebar
when unfocused. Leaves them intact when in high contrast mode. The color
used is borrowed from PowerToys' unfocused color.

## Validation Steps Performed
Tested by hovering and unhovering in focused and unfocused states, as
well as in high contrast mode. States are consistent and applied
correctly. I did notice that clicking on the titlebar wouldn't put it
into focus unless I also moved my mouse though, but that is also present
in the release branch.

Closes #12632
2026-01-20 20:18:07 +00:00
301 changed files with 7672 additions and 5203 deletions

View File

@@ -1,4 +1,4 @@
blank_issues_enabled: true
blank_issues_enabled: false
contact_links:
- name: Microsoft Security Response Center 🔐

View File

@@ -99,8 +99,7 @@ Resources/(?!en)
^NOTICE.md
^oss/.*?/
^samples/PixelShaders/Screenshots/
^src/cascadia/TerminalApp/TmuxControl\.cpp$
^src/cascadia/TerminalSettingsEditor/SegoeFluentIconList\.h$
^src/cascadia/TerminalSettingsEditor/SegoeFluentIconList.h$
^src/interactivity/onecore/BgfxEngine\.
^src/renderer/atlas/
^src/renderer/wddmcon/WddmConRenderer\.

View File

@@ -256,7 +256,6 @@ conterm
contsf
contypes
conwinuserrefs
coordnew
COPYCOLOR
COPYDATA
COPYDATASTRUCT
@@ -622,7 +621,6 @@ fuzzmap
fuzzwrapper
fwdecl
fwe
fwlink
fzf
gci
gcx
@@ -866,6 +864,7 @@ KILLACTIVE
KILLFOCUS
kinda
KIYEOK
KKP
KLF
KLMNO
KOK
@@ -885,6 +884,7 @@ LBUTTONDOWN
LBUTTONUP
lcb
lci
LCMAP
LCONTROL
LCTRL
lcx
@@ -1064,6 +1064,7 @@ Mypair
Myval
NAMELENGTH
namestream
NCACTIVATE
NCCALCSIZE
NCCREATE
NCLBUTTONDOWN

View File

@@ -28,7 +28,7 @@ extends:
official: true
branding: Canary
buildTerminal: true
pgoBuildMode: None # BODGY - OneBranch is on VS 17.10, which is known to be the worst
pgoBuildMode: Optimize
codeSign: true
signingIdentity:
serviceName: $(SigningServiceName)

View File

@@ -50,6 +50,7 @@ stages:
buildEverything: true
pgoBuildMode: Instrument
artifactStem: -instrumentation
keepAllExpensiveBuildOutputs: false # the ARM64 build agent runs out of memory downloading the artifacts...
- stage: RunPGO
displayName: Run PGO

View File

@@ -26,6 +26,7 @@ jobs:
pgoToolsPath: $(Build.SourcesDirectory)\build\PGO
nuspecPath: $(pgoToolsPath)\NuSpecs
nuspecFilename: PGO.nuspec
nugetFeed: "https://pkgs.dev.azure.com/shine-oss/terminal/_packaging/TerminalDependencies/nuget/v3/index.json"
steps:
- checkout: self
@@ -45,7 +46,8 @@ jobs:
- task: NuGetAuthenticate@1
inputs:
nuGetServiceConnections: 'Terminal Public Artifact Feed'
azureDevOpsServiceConnection: 'Terminal Public Artifact Feed'
feedUrl: $(nugetFeed)
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
# This should be `task: NuGetCommand@2`
@@ -68,15 +70,7 @@ jobs:
artifact: pgo-nupkg-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
displayName: "Publish Pipeline Artifact"
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: 'NuGet push'
inputs:
command: push
nuGetFeedType: external
packagesToPush: $(Build.ArtifactStagingDirectory)/*.nupkg
# The actual URL and PAT for this feed is configured at
# https://microsoft.visualstudio.com/Dart/_settings/adminservices
# This is the name of that connection
publishFeedCredentials: 'Terminal Public Artifact Feed'
feedsToUse: config
nugetConfigPath: '$(Build.SourcesDirectory)/NuGet.config'
- pwsh: |-
$nupkg = Get-Item "$(Build.ArtifactStagingDirectory)/*.nupkg"
& nuget push -ApiKey az -Source "$(nugetFeed)" "$nupkg"
displayName: NuGet push

View File

@@ -45,6 +45,10 @@ jobs:
displayName: Extract the unpackaged build for PGO
- template: steps-ensure-nuget-version.yml
parameters:
${{ if eq(parameters.buildPlatform, 'arm64') }}:
# The ARM64 agents do not seem to have NuGet installed
forceNugetInstallation: true
- powershell: |-
$Package = 'Microsoft.Internal.Windows.Terminal.TestContent'

View File

@@ -210,6 +210,8 @@ extends:
ob_createvpack_taskLogVerbosity: Detailed
ob_createvpack_verbose: true
ob_createvpack_vpackdirectory: '$(JobOutputDirectory)\vpack'
ob_createvpack_versionAs: string
ob_createvpack_version: '$(XES_APPXMANIFESTVERSION)'
ob_updateOSManifest_gitcheckinConfigPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
# We're skipping the 'fetch' part of the OneBranch rules, but that doesn't mean
# that it doesn't expect to have downloaded a manifest directly to some 'destination'

View File

@@ -1,5 +1,10 @@
parameters:
- name: forceNugetInstallation
type: boolean
default: false
steps:
- ${{ if eq(variables['System.CollectionId'], 'cb55739e-4afe-46a3-970f-1b49d8ee7564') }}:
- ${{ if and(ne(parameters.forceNugetInstallation, true), eq(variables['System.CollectionId'], 'cb55739e-4afe-46a3-970f-1b49d8ee7564')) }}:
- pwsh: |-
Write-Host "Assuming NuGet is already installed..."
& nuget.exe help
@@ -7,6 +12,6 @@ steps:
- ${{ else }}:
- task: NuGetToolInstaller@1
displayName: Use NuGet 6.6.1
displayName: Use NuGet 7.0.1
inputs:
versionSpec: 6.6.1
versionSpec: 7.0.1

View File

@@ -0,0 +1,45 @@
From c3be070b7ee42639554555c27dce10c9de7af76c Mon Sep 17 00:00:00 2001
From: "J. Berger" <mail@janaberger.de>
Date: Sat, 1 Nov 2025 17:38:30 +0100
Subject: [PATCH] When using MSVC x86 to compile v12.0.0 or v12.1.0,
conversions from __int64 to a 32bit unsigned int trigger warnings. (#4594)
This is a follow-up for PR #4572.
---
include/fmt/format.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/fmt/format.h b/include/fmt/format.h
index 4a653007..65e19d2d 100644
--- a/include/fmt/format.h
+++ b/include/fmt/format.h
@@ -2534,7 +2534,7 @@ FMT_CONSTEXPR20 auto write_fixed(OutputIt out, const DecimalFP& f,
auto grouping = Grouping(loc, specs.localized());
size += grouping.count_separators(exp);
return write_padded<Char, align::right>(
- out, specs, to_unsigned(size), [&](iterator it) {
+ out, specs, static_cast<size_t>(size), [&](iterator it) {
if (s != sign::none) *it++ = detail::getsign<Char>(s);
it = write_significand(it, f.significand, significand_size, exp,
decimal_point, grouping);
@@ -2550,7 +2550,7 @@ FMT_CONSTEXPR20 auto write_fixed(OutputIt out, const DecimalFP& f,
bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
size += 1 + (pointy ? 1 : 0) + num_zeros;
return write_padded<Char, align::right>(
- out, specs, to_unsigned(size), [&](iterator it) {
+ out, specs, static_cast<size_t>(size), [&](iterator it) {
if (s != sign::none) *it++ = detail::getsign<Char>(s);
*it++ = Char('0');
if (!pointy) return it;
@@ -2594,7 +2594,7 @@ FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
*it++ = Char(exp_char);
return write_exponent<Char>(exp, it);
};
- auto usize = to_unsigned(size);
+ size_t usize = static_cast<size_t>(size);
return specs.width > 0
? write_padded<Char, align::right>(out, specs, usize, write)
: base_iterator(out, write(reserve(out, usize)));
--
2.52.0.vfs.0.5

View File

@@ -1,13 +0,0 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88c12148..967b53dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -260,7 +260,7 @@ if (FMT_MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
join(netfxpath
"C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\"
".NETFramework\\v4.0")
- file(WRITE run-msbuild.bat "
+ file(WRITE "${CMAKE_BINARY_DIR}/run-msbuild.bat" "
${MSBUILD_SETUP}
${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*")
endif ()

View File

@@ -2,10 +2,10 @@ vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO fmtlib/fmt
REF "${VERSION}"
SHA512 573b7de1bd224b7b1b60d44808a843db35d4bc4634f72a9edcb52cf68e99ca66c744fd5d5c97b4336ba70b94abdabac5fc253b245d0d5cd8bbe2a096bf941e39
SHA512 f0da82c545b01692e9fd30fdfb613dbb8dd9716983dcd0ff19ac2a8d36f74beb5540ef38072fdecc1e34191b3682a8542ecbf3a61ef287dbba0a2679d4e023f2
HEAD_REF master
PATCHES
fix-write-batch.patch
0001-When-using-MSVC-x86-to-compile-v12.0.0-or-v12.1.0-co.patch
)
vcpkg_cmake_configure(
@@ -22,13 +22,6 @@ vcpkg_cmake_config_fixup()
vcpkg_fixup_pkgconfig()
vcpkg_copy_pdbs()
if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/fmt/base.h"
"defined(FMT_SHARED)"
"1"
)
endif()
file(REMOVE_RECURSE
"${CURRENT_PACKAGES_DIR}/debug/include"
"${CURRENT_PACKAGES_DIR}/debug/share"

View File

@@ -1,6 +1,6 @@
{
"name": "fmt",
"version": "11.1.4",
"version": "12.1.0",
"description": "{fmt} is an open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.",
"homepage": "https://github.com/fmtlib/fmt",
"license": "MIT",

View File

@@ -0,0 +1,57 @@
From fae5556fd4d4850f948aeabee25ddf0280494725 Mon Sep 17 00:00:00 2001
From: lizz <lizz@sensetime.com>
Date: Fri, 10 Apr 2020 23:02:21 +0800
Subject: [PATCH] No trailing space for BuiltStyledStreamWriter
Signed-off-by: lizz <lizz@sensetime.com>
---
src/lib_json/json_writer.cpp | 10 +++++++++-
src/test_lib_json/main.cpp | 4 ++--
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp
index ee45c43..e22eb17 100644
--- a/src/lib_json/json_writer.cpp
+++ b/src/lib_json/json_writer.cpp
@@ -990,7 +990,15 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
writeCommentBeforeValue(childValue);
writeWithIndent(
valueToQuotedStringN(name.data(), name.length(), emitUTF8_));
- *sout_ << colonSymbol_;
+ size_t n = colonSymbol_.size();
+ if ((childValue.type() == objectValue && !childValue.empty()) ||
+ (childValue.type() == arrayValue && !childValue.empty() &&
+ ((cs_ == CommentStyle::All) || isMultilineArray(childValue)))) {
+ // Line-ending colon, so trim any trailing space from it
+ for (; n && colonSymbol_[n - 1] == ' '; --n)
+ ;
+ }
+ sout_->write(colonSymbol_.data(), n);
writeValue(childValue);
if (++it == members.end()) {
writeCommentAfterValueOnSameLine(childValue);
diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp
index 55ab224..28cb043 100644
--- a/src/test_lib_json/main.cpp
+++ b/src/test_lib_json/main.cpp
@@ -2533,7 +2533,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeNumericValue) {
JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeArrays) {
Json::StreamWriterBuilder writer;
const Json::String expected("{\n"
- "\t\"property1\" : \n"
+ "\t\"property1\" :\n"
"\t[\n"
"\t\t\"value1\",\n"
"\t\t\"value2\"\n"
@@ -2553,7 +2553,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeArrays) {
JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeNestedObjects) {
Json::StreamWriterBuilder writer;
const Json::String expected("{\n"
- "\t\"object1\" : \n"
+ "\t\"object1\" :\n"
"\t{\n"
"\t\t\"bool\" : true,\n"
"\t\t\"nested\" : 123\n"
--
2.52.0.vfs.0.5

View File

@@ -0,0 +1,36 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO open-source-parsers/jsoncpp
REF "${VERSION}"
SHA512 006d81f9f723dcfe875ebc2147449c07c5246bf97dd7b9eee1909decc914b051d6f3f06feb5c3dfa143d28773fb310aabb04a81dc447cc61513309df8eba8b08
HEAD_REF master
PATCHES
0001-No-trailing-space-for-BuildStyledStreamWriter.patch
)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" JSONCPP_STATIC)
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" STATIC_CRT)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DJSONCPP_WITH_CMAKE_PACKAGE=ON
-DBUILD_STATIC_LIBS=${JSONCPP_STATIC}
-DJSONCPP_STATIC_WINDOWS_RUNTIME=${STATIC_CRT}
-DJSONCPP_WITH_PKGCONFIG_SUPPORT=ON
-DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF
-DJSONCPP_WITH_TESTS=OFF
-DJSONCPP_WITH_EXAMPLE=OFF
-DBUILD_OBJECT_LIBS=OFF
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/jsoncpp)
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
vcpkg_copy_pdbs()
vcpkg_fixup_pkgconfig()
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

View File

@@ -0,0 +1,17 @@
{
"name": "jsoncpp",
"version": "1.9.6",
"description": "JsonCpp is a C++ library that allows manipulating JSON values, including serialization and deserialization to and from strings. It can also preserve existing comment in unserialization/serialization steps, making it a convenient format to store user input files.",
"homepage": "https://github.com/open-source-parsers/jsoncpp",
"license": "MIT",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}

View File

@@ -600,90 +600,6 @@ namespace
},
},
};
#pragma region TAEF hookup for the test case array above
struct ArrayIndexTaefAdapterRow : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom | Microsoft::WRL::InhibitFtmBase>, IDataRow>
{
HRESULT RuntimeClassInitialize(const size_t index)
{
_index = index;
return S_OK;
}
STDMETHODIMP GetTestData(BSTR /*pszName*/, SAFEARRAY** ppData) override
{
const auto indexString{ wil::str_printf<std::wstring>(L"%zu", _index) };
auto safeArray{ SafeArrayCreateVector(VT_BSTR, 0, 1) };
LONG index{ 0 };
auto indexBstr{ wil::make_bstr(indexString.c_str()) };
(void)SafeArrayPutElement(safeArray, &index, indexBstr.release());
*ppData = safeArray;
return S_OK;
}
STDMETHODIMP GetMetadataNames(SAFEARRAY** ppMetadataNames) override
{
*ppMetadataNames = nullptr;
return S_FALSE;
}
STDMETHODIMP GetMetadata(BSTR /*pszName*/, SAFEARRAY** ppData) override
{
*ppData = nullptr;
return S_FALSE;
}
STDMETHODIMP GetName(BSTR* ppszRowName) override
{
*ppszRowName = nullptr;
return S_FALSE;
}
private:
size_t _index;
};
struct ArrayIndexTaefAdapterSource : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom | Microsoft::WRL::InhibitFtmBase>, IDataSource>
{
STDMETHODIMP Advance(IDataRow** ppDataRow) override
{
if (_index < std::extent_v<decltype(testCases)>)
{
Microsoft::WRL::MakeAndInitialize<ArrayIndexTaefAdapterRow>(ppDataRow, _index++);
}
else
{
*ppDataRow = nullptr;
}
return S_OK;
}
STDMETHODIMP Reset() override
{
_index = 0;
return S_OK;
}
STDMETHODIMP GetTestDataNames(SAFEARRAY** names) override
{
auto safeArray{ SafeArrayCreateVector(VT_BSTR, 0, 1) };
LONG index{ 0 };
auto dataNameBstr{ wil::make_bstr(L"index") };
(void)SafeArrayPutElement(safeArray, &index, dataNameBstr.release());
*names = safeArray;
return S_OK;
}
STDMETHODIMP GetTestDataType(BSTR /*name*/, BSTR* type) override
{
*type = nullptr;
return S_OK;
}
private:
size_t _index{ 0 };
};
#pragma endregion
}
extern "C" HRESULT __declspec(dllexport) __cdecl ReflowTestDataSource(IDataSource** ppDataSource, void*)

View File

@@ -1421,7 +1421,7 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(L"profile0", terminalArgs.Profile());
VERIFY_IS_NULL(terminalArgs.Elevate());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
@@ -1444,7 +1444,7 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
VERIFY_IS_NULL(terminalArgs.Elevate());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
@@ -1467,7 +1467,7 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
VERIFY_IS_NULL(terminalArgs.Elevate());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
@@ -1492,7 +1492,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
@@ -1516,7 +1516,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
@@ -1540,7 +1540,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
@@ -1565,7 +1565,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
@@ -1588,7 +1588,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
@@ -1612,7 +1612,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
const auto termSettings = termSettingsResult.DefaultSettings();
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
VERIFY_ARE_EQUAL(true, termSettings->Elevate());

View File

@@ -1099,7 +1099,7 @@ namespace TerminalAppLocalTests
Log::Comment(L"Change the tab switch order to MRU switching");
TestOnUIThread([&page]() {
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
});
Log::Comment(L"Switch to the next MRU tab, which is the fourth tab");
@@ -1145,7 +1145,7 @@ namespace TerminalAppLocalTests
});
Log::Comment(L"Change the tab switch order to in-order switching");
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::InOrder);
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::InOrder);
Log::Comment(L"Switch to the next in-order tab, which is the third tab");
TestOnUIThread([&page]() {
@@ -1157,7 +1157,7 @@ namespace TerminalAppLocalTests
});
Log::Comment(L"Change the tab switch order to not use the tab switcher (which is in-order always)");
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::Disabled);
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::Disabled);
Log::Comment(L"Switch to the next in-order tab, which is the fourth tab");
TestOnUIThread([&page]() {
@@ -1219,7 +1219,7 @@ namespace TerminalAppLocalTests
Log::Comment(L"Change the tab switch order to MRU switching");
TestOnUIThread([&page]() {
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
});
Log::Comment(L"Select the tabs from 0 to 3");

View File

@@ -34,7 +34,7 @@ struct
#else // DEV
__declspec(uuid("52065414-e077-47ec-a3ac-1cc5455e1b54"))
#endif
OpenTerminalHere : public RuntimeClass<RuntimeClassFlags<ClassicCom | InhibitFtmBase>, IExplorerCommand, IObjectWithSite>
OpenTerminalHere : public RuntimeClass<RuntimeClassFlags<ClassicCom | InhibitFtmBase>, IExplorerCommand, IObjectWithSite>
{
#pragma region IExplorerCommand
STDMETHODIMP Invoke(IShellItemArray* psiItemArray,

View File

@@ -4,13 +4,12 @@
#include "pch.h"
#include "App.h"
#include "ScratchpadContent.h"
#include "TerminalPage.h"
#include "TmuxControl.h"
#include "Utils.h"
#include "ScratchpadContent.h"
#include "../WinRTUtils/inc/WtExeUtils.h"
#include "../../types/inc/utils.hpp"
#include "../TerminalSettingsAppAdapterLib/TerminalSettings.h"
#include "../WinRTUtils/inc/WtExeUtils.h"
#include "Utils.h"
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::UI::Xaml;
@@ -285,15 +284,6 @@ namespace winrt::TerminalApp::implementation
const auto& activeTab{ _senderOrFocusedTab(sender) };
if constexpr (Feature_TmuxControl::IsEnabled())
{
//Tmux control takes over
if (_tmuxControl && _tmuxControl->TabIsTmuxControl(activeTab))
{
return _tmuxControl->SplitPane(activeTab, realArgs.SplitDirection());
}
}
_SplitPane(activeTab,
realArgs.SplitDirection(),
// This is safe, we're already filtering so the value is (0, 1)
@@ -560,7 +550,7 @@ namespace winrt::TerminalApp::implementation
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
{
const auto copyFormatting = realArgs.CopyFormatting();
const auto format = copyFormatting ? copyFormatting.Value() : _settings.GlobalSettings().CopyFormatting();
const auto format = copyFormatting ? copyFormatting.Value() : _currentWindowSettings().CopyFormatting();
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.WithControlSequences(), format);
args.Handled(handled);
}
@@ -948,6 +938,27 @@ namespace winrt::TerminalApp::implementation
co_return;
}
// Launch `wt -w <name>` so the monarch can either summon an existing
// window with that name or restore a persisted workspace.
safe_void_coroutine TerminalPage::_OpenWorkspaceWindow(const winrt::hstring name)
{
co_await winrt::resume_background();
const auto exePath{ GetWtExePath() };
const auto cmdline = fmt::format(FMT_COMPILE(L"-w {}"), std::wstring_view{ name });
SHELLEXECUTEINFOW seInfo{ 0 };
seInfo.cbSize = sizeof(seInfo);
seInfo.fMask = SEE_MASK_NOASYNC;
seInfo.lpVerb = L"open";
seInfo.lpFile = exePath.c_str();
seInfo.lpParameters = cmdline.c_str();
seInfo.nShow = SW_SHOWNORMAL;
LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo));
co_return;
}
void TerminalPage::_HandleNewWindow(const IInspectable& /*sender*/,
const ActionEventArgs& actionArgs)
{
@@ -971,7 +982,7 @@ namespace winrt::TerminalApp::implementation
if (const auto& terminalArgs{ newContentArgs.try_as<NewTerminalArgs>() })
{
const auto profile{ _settings.GetProfileForArgs(terminalArgs) };
const auto profile{ _settings.GetProfileForArgs(terminalArgs, _currentWindowSettings()) };
terminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
}
@@ -1128,7 +1139,7 @@ namespace winrt::TerminalApp::implementation
// use global default if query URL is unspecified
if (queryUrl.empty())
{
queryUrl = std::wstring_view{ _settings.GlobalSettings().SearchWebDefaultQueryUrl() };
queryUrl = std::wstring_view{ _currentWindowSettings().SearchWebDefaultQueryUrl() };
}
constexpr std::wstring_view queryToken{ L"%s" };
@@ -1643,4 +1654,68 @@ namespace winrt::TerminalApp::implementation
args.Handled(handled);
}
}
void TerminalPage::_HandleOpenWorkspace(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
// Open (or summon) a named window. We launch a new `wt -w <name>`
// process which the monarch will route to the correct live window or
// restore from a persisted workspace.
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<OpenWorkspaceArgs>())
{
const auto name = realArgs.Name();
if (!name.empty())
{
_OpenWorkspaceWindow(name);
}
args.Handled(true);
}
}
}
void TerminalPage::_HandleSaveWorkspace(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<SaveWorkspaceArgs>())
{
// If a name is supplied, use it; otherwise fall back to the
// current window name.
auto name = realArgs.Name();
if (name.empty())
{
name = _WindowProperties.WindowName();
}
if (!name.empty())
{
if (const auto layout = GetWindowLayout())
{
ApplicationState::SharedInstance().SaveWorkspace(name, layout);
}
}
args.Handled(true);
}
}
}
void TerminalPage::_HandleDeleteWorkspace(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<DeleteWorkspaceArgs>())
{
const auto name = realArgs.Name();
if (!name.empty())
{
ApplicationState::SharedInstance().RemoveWorkspace(name);
}
args.Handled(true);
}
}
}
}

View File

@@ -194,7 +194,7 @@ namespace winrt::TerminalApp::implementation
g_hTerminalAppProvider,
"AppCreated",
TraceLoggingDescription("Event emitted when the application is started"),
TraceLoggingBool(_settings.GlobalSettings().ShowTabsInTitlebar(), "TabsInTitlebar"),
TraceLoggingBool(_settings.WindowSettingsDefaults().ShowTabsInTitlebar(), "TabsInTitlebar"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
}
@@ -229,12 +229,12 @@ namespace winrt::TerminalApp::implementation
}
_hasSettingsStartupActions = false;
const auto startupActions = newSettings.GlobalSettings().StartupActions();
const auto startupActions = newSettings.WindowSettingsDefaults().StartupActions();
if (!startupActions.empty())
{
_settingsAppArgs.FullResetState();
ExecuteCommandlineArgs args{ newSettings.GlobalSettings().StartupActions() };
ExecuteCommandlineArgs args{ newSettings.WindowSettingsDefaults().StartupActions() };
auto result = _settingsAppArgs.ParseArgs(args);
if (result == 0)
{

View File

@@ -928,6 +928,17 @@ namespace winrt::TerminalApp::implementation
void CommandPalette::_filterTextChanged(const IInspectable& /*sender*/,
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
{
// GH#18737: Only respond to this change if we are visible:
// _close calls _searchBox().Text(L"") to reset the search text, which lands us
// in here after the command palette is dismissed. Since we have a code path here that
// could potentially lead to an action being previewed (specifically if there is a
// preview-able action as the first entry in the command list), that preview will
// appear after the palette is dismissed without this check.
if (Visibility() != Visibility::Visible)
{
return;
}
// When we are executing the _SelectNextTab in the TabManagement.cpp, this method
// is getting triggered because we set up the default value for that CommandPalette
// with an empty string. Therefore, to avoid the reset of the index when executing

View File

@@ -13,7 +13,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
{
public:
explicit DebugTapConnection(Microsoft::Terminal::TerminalConnection::ITerminalConnection wrappedConnection);
void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/){};
void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) {};
~DebugTapConnection();
void Start();
void WriteInput(const winrt::array_view<const char16_t> data);

View File

@@ -25,7 +25,7 @@ namespace winrt::TerminalApp::implementation
#pragma region IPaneContent
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings&){};
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings&) {};
winrt::Windows::Foundation::Size MinimumSize() { return { 1, 1 }; };
void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic) { reason; };

View File

@@ -88,6 +88,18 @@ namespace winrt::TerminalApp::implementation
CloseClick.raise(*this, e);
}
bool MinMaxCloseControl::Focused() const
{
return _focused;
}
void MinMaxCloseControl::Focused(bool focused)
{
_focused = focused;
ReleaseButtons();
}
void MinMaxCloseControl::SetWindowVisualState(WindowVisualState visualState)
{
// Look up the heights we should use for the caption buttons from our
@@ -169,25 +181,25 @@ namespace winrt::TerminalApp::implementation
// animate the fade in/out transition between colors.
case CaptionButton::Minimize:
VisualStateManager::GoToState(MinimizeButton(), L"PointerOver", true);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
_displayToolTip->Run(MinimizeButton());
closeToolTipForButton(MaximizeButton());
closeToolTipForButton(CloseButton());
break;
case CaptionButton::Maximize:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
VisualStateManager::GoToState(MaximizeButton(), L"PointerOver", true);
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
closeToolTipForButton(MinimizeButton());
_displayToolTip->Run(MaximizeButton());
closeToolTipForButton(CloseButton());
break;
case CaptionButton::Close:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
VisualStateManager::GoToState(CloseButton(), L"PointerOver", true);
closeToolTipForButton(MinimizeButton());
@@ -210,17 +222,17 @@ namespace winrt::TerminalApp::implementation
{
case CaptionButton::Minimize:
VisualStateManager::GoToState(MinimizeButton(), L"Pressed", true);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
break;
case CaptionButton::Maximize:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
VisualStateManager::GoToState(MaximizeButton(), L"Pressed", true);
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
break;
case CaptionButton::Close:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
VisualStateManager::GoToState(CloseButton(), L"Pressed", true);
break;
}
@@ -233,9 +245,9 @@ namespace winrt::TerminalApp::implementation
void MinMaxCloseControl::ReleaseButtons()
{
_displayToolTip->Run(nullptr);
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
closeToolTipForButton(MinimizeButton());
closeToolTipForButton(MaximizeButton());
@@ -243,4 +255,11 @@ namespace winrt::TerminalApp::implementation
_lastPressedButton = std::nullopt;
}
const winrt::param::hstring& MinMaxCloseControl::_normalState() const
{
static const winrt::param::hstring normal = L"Normal";
static const winrt::param::hstring unfocused = L"Unfocused";
return (_focused ? normal : unfocused);
}
}

View File

@@ -21,6 +21,9 @@ namespace winrt::TerminalApp::implementation
void PressButton(CaptionButton button);
void ReleaseButtons();
bool Focused() const;
void Focused(bool focused);
void _MinimizeClick(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _MaximizeClick(const winrt::Windows::Foundation::IInspectable& sender,
@@ -32,8 +35,12 @@ namespace winrt::TerminalApp::implementation
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> MaximizeClick;
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> CloseClick;
bool _focused{ false };
std::shared_ptr<ThrottledFunc<winrt::Windows::UI::Xaml::Controls::Button>> _displayToolTip{ nullptr };
std::optional<CaptionButton> _lastPressedButton{ std::nullopt };
private:
const winrt::param::hstring& _normalState() const;
};
}

View File

@@ -14,6 +14,7 @@ namespace TerminalApp
void HoverButton(CaptionButton button);
void PressButton(CaptionButton button);
void ReleaseButtons();
Boolean Focused { get; set; };
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MinimizeClick;
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MaximizeClick;

View File

@@ -32,6 +32,10 @@
ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CaptionButtonForegroundPressed"
ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CaptionButtonForegroundUnfocusedColor"
ResourceKey="TextFillColorDisabled" />
<SolidColorBrush x:Key="CaptionButtonForegroundUnfocused"
Color="{ThemeResource CaptionButtonForegroundUnfocusedColor}" />
<SolidColorBrush x:Key="CaptionButtonBackground"
Color="Transparent" />
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
@@ -66,6 +70,10 @@
ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CaptionButtonForegroundPressed"
ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CaptionButtonForegroundUnfocusedColor"
ResourceKey="TextFillColorDisabled" />
<SolidColorBrush x:Key="CaptionButtonForegroundUnfocused"
Color="{ThemeResource CaptionButtonForegroundUnfocusedColor}" />
<SolidColorBrush x:Key="CaptionButtonBackground"
Color="Transparent" />
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
@@ -103,6 +111,10 @@
Color="{ThemeResource SystemColorHighlightTextColor}" />
<SolidColorBrush x:Key="CaptionButtonForegroundPressed"
Color="{ThemeResource SystemColorHighlightTextColor}" />
<SolidColorBrush x:Key="CaptionButtonForegroundUnfocused"
Color="{ThemeResource SystemColorButtonTextColor}" />
<StaticResource x:Key="CaptionButtonForegroundUnfocusedColor"
ResourceKey="SystemColorButtonTextColor" />
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="CloseButtonForegroundPointerOver"
@@ -189,6 +201,20 @@
Duration="0:0:0.1" />
</Storyboard>
</VisualTransition>
<VisualTransition From="PointerOver"
To="Unfocused">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBaseElement"
Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)"
To="{ThemeResource CaptionButtonBackgroundColor}"
Duration="0:0:0.15" />
<ColorAnimation Storyboard.TargetName="ButtonIcon"
Storyboard.TargetProperty="(UIElement.Foreground).(SolidColorBrush.Color)"
To="{ThemeResource CaptionButtonForegroundUnfocusedColor}"
Duration="0:0:0.1" />
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal">
@@ -198,6 +224,13 @@
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unfocused">
<VisualState.Setters>
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackground}" />
<Setter Target="ButtonIcon.Foreground" Value="{ThemeResource CaptionButtonForegroundUnfocused}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackgroundPointerOver}" />

View File

@@ -1306,10 +1306,10 @@ void Pane::UpdateSettings(const CascadiaSettings& settings)
// - splitType: How the pane should be attached
// Return Value:
// - the new reference to the child created from the current pane.
std::shared_ptr<Pane> Pane::AttachPane(std::shared_ptr<Pane> pane, SplitDirection splitType, const float splitSize)
std::shared_ptr<Pane> Pane::AttachPane(std::shared_ptr<Pane> pane, SplitDirection splitType)
{
// Splice the new pane into the tree
const auto [first, _] = _Split(splitType, splitSize, pane);
const auto [first, _] = _Split(splitType, .5, pane);
// If the new pane has a child that was the focus, re-focus it
// to steal focus from the currently focused pane.
@@ -2298,7 +2298,8 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
_firstChild->Closed(_firstClosedToken);
_secondChild->Closed(_secondClosedToken);
// If we are not a leaf we should create a new pane that contains our children
_firstChild = std::make_shared<Pane>(_firstChild, _secondChild, _splitState, _desiredSplitPosition);
auto first = std::make_shared<Pane>(_firstChild, _secondChild, _splitState, _desiredSplitPosition);
_firstChild = first;
}
else
{

View File

@@ -131,8 +131,7 @@ public:
void Close();
std::shared_ptr<Pane> AttachPane(std::shared_ptr<Pane> pane,
winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize = .5);
winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType);
std::shared_ptr<Pane> DetachPane(std::shared_ptr<Pane> pane);
int GetLeafPaneCount() const noexcept;

View File

@@ -85,6 +85,7 @@ namespace winrt::TerminalApp::implementation
WINRT_PROPERTY(TerminalApp::CommandlineArgs, Command, nullptr);
WINRT_PROPERTY(winrt::hstring, Content);
WINRT_PROPERTY(Windows::Foundation::IReference<Windows::Foundation::Rect>, InitialBounds);
WINRT_PROPERTY(winrt::Microsoft::Terminal::Settings::Model::WindowLayout, PersistedLayout, nullptr);
};
}

View File

@@ -51,5 +51,6 @@ namespace TerminalApp
CommandlineArgs Command { get; };
String Content { get; };
Windows.Foundation.IReference<Windows.Foundation.Rect> InitialBounds { get; };
Microsoft.Terminal.Settings.Model.WindowLayout PersistedLayout;
};
}

View File

@@ -923,11 +923,4 @@
<data name="InvalidRegex" xml:space="preserve">
<value>An invalid regular expression was found.</value>
</data>
<data name="TmuxControlInfo" xml:space="preserve">
<value>Running in tmux control mode; Press 'q' to detach:</value>
<comment>{Locked="'q'"}</comment>
</data>
<data name="NewTmuxControlTab.Text" xml:space="preserve">
<value>Tmux Control Tab</value>
</data>
</root>
</root>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="InitialJsonParseErrorText" xml:space="preserve">
<value>Подешавања нису могла да се учитау из фајла. Проверите има ли синтаксних грешака, укључујући запете на крају реда.</value>
<value>Подешавања нису могла да се учитају из фајла. Проверите има ли синтаксних грешака, укључујући запете на крају реда.</value>
</data>
<data name="MissingDefaultProfileText" xml:space="preserve">
<value>У листи профила није могао да се пронађе ваш подразумевани профил - користи се први профил. Проверите да ли се "defaultProfile" подудара са GUID неког од ваших профила.</value>
@@ -141,7 +141,7 @@
<value>Подешавања нису могла поново да се учитају из фајла. Проверите има ли синтаксних грешака, укључујући запете на крају реда.</value>
</data>
<data name="UsingDefaultSettingsText" xml:space="preserve">
<value>Привремено се користе подразумевана подешавања Windows Терминала.</value>
<value>Привремено се користе подразумевана подешавања апликације Windows Терминал.</value>
</data>
<data name="InitialJsonParseErrorTitle" xml:space="preserve">
<value>Није успело учитавање подешавања</value>
@@ -149,12 +149,6 @@
<data name="SettingsValidateErrorTitle" xml:space="preserve">
<value>Наишло се на грешке током учитавања корисничких подешавања</value>
</data>
<data name="KeyboardServiceDisabledDialog.PrimaryButtonText" xml:space="preserve">
<value>ОК</value>
</data>
<data name="KeyboardServiceDisabledDialog.Title" xml:space="preserve">
<value>Упозорење:</value>
</data>
<data name="KeyboardServiceWarningText" xml:space="preserve">
<value>„{0}” се не извршава на вашој машини. Због тога Терминал можда неће моћи да прима улаз са тастатуре.</value>
<comment>{0} will be replaced with the OS-localized name of the TabletInputService</comment>
@@ -165,28 +159,12 @@
<data name="ReloadJsonParseErrorTitle" xml:space="preserve">
<value>Није успело поновно учитавање подешавања</value>
</data>
<data name="FeedbackUriValue" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2125419</value>
<comment>{Locked}This is a FWLink, so it will be localized with the fwlink tool</comment>
</data>
<data name="AboutMenuItem" xml:space="preserve">
<value>О програму</value>
</data>
<data name="FeedbackMenuItem" xml:space="preserve">
<value>Повратне информације</value>
</data>
<data name="SettingsMenuItem" xml:space="preserve">
<value>Подешавања</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Откажи</value>
</data>
<data name="CloseAll" xml:space="preserve">
<value>Затвори све</value>
</data>
<data name="Quit" xml:space="preserve">
<value>Напусти</value>
</data>
<data name="MultiplePanes" xml:space="preserve">
<value>Више панела</value>
</data>
@@ -293,17 +271,6 @@
<value>• Наведена "theme" није пронађена у листи тема. Привремено се употребљава подразумевана вредност.</value>
<comment>{Locked="•"} This glyph is a bullet, used in a bulleted list.</comment>
</data>
<data name="LegacyGlobalsProperty" xml:space="preserve">
<value>Особина "globals" је застарела - ваша подешавања би требало да се ажурирају. </value>
<comment>{Locked="\"globals\""} </comment>
</data>
<data name="LegacyGlobalsPropertyHrefUrl" xml:space="preserve">
<value>https://go.microsoft.com/fwlink/?linkid=2128258</value>
<comment>{Locked}This is a FWLink, so it will be localized with the fwlink tool</comment>
</data>
<data name="LegacyGlobalsPropertyHrefLabel" xml:space="preserve">
<value>За више информација, погледајте следећу веб страницу.</value>
</data>
<data name="FailedToParseCommandJson" xml:space="preserve">
<value>Није успело развијање команде којој је постављено "iterateOn". Ова команда ће се игнорисати.</value>
<comment>{Locked="\"iterateOn\""} </comment>
@@ -484,21 +451,12 @@
<data name="ElevatedRun.Text" xml:space="preserve">
<value>Ctrl+Клик да отворите као администратор</value>
</data>
<data name="WindowCloseButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Затвори</value>
</data>
<data name="WindowCloseButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Затвори</value>
</data>
<data name="WindowCloseButtonToolTip.Text" xml:space="preserve">
<value>Затвори</value>
</data>
<data name="WindowMaximizeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Увећај</value>
</data>
<data name="WindowMinimizeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Умањи</value>
</data>
<data name="WindowMinimizeButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Умањи</value>
</data>
@@ -518,10 +476,6 @@
<value>Верзија:</value>
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Брзи почетак</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
<value>Изворни кôд</value>
<comment>A hyperlink name for the Terminal's documentation</comment>
@@ -600,7 +554,7 @@
<value>Откуцајте име команде...</value>
</data>
<data name="CommandPalette_NoMatchesText.Text" xml:space="preserve">
<value>Нема команди које се подударају</value>
<value>Ниједна команда се не подудара</value>
</data>
<data name="CommandPaletteModeAnnouncement_ActionMode" xml:space="preserve">
<value>Акција режим претраге</value>
@@ -797,18 +751,9 @@
<data name="ExportTabText" xml:space="preserve">
<value>Извези текст</value>
</data>
<data name="ExportFailure" xml:space="preserve">
<value>Није успео извоз садржаја терминала</value>
</data>
<data name="ExportSuccess" xml:space="preserve">
<value>Успешно је извезен садржај терминала</value>
</data>
<data name="FindText" xml:space="preserve">
<value>Пронађи</value>
</data>
<data name="PlainText" xml:space="preserve">
<value>Чисти текст</value>
</data>
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Понашање при прекиду извршавања може да се подеси у напредним подешавањима профила.</value>
</data>
@@ -914,10 +859,6 @@
<value>Картица "{0}" је премештена на позицију "{1}"</value>
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful tab movement. {0} is the name of the tab. {1} is the new tab index in the tab row.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow" xml:space="preserve">
<value>Активни панел је премештен у картицу "{0}" у прозору "{1}"</value>
<comment>{Locked="{0}"}{Locked="{1}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the tab the pane was moved to. {1} is the name of the window the pane was moved to. Replaced in 1.19 by TerminalPage_PaneMovedAnnouncement_ExistingWindow2</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingWindow2" xml:space="preserve">
<value>Активни панел је премештен у прозор "{0}"</value>
<comment>{Locked="{0}"}This text is read out by screen readers upon a successful pane movement. {0} is the name of the window the pane was moved to.</comment>

View File

@@ -19,7 +19,7 @@ namespace winrt::TerminalApp::implementation
// Stash away the current requested theme of the app. We'll need that in
// _BackgroundBrush() to do a theme-aware resource lookup
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
_requestedTheme = settings.GlobalSettings().CurrentTheme(settings.WindowSettingsDefaults()).RequestedTheme();
}
void SettingsPaneContent::UpdateSettings(const CascadiaSettings& settings)
@@ -27,7 +27,7 @@ namespace winrt::TerminalApp::implementation
ASSERT_UI_THREAD();
_sui.UpdateSettings(settings);
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
_requestedTheme = settings.GlobalSettings().CurrentTheme(settings.WindowSettingsDefaults()).RequestedTheme();
}
winrt::Windows::UI::Xaml::FrameworkElement SettingsPaneContent::GetRoot()

View File

@@ -121,7 +121,7 @@ namespace winrt::TerminalApp::implementation
{
static const auto key = winrt::box_value(L"SettingsUiTabBrush");
return ThemeLookup(WUX::Application::Current().Resources(),
_settings.GlobalSettings().CurrentTheme().RequestedTheme(),
_settings.GlobalSettings().CurrentTheme(_settings.WindowSettingsDefaults()).RequestedTheme(),
key)
.try_as<winrt::WUX::Media::Brush>();
}

View File

@@ -173,7 +173,7 @@ namespace winrt::TerminalApp::implementation
// Make sure to try/catch this, because the LocalTests won't be
// able to use this helper.
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
if (settings.GlobalSettings().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
if (settings.WindowSettingsDefaults().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
{
_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthTitleLength);
}
@@ -1114,7 +1114,7 @@ namespace winrt::TerminalApp::implementation
[dispatcher, weakThis](auto&&, auto&&) -> safe_void_coroutine {
const auto weakThisCopy = weakThis;
co_await wil::resume_foreground(dispatcher);
if (auto tab{ weakThis.get() })
if (auto tab{ weakThisCopy.get() })
{
tab->_RecalculateAndApplyReadOnly();
}

View File

@@ -66,14 +66,14 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& newTerminalArgs{ newContentArgs.try_as<NewTerminalArgs>() })
{
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings()) };
// GH#11114: GetProfileForArgs can return null if the index is higher
// than the number of available profiles.
if (!profile)
{
return S_FALSE;
}
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs) };
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, _currentWindowSettings()) };
// Try to handle auto-elevation
if (_maybeElevate(newTerminalArgs, settings, profile))
@@ -105,7 +105,7 @@ namespace winrt::TerminalApp::implementation
if (insertPosition == -1)
{
insertPosition = _tabs.Size();
if (_settings.GlobalSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
if (_currentWindowSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
{
auto currentTabIndex = _GetFocusedTabIndex();
if (currentTabIndex.has_value())
@@ -220,7 +220,7 @@ namespace winrt::TerminalApp::implementation
if (const auto content{ tab.GetActiveContent() })
{
const auto& icon{ content.Icon() };
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
tab.UpdateIcon(icon, iconStyle);
@@ -231,7 +231,7 @@ namespace winrt::TerminalApp::implementation
// - Handle changes to the tab width set by the user
void TerminalPage::_UpdateTabWidthMode()
{
_tabView.TabWidthMode(_settings.GlobalSettings().TabWidthMode());
_tabView.TabWidthMode(_currentWindowSettings().TabWidthMode());
}
// Method Description:
@@ -244,9 +244,9 @@ namespace winrt::TerminalApp::implementation
// - there is more than one tab, or the user has chosen to always show tabs
const auto isVisible = !_isInFocusMode &&
(!_isFullscreen || _showTabsFullscreen) &&
(_settings.GlobalSettings().ShowTabsInTitlebar() ||
(_currentWindowSettings().ShowTabsInTitlebar() ||
(_tabs.Size() > 1) ||
_settings.GlobalSettings().AlwaysShowTabs());
_currentWindowSettings().AlwaysShowTabs());
if (_tabView)
{
@@ -286,7 +286,7 @@ namespace winrt::TerminalApp::implementation
// current control's live settings (which will include changes
// made through VT).
uint32_t insertPosition = _tabs.Size();
if (_settings.GlobalSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
if (_currentWindowSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
{
insertPosition = tab.TabViewIndex() + 1;
}
@@ -438,6 +438,21 @@ namespace winrt::TerminalApp::implementation
const auto focusedTabIndex{ _GetFocusedTabIndex() };
// If this is the last tab in a named window, persist the workspace
// layout now—before the tab is shut down—so GetWindowLayout() can
// still see its tab data.
if (_tabs.Size() == 1)
{
const auto& windowName = _WindowProperties.WindowName();
if (!windowName.empty())
{
if (const auto layout = GetWindowLayout())
{
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
}
}
}
// Removing the tab from the collection should destroy its control and disconnect its connection,
// but it doesn't always do so. The UI tree may still be holding the control and preventing its destruction.
tab.Shutdown();
@@ -477,7 +492,7 @@ namespace winrt::TerminalApp::implementation
// 1. We want to customize this behavior (e.g., use MRU logic)
// 2. In fullscreen (GH#5799) and focus (GH#7916) modes the _OnTabItemsChanged is not fired
// 3. When rearranging tabs (GH#7916) _OnTabItemsChanged is suppressed
const auto tabSwitchMode = _settings.GlobalSettings().TabSwitcherMode();
const auto tabSwitchMode = _currentWindowSettings().TabSwitcherMode();
if (tabSwitchMode == TabSwitcherMode::MostRecentlyUsed)
{
@@ -528,7 +543,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_SelectNextTab(const bool bMoveRight, const Windows::Foundation::IReference<Microsoft::Terminal::Settings::Model::TabSwitcherMode>& customTabSwitcherMode)
{
const auto index{ _GetFocusedTabIndex().value_or(0) };
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _settings.GlobalSettings().TabSwitcherMode();
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _currentWindowSettings().TabSwitcherMode();
if (tabSwitchMode == TabSwitcherMode::Disabled)
{
auto tabCount = _tabs.Size();
@@ -1017,7 +1032,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_UpdateBackground(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile)
{
if (profile && _settings.GlobalSettings().UseBackgroundImageForWindow())
if (profile && _currentWindowSettings().UseBackgroundImageForWindow())
{
_SetBackgroundImage(profile.DefaultAppearance());
}

View File

@@ -25,6 +25,21 @@ namespace winrt::TerminalApp::implementation
InitializeComponent();
}
void TabRowControl::WorkspaceName(const winrt::hstring& value)
{
if (_WorkspaceName != value)
{
_WorkspaceName = value;
PropertyChanged.raise(*this, WUX::Data::PropertyChangedEventArgs{ L"WorkspaceName" });
// Collapse the name text when empty so the button shows only the icon.
if (const auto textBlock = WorkspaceNameText())
{
textBlock.Visibility(value.empty() ? WUX::Visibility::Collapsed : WUX::Visibility::Visible);
}
}
}
// Method Description:
// - Bound in the Xaml editor to the [+] button.
// Arguments:

View File

@@ -19,6 +19,14 @@ namespace winrt::TerminalApp::implementation
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(bool, ShowElevationShield, PropertyChanged.raise, false);
WINRT_OBSERVABLE_PROPERTY(bool, ShowWindowsButton, PropertyChanged.raise, true);
public:
winrt::hstring WorkspaceName() const noexcept { return _WorkspaceName; }
void WorkspaceName(const winrt::hstring& value);
private:
winrt::hstring _WorkspaceName{};
};
}

View File

@@ -9,5 +9,7 @@ namespace TerminalApp
TabRowControl();
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
Boolean ShowElevationShield;
Boolean ShowWindowsButton;
String WorkspaceName;
}
}

View File

@@ -35,14 +35,43 @@
TabWidthMode="Equal">
<mux:TabView.TabStripHeader>
<!-- EA18 is the "Shield" glyph -->
<FontIcon x:Uid="ElevationShield"
Margin="9,4,0,4"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
Glyph="&#xEA18;"
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
<StackPanel Orientation="Horizontal">
<!-- EA18 is the "Shield" glyph -->
<FontIcon x:Uid="ElevationShield"
Margin="9,4,0,4"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
Glyph="&#xEA18;"
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
<!-- Workspace/windows button -->
<Button x:Name="WorkspaceDropdown"
Margin="4,4,0,4"
Padding="8,2,4,2"
VerticalAlignment="Center"
BorderThickness="0"
Background="Transparent"
Visibility="{x:Bind ShowWindowsButton, Mode=OneWay}">
<Button.Content>
<StackPanel Orientation="Horizontal"
Spacing="4">
<!-- EE40 is the "TaskViewSettings" glyph -->
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xEE40;" />
<TextBlock x:Name="WorkspaceNameText"
VerticalAlignment="Center"
FontSize="12"
Visibility="Collapsed"
Text="{x:Bind WorkspaceName, Mode=OneWay}" />
</StackPanel>
</Button.Content>
<Button.Flyout>
<MenuFlyout x:Name="WorkspaceFlyout" />
</Button.Flyout>
</Button>
</StackPanel>
</mux:TabView.TabStripHeader>
<mux:TabView.TabStripFooter>

View File

@@ -9,7 +9,7 @@ namespace winrt::TerminalApp::implementation
{
// Default to unset, 0%.
TaskbarState::TaskbarState() :
TaskbarState(0, 0){};
TaskbarState(0, 0) {};
TaskbarState::TaskbarState(const uint64_t dispatchTypesState, const uint64_t progressParam) :
_State{ dispatchTypesState },

View File

@@ -134,7 +134,7 @@
</ClInclude>
<ClInclude Include="FilteredCommand.h" />
<ClInclude Include="Pane.h" />
<ClInclude Include="fzf/fzf.h" />
<ClInclude Include="../fzf/fzf.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="ShortcutActionDispatch.h">
<DependentUpon>ShortcutActionDispatch.idl</DependentUpon>
@@ -173,8 +173,6 @@
<ClInclude Include="SettingsPaneContent.h">
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
</ClInclude>
<ClInclude Include="TmuxConnection.h" />
<ClInclude Include="TmuxControl.h" />
<ClInclude Include="Toast.h" />
<ClInclude Include="TerminalSettingsCache.h" />
<ClInclude Include="SuggestionsControl.h">
@@ -206,7 +204,7 @@
<ClCompile Include="Tab.cpp">
<DependentUpon>Tab.idl</DependentUpon>
</ClCompile>
<ClCompile Include="fzf/fzf.cpp" />
<ClCompile Include="../fzf/fzf.cpp" />
<ClCompile Include="TaskbarState.cpp">
<DependentUpon>TaskbarState.idl</DependentUpon>
</ClCompile>
@@ -288,8 +286,6 @@
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="TmuxConnection.cpp" />
<ClCompile Include="TmuxControl.cpp" />
<ClCompile Include="Toast.cpp" />
<ClCompile Include="TerminalSettingsCache.cpp" />
<ClCompile Include="SuggestionsControl.cpp">
@@ -299,6 +295,7 @@
<DependentUpon>MarkdownPaneContent.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
</ItemGroup>
<!-- ========================= idl Files ======================== -->
<ItemGroup>
@@ -425,6 +422,7 @@
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<!-- This is a hack to get the ARM64 CI build working. See
@@ -518,4 +516,4 @@
</ItemGroup>
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>
</Project>

View File

@@ -33,8 +33,6 @@
<ClCompile Include="Toast.cpp" />
<ClCompile Include="LanguageProfileNotifier.cpp" />
<ClCompile Include="TerminalSettingsCache.cpp" />
<ClCompile Include="TmuxConnection.cpp" />
<ClCompile Include="TmuxControl.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
@@ -64,8 +62,6 @@
<ClInclude Include="LanguageProfileNotifier.h" />
<ClInclude Include="WindowsPackageManagerFactory.h" />
<ClInclude Include="TerminalSettingsCache.h" />
<ClInclude Include="TmuxConnection.h" />
<ClInclude Include="TmuxControl.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="AppLogic.idl">
@@ -155,4 +151,4 @@
<Filter>app</Filter>
</ApplicationDefinition>
</ItemGroup>
</Project>
</Project>

View File

@@ -23,9 +23,9 @@
#include "SnippetsPaneContent.h"
#include "TabRowControl.h"
#include "TerminalSettingsCache.h"
#include "TmuxControl.h"
#include "LaunchPositionRequest.g.cpp"
#include "WindowListRequest.g.cpp"
#include "RenameWindowRequestedArgs.g.cpp"
#include "RequestMoveContentArgs.g.cpp"
#include "TerminalPage.g.cpp"
@@ -39,7 +39,6 @@ using namespace winrt::Microsoft::Terminal;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::System;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::UI::Text;
@@ -228,6 +227,11 @@ namespace winrt::TerminalApp::implementation
_WindowProperties.PropertyChanged({ get_weak(), &TerminalPage::_windowPropertyChanged });
}
winrt::Microsoft::Terminal::Settings::Model::WindowSettings TerminalPage::_currentWindowSettings() const
{
return _settings.WindowSettings(_WindowProperties.WindowName());
}
// Method Description:
// - implements the IInitializeWithWindow interface from shobjidl_core.
// - We're going to use this HWND as the owner for the ConPTY windows, via
@@ -270,12 +274,19 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::SetSettings(CascadiaSettings settings, bool needRefreshUI)
{
assert(Dispatcher().HasThreadAccess());
if (_settings == nullptr)
// IMPORTANT: we must assign _settings FIRST, because many downstream
// helpers (e.g. _currentWindowSettings()) dereference it. On the very
// first call _settings is nullptr, so any access before this line would
// crash.
const auto firstLoad = _settings == nullptr;
_settings = settings;
if (firstLoad)
{
// Create this only on the first time we load the settings.
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings);
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings, _currentWindowSettings());
}
_settings = settings;
// Make sure to call SetCommands before _RefreshUIForSettingsReload.
// SetCommands will make sure the KeyChordText of Commands is updated, which needs
@@ -336,8 +347,22 @@ namespace winrt::TerminalApp::implementation
auto tabRowImpl = winrt::get_self<implementation::TabRowControl>(_tabRow);
_newTabButton = tabRowImpl->NewTabButton();
_workspaceFlyout = tabRowImpl->WorkspaceFlyout();
if (_settings.GlobalSettings().ShowTabsInTitlebar())
// Set the initial workspace name from the window name.
// Use raw WindowName() so unnamed windows show no text.
_tabRow.WorkspaceName(_WindowProperties.WindowName());
// Rebuild the workspace flyout each time it opens so it always
// reflects the latest set of persisted workspaces.
_workspaceFlyout.Opening([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
page->_PopulateWorkspaceFlyout();
}
});
if (_currentWindowSettings().ShowTabsInTitlebar())
{
// Remove the TabView from the page. We'll hang on to it, we need to
// put it in the titlebar.
@@ -372,7 +397,7 @@ namespace winrt::TerminalApp::implementation
// Initialize the state of the CloseButtonOverlayMode property of
// our TabView, to match the tab.showCloseButton property in the theme.
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
if (const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()))
{
const auto visibility = theme.Tab() ? theme.Tab().ShowCloseButton() : Settings::Model::TabCloseButtonVisibility::Always;
@@ -407,15 +432,6 @@ namespace winrt::TerminalApp::implementation
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
if constexpr (Feature_TmuxControl::IsEnabled())
{
// tmux control takes over
if (page->_tmuxControl && page->_tmuxControl->TabIsTmuxControl(page->_GetFocusedTabImpl()))
{
return;
}
}
page->_OpenNewTerminalViaDropdown(NewTerminalArgs());
}
});
@@ -436,7 +452,7 @@ namespace winrt::TerminalApp::implementation
// Settings AllowDependentAnimations will affect whether animations are
// enabled application-wide, so we don't need to check it each time we
// want to create an animation.
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_currentWindowSettings().DisableAnimations());
// Once the page is actually laid out on the screen, trigger all our
// startup actions. Things like Panes need to know at least how big the
@@ -445,14 +461,20 @@ namespace winrt::TerminalApp::implementation
// _OnFirstLayout will remove this handler so it doesn't get called more than once.
_layoutUpdatedRevoker = _tabContent.LayoutUpdated(winrt::auto_revoke, { this, &TerminalPage::_OnFirstLayout });
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
_showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen();
_isAlwaysOnTop = _currentWindowSettings().AlwaysOnTop();
_showTabsFullscreen = _currentWindowSettings().ShowTabsFullscreen();
// DON'T set up Toasts/TeachingTips here. They should be loaded and
// initialized the first time they're opened, in whatever method opens
// them.
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
_tabRow.ShowElevationShield(IsRunningElevated() && _currentWindowSettings().ShowAdminShield());
// Apply the ShowWindowsButton theme setting.
if (const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()))
{
_tabRow.ShowWindowsButton(theme.Window() ? theme.Window().ShowWindowsButton() : true);
}
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
DispatcherQueue::GetForCurrentThread(),
@@ -531,7 +553,7 @@ namespace winrt::TerminalApp::implementation
// It's possible that newTerminalArgs is null here.
// GetProfileForArgs should be resilient to that.
const auto profile{ settings.GetProfileForArgs(newTerminalArgs) };
const auto profile{ settings.GetProfileForArgs(newTerminalArgs, settings.WindowSettingsDefaults()) };
if (profile.Elevate())
{
continue;
@@ -962,7 +984,7 @@ namespace winrt::TerminalApp::implementation
// Create profile entries from the NewTabMenu configuration using a
// recursive helper function. This returns a std::vector of FlyoutItemBases,
// that we then add to our Flyout.
auto entries = _settings.GlobalSettings().NewTabMenu();
auto entries = _currentWindowSettings().NewTabMenu();
auto items = _CreateNewTabFlyoutItems(entries);
for (const auto& item : items)
{
@@ -1244,7 +1266,7 @@ namespace winrt::TerminalApp::implementation
profileMenuItem.Icon(icon);
}
if (profile.Guid() == _settings.GlobalSettings().DefaultProfile())
if (profile.Guid() == _currentWindowSettings().DefaultProfile())
{
// Contrast the default profile with others in font weight.
profileMenuItem.FontWeight(FontWeights::Bold());
@@ -1410,7 +1432,7 @@ namespace winrt::TerminalApp::implementation
if (newTerminalArgs.ProfileIndex() != nullptr)
{
// We want to promote the index to a GUID because there is no "launch to profile index" command.
const auto profile = _settings.GetProfileForArgs(newTerminalArgs);
const auto profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
if (profile)
{
newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
@@ -1441,15 +1463,6 @@ namespace winrt::TerminalApp::implementation
}
if (altPressed && !debugTap)
{
// tmux control panes don't share tab with other panes
if constexpr (Feature_TmuxControl::IsEnabled())
{
if (_tmuxControl && _tmuxControl->TabIsTmuxControl(_GetFocusedTabImpl()))
{
return;
}
}
this->_SplitPane(_GetFocusedTabImpl(),
SplitDirection::Automatic,
0.5f,
@@ -1490,7 +1503,7 @@ namespace winrt::TerminalApp::implementation
const bool inheritCursor)
{
static const auto textMeasurement = [&]() -> std::wstring_view {
switch (_settings.GlobalSettings().TextMeasurement())
switch (_currentWindowSettings().TextMeasurement())
{
case TextMeasurement::Graphemes:
return L"graphemes";
@@ -1609,7 +1622,7 @@ namespace winrt::TerminalApp::implementation
{
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
profile = GetClosestProfileForDuplicationOfProfile(profile);
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile, _currentWindowSettings());
// Replace the Starting directory with the CWD, if given
const auto workingDirectory = control.WorkingDirectory();
@@ -2246,14 +2259,14 @@ namespace winrt::TerminalApp::implementation
}
}
void TerminalPage::PersistState()
WindowLayout TerminalPage::GetWindowLayout()
{
// This method may be called for a window even if it hasn't had a tab yet or lost all of them.
// We shouldn't persist such windows.
const auto tabCount = _tabs.Size();
if (_startupState != StartupState::Initialized || tabCount == 0)
{
return;
return nullptr;
}
std::vector<ActionAndArgs> actions;
@@ -2268,7 +2281,7 @@ namespace winrt::TerminalApp::implementation
// Avoid persisting a window with zero tabs, because `BuildStartupActions` happened to return an empty vector.
if (actions.empty())
{
return;
return nullptr;
}
// if the focused tab was not the last tab, restore that
@@ -2317,7 +2330,41 @@ namespace winrt::TerminalApp::implementation
RequestLaunchPosition.raise(*this, launchPosRequest);
layout.InitialPosition(launchPosRequest.Position());
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
return layout;
}
void TerminalPage::PersistState()
{
if (const auto layout = GetWindowLayout())
{
// For named windows, save the full state into the workspace collection
// and emit a lightweight openWorkspace action in the generic layout.
// This way, restoring generic layouts re-opens workspaces by name
// rather than duplicating their full tab state.
const auto& windowName = _WindowProperties.WindowName();
if (!windowName.empty())
{
// Persist the full layout into the workspace collection.
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
// Build a minimal layout with just an openWorkspace action
// so the generic restore path re-opens this workspace by name.
std::vector<ActionAndArgs> actions;
ActionAndArgs action;
action.Action(ShortcutAction::OpenWorkspace);
OpenWorkspaceArgs args{ windowName };
action.Args(args);
actions.emplace_back(std::move(action));
WindowLayout stub;
stub.TabLayout(winrt::single_threaded_vector<ActionAndArgs>(std::move(actions)));
ApplicationState::SharedInstance().AppendPersistedWindowLayout(stub);
}
else
{
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
}
}
}
// Method Description:
@@ -2326,7 +2373,7 @@ namespace winrt::TerminalApp::implementation
safe_void_coroutine TerminalPage::CloseWindow()
{
if (_HasMultipleTabs() &&
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
_currentWindowSettings().ConfirmCloseAllTabs() &&
!_displayingCloseDialog)
{
if (_newTabButton && _newTabButton.Flyout())
@@ -2554,15 +2601,6 @@ namespace winrt::TerminalApp::implementation
return false;
}
if constexpr (Feature_TmuxControl::IsEnabled())
{
//Tmux control tab doesn't support to drag
if (_tmuxControl && _tmuxControl->TabIsTmuxControl(tab))
{
return false;
}
}
// If there was a windowId in the action, try to move it to the
// specified window instead of moving it in our tab row.
const auto windowId{ args.Window() };
@@ -2860,7 +2898,7 @@ namespace winrt::TerminalApp::implementation
// - the title of the focused control if there is one, else "Terminal"
hstring TerminalPage::Title()
{
if (_settings.GlobalSettings().ShowTitleInTitlebar())
if (_currentWindowSettings().ShowTitleInTitlebar())
{
if (const auto tab{ _GetFocusedTab() })
{
@@ -2949,7 +2987,7 @@ namespace winrt::TerminalApp::implementation
// - See Pane::CalcSnappedDimension
float TerminalPage::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
{
if (_settings && _settings.GlobalSettings().SnapToGridOnResize())
if (_settings && _currentWindowSettings().SnapToGridOnResize())
{
if (const auto tabImpl{ _GetFocusedTabImpl() })
{
@@ -2970,15 +3008,16 @@ namespace winrt::TerminalApp::implementation
// - Does some of this in a background thread, as to not hang/crash the UI thread.
// Arguments:
// - eventArgs: the PasteFromClipboard event sent from the TermControl
safe_void_coroutine TerminalPage::_PasteFromClipboardHandler(const IInspectable /*sender*/, const PasteFromClipboardEventArgs eventArgs)
safe_void_coroutine TerminalPage::_PasteFromClipboardHandler(const IInspectable sender, const PasteFromClipboardEventArgs eventArgs)
try
{
// The old Win32 clipboard API as used below is somewhere in the order of 300-1000x faster than
// the WinRT one on average, depending on CPU load. Don't use the WinRT clipboard API if you can.
const auto weakThis = get_weak();
const auto dispatcher = Dispatcher();
const auto globalSettings = _settings.GlobalSettings();
const auto windowSettings = _currentWindowSettings();
const auto bracketedPaste = eventArgs.BracketedPasteEnabled();
const auto sourceId = sender.try_as<ControlInteractivity>().Id();
// GetClipboardData might block for up to 30s for delay-rendered contents.
co_await winrt::resume_background();
@@ -2989,7 +3028,7 @@ namespace winrt::TerminalApp::implementation
text = clipboard::read();
}
if (!bracketedPaste && globalSettings.TrimPaste())
if (!bracketedPaste && windowSettings.TrimPaste())
{
text = winrt::hstring{ Utils::TrimPaste(text) };
}
@@ -3000,7 +3039,7 @@ namespace winrt::TerminalApp::implementation
}
bool warnMultiLine = false;
switch (globalSettings.WarnAboutMultiLinePaste())
switch (windowSettings.WarnAboutMultiLinePaste())
{
case WarnAboutMultiLinePaste::Automatic:
// NOTE that this is unsafe, because a shell that doesn't support bracketed paste
@@ -3023,7 +3062,7 @@ namespace winrt::TerminalApp::implementation
}
constexpr std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
const auto warnLargeText = text.size() > minimumSizeForWarning && globalSettings.WarnAboutLargePaste();
const auto warnLargeText = text.size() > minimumSizeForWarning && windowSettings.WarnAboutLargePaste();
if (warnMultiLine || warnLargeText)
{
@@ -3076,7 +3115,30 @@ namespace winrt::TerminalApp::implementation
// This will end up calling ConptyConnection::WriteInput which calls WriteFile which may block for
// an indefinite amount of time. Avoid freezes and deadlocks by running this on a background thread.
assert(!dispatcher.HasThreadAccess());
eventArgs.HandleClipboardData(std::move(text));
eventArgs.HandleClipboardData(text);
// GH#18821: If broadcast input is active, paste the same text into all other
// panes on the tab. We do this here (rather than re-reading the
// clipboard per-pane) so that only one paste warning is shown.
co_await wil::resume_foreground(dispatcher);
if (const auto strongThis = weakThis.get())
{
if (const auto& tab{ strongThis->_GetFocusedTabImpl() })
{
if (tab->TabStatus().IsInputBroadcastActive())
{
tab->GetRootPane()->WalkTree([&](auto&& pane) {
if (const auto control = pane->GetTerminalControl())
{
if (control.ContentId() != sourceId && !control.ReadOnly())
{
control.RawWriteString(text);
}
}
});
}
}
}
}
CATCH_LOG();
@@ -3345,13 +3407,13 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_WindowSizeChanged(const IInspectable sender, const Microsoft::Terminal::Control::WindowSizeChangedEventArgs args)
{
// Raise if:
// - Not in quake mode
// - Not in docked mode
// - Not in fullscreen
// - Only one tab exists
// - Only one pane exists
// else:
// - Reset conpty to its original size back
if (!WindowProperties().IsQuakeWindow() && !Fullscreen() &&
if (!_currentWindowSettings().DockWindow() && !Fullscreen() &&
NumberOfTabs() == 1 && _GetFocusedTabImpl()->GetLeafPaneCount() == 1)
{
WindowSizeChanged.raise(*this, args);
@@ -3386,24 +3448,6 @@ namespace winrt::TerminalApp::implementation
// - Paste text from the Windows Clipboard to the focused terminal
void TerminalPage::_PasteText()
{
// First, check if we're in broadcast input mode. If so, let's tell all
// the controls to paste.
if (const auto& tab{ _GetFocusedTabImpl() })
{
if (tab->TabStatus().IsInputBroadcastActive())
{
tab->GetRootPane()->WalkTree([](auto&& pane) {
if (auto control = pane->GetTerminalControl())
{
control.PasteTextFromClipboard();
}
});
return;
}
}
// The focused tab wasn't in broadcast mode. No matter. Just ask the
// current one to paste.
if (const auto& control{ _GetActiveControl() })
{
control.PasteTextFromClipboard();
@@ -3553,7 +3597,7 @@ namespace winrt::TerminalApp::implementation
{
// Don't need to worry about duplicating or anything - we'll
// serialize the actual profile's GUID along with the content guid.
const auto& profile = _settings.GetProfileForArgs(newTerminalArgs);
const auto& profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
const auto control = _AttachControlToContent(newTerminalArgs.ContentId());
auto paneContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, control) };
return std::make_shared<Pane>(paneContent);
@@ -3569,7 +3613,7 @@ namespace winrt::TerminalApp::implementation
{
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
profile = GetClosestProfileForDuplicationOfProfile(profile);
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile, _currentWindowSettings());
const auto workingDirectory = tabImpl->GetActiveTerminalControl().WorkingDirectory();
const auto validWorkingDirectory = !workingDirectory.empty();
if (validWorkingDirectory)
@@ -3580,8 +3624,8 @@ namespace winrt::TerminalApp::implementation
}
if (!profile)
{
profile = _settings.GetProfileForArgs(newTerminalArgs);
controlSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs);
profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
controlSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, _currentWindowSettings());
}
// Try to handle auto-elevation
@@ -3626,8 +3670,9 @@ namespace winrt::TerminalApp::implementation
control.RestoreFromPath(path);
}
const auto paneContent = winrt::make_self<TerminalPaneContent>(profile, _terminalSettingsCache, control);
auto resultPane = std::make_shared<Pane>(*paneContent);
auto paneContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, control) };
auto resultPane = std::make_shared<Pane>(paneContent);
if (debugConnection) // this will only be set if global debugging is on and tap is active
{
@@ -3648,28 +3693,6 @@ namespace winrt::TerminalApp::implementation
original->SetActive();
}
if constexpr (Feature_TmuxControl::IsEnabled())
{
if (!_tmuxControl)
{
_tmuxControl = std::make_shared<TmuxControl>(*this);
}
// We attach the callback to the control that paneContent owns.
// As such, using a weak-ref here is crucial.
control.EnterTmuxControl([tmuxControl = _tmuxControl.get(), paneContentWeak = winrt::make_weak(paneContent)](auto&&, auto&& args) {
if (const auto paneContent = paneContentWeak.get())
{
if (paneContent->AllowTmuxControl() && tmuxControl->AcquireSingleUseLock(paneContent->GetTermControl()))
{
args.InputCallback([tmuxControl](auto&& str) {
tmuxControl->FeedInput(winrt_array_to_wstring_view(str));
});
}
}
});
}
return resultPane;
}
@@ -3793,7 +3816,7 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalPage::_SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance)
{
if (!_settings.GlobalSettings().UseBackgroundImageForWindow())
if (!_currentWindowSettings().UseBackgroundImageForWindow())
{
_tabContent.Background(nullptr);
return;
@@ -3864,7 +3887,7 @@ namespace winrt::TerminalApp::implementation
// updating terminal panes, so that we don't have to build a _new_
// TerminalSettings for every profile we update - we can just look them
// up the previous ones we built.
_terminalSettingsCache->Reset(_settings);
_terminalSettingsCache->Reset(_settings, _currentWindowSettings());
for (const auto& tab : _tabs)
{
@@ -3902,17 +3925,23 @@ namespace winrt::TerminalApp::implementation
// Reload the current value of alwaysOnTop from the settings file. This
// will let the user hot-reload this setting, but any runtime changes to
// the alwaysOnTop setting will be lost.
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
_isAlwaysOnTop = _currentWindowSettings().AlwaysOnTop();
AlwaysOnTopChanged.raise(*this, nullptr);
_showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen();
_showTabsFullscreen = _currentWindowSettings().ShowTabsFullscreen();
// Settings AllowDependentAnimations will affect whether animations are
// enabled application-wide, so we don't need to check it each time we
// want to create an animation.
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_currentWindowSettings().DisableAnimations());
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
_tabRow.ShowElevationShield(IsRunningElevated() && _currentWindowSettings().ShowAdminShield());
// Apply the ShowWindowsButton theme setting.
if (const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()))
{
_tabRow.ShowWindowsButton(theme.Window() ? theme.Window().ShowWindowsButton() : true);
}
Media::SolidColorBrush transparent{ Windows::UI::Colors::Transparent() };
_tabView.Background(transparent);
@@ -3933,7 +3962,7 @@ namespace winrt::TerminalApp::implementation
// our TabView, to match the tab.showCloseButton property in the theme.
//
// Also update every tab's individual IsClosable to match the same property.
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
const auto visibility = (theme && theme.Tab()) ?
theme.Tab().ShowCloseButton() :
Settings::Model::TabCloseButtonVisibility::Always;
@@ -4141,12 +4170,12 @@ namespace winrt::TerminalApp::implementation
{
constexpr auto lightnessThreshold = 0.6f;
// TODO GH#3327: Look at what to do with the tab button when we have XAML theming
const auto IsBrightColor = ColorFix::GetLightness(color) >= lightnessThreshold;
const auto isBrightColor = ColorFix::GetLightness(color) >= lightnessThreshold;
const auto isLightAccentColor = ColorFix::GetLightness(accentColor) >= lightnessThreshold;
const auto hoverColorAdjustment = isLightAccentColor ? -0.05f : 0.05f;
const auto pressedColorAdjustment = isLightAccentColor ? -0.1f : 0.1f;
const auto foregroundColor = IsBrightColor ? Colors::Black() : Colors::White();
const auto foregroundColor = isBrightColor ? Colors::Black() : Colors::White();
const auto hoverColor = til::color{ ColorFix::AdjustLightness(accentColor, hoverColorAdjustment) };
const auto pressedColor = til::color{ ColorFix::AdjustLightness(accentColor, pressedColorAdjustment) };
@@ -4547,7 +4576,7 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalPage::_UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element)
{
auto theme{ _settings.GlobalSettings().CurrentTheme() };
auto theme{ _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()) };
auto requestedTheme{ theme.RequestedTheme() };
while (element)
{
@@ -4700,7 +4729,7 @@ namespace winrt::TerminalApp::implementation
{
if (profile == _settings.ProfileDefaults())
{
return _settings.FindProfile(_settings.GlobalSettings().DefaultProfile());
return _settings.FindProfile(_currentWindowSettings().DefaultProfile());
}
return profile;
}
@@ -4921,7 +4950,7 @@ namespace winrt::TerminalApp::implementation
return;
}
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
auto requestedTheme{ theme.RequestedTheme() };
{
@@ -4965,7 +4994,7 @@ namespace winrt::TerminalApp::implementation
theme.TabRow().UnfocusedBackground()) :
ThemeColor{ nullptr } };
if (_settings.GlobalSettings().UseAcrylicInTabRow() && (_activated || _settings.GlobalSettings().EnableUnfocusedAcrylic()))
if (_currentWindowSettings().UseAcrylicInTabRow())
{
if (tabRowBg)
{
@@ -4995,7 +5024,7 @@ namespace winrt::TerminalApp::implementation
TitlebarBrush(backgroundSolidBrush);
}
if (!_settings.GlobalSettings().ShowTabsInTitlebar())
if (!_currentWindowSettings().ShowTabsInTitlebar())
{
_tabRow.Background(TitlebarBrush());
}
@@ -5231,7 +5260,7 @@ namespace winrt::TerminalApp::implementation
// Feature_ShellCompletions::IsEnabled back in _RegisterTerminalEvents
// User must explicitly opt-in on Preview builds
if (!_settings.GlobalSettings().EnableShellCompletionMenu())
if (!_currentWindowSettings().EnableShellCompletionMenu())
{
co_return;
}
@@ -5554,6 +5583,199 @@ namespace winrt::TerminalApp::implementation
}
}
// Rebuild the workspace flyout contents. Called every time the flyout opens
// so it reflects the current set of persisted workspaces.
void TerminalPage::_PopulateWorkspaceFlyout()
{
if (!_workspaceFlyout)
{
return;
}
_workspaceFlyout.Items().Clear();
// --- "Name / Rename this window" ---
{
MenuFlyoutItem item{};
item.Text(winrt::hstring{ _WindowProperties.WindowName().empty() ? L"Name this window\u2026" : L"Rename this window\u2026" });
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE8AC"); // Rename glyph
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
item.Icon(iconElement);
item.Click([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
// Re-use the existing openWindowRenamer action.
page->_actionDispatch->DoAction(ActionAndArgs{ ShortcutAction::OpenWindowRenamer, nullptr });
}
});
_workspaceFlyout.Items().Append(item);
}
// --- "Save workspace" ---
{
MenuFlyoutItem item{};
item.Text(winrt::hstring{ L"Save workspace" });
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE74E"); // Save glyph
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
item.Icon(iconElement);
// Only enable if the window has a name.
item.IsEnabled(!_WindowProperties.WindowName().empty());
item.Click([weakThis{ get_weak() }](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
page->_actionDispatch->DoAction(ActionAndArgs{ ShortcutAction::SaveWorkspace, nullptr });
}
});
_workspaceFlyout.Items().Append(item);
}
// --- Gather open window info first so we can filter workspaces ---
// Ask the host (via AppHost → WindowEmperor) for all live windows.
const auto windowListReq{ winrt::make<WindowListRequest>() };
RequestWindowList.raise(*this, windowListReq);
const auto windowEntries = windowListReq.WindowEntries();
// Collect the names of all currently-open windows so we can hide
// workspaces that are already live from the saved-workspaces list.
std::set<winrt::hstring> openWindowNames;
if (windowEntries)
{
for (const auto& entry : windowEntries)
{
const std::wstring_view entryView{ entry };
const auto tabPos = entryView.find(L'\t');
if (tabPos != std::wstring_view::npos)
{
const auto namePart = entryView.substr(tabPos + 1);
if (!namePart.empty())
{
openWindowNames.emplace(namePart);
}
}
}
}
// --- Saved workspaces section (only those not currently open) ---
const auto workspaces = ApplicationState::SharedInstance().AllPersistedWorkspaces();
if (workspaces && workspaces.Size() > 0)
{
bool addedSeparator = false;
for (const auto& pair : workspaces)
{
const auto name = pair.Key();
// Skip workspaces that correspond to a currently-open window.
if (openWindowNames.count(name))
{
continue;
}
if (!addedSeparator)
{
_workspaceFlyout.Items().Append(MenuFlyoutSeparator{});
addedSeparator = true;
}
MenuFlyoutItem item{};
item.Text(name);
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE8F1"); // SwitchApps glyph
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
item.Icon(iconElement);
item.Click([weakThis{ get_weak() }, name](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
page->_OpenWorkspaceWindow(name);
}
});
_workspaceFlyout.Items().Append(item);
}
}
// --- Open windows section ---
if (windowEntries && windowEntries.Size() > 0)
{
_workspaceFlyout.Items().Append(MenuFlyoutSeparator{});
const auto thisWindowId = _WindowProperties.WindowId();
for (const auto& entry : windowEntries)
{
// Each entry is formatted as "id\tname"
const std::wstring_view entryView{ entry };
const auto tabPos = entryView.find(L'\t');
if (tabPos == std::wstring_view::npos)
{
continue;
}
uint64_t id = 0;
const auto idPart = entryView.substr(0, tabPos);
for (const auto ch : idPart)
{
if (ch >= L'0' && ch <= L'9')
{
id = id * 10 + (ch - L'0');
}
}
const auto namePart = entryView.substr(tabPos + 1);
// Build display text like "#1: MyWindow" or "#2: <unnamed>"
winrt::hstring displayText;
if (namePart.empty())
{
displayText = winrt::hstring{ fmt::format(FMT_COMPILE(L"#{} (unnamed)"), id) };
}
else
{
displayText = winrt::hstring{ fmt::format(FMT_COMPILE(L"#{}: {}"), id, namePart) };
}
MenuFlyoutItem item{};
item.Text(displayText);
// Use a different glyph for the current window
if (id == thisWindowId)
{
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE73E"); // CheckMark glyph
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
item.Icon(iconElement);
item.IsEnabled(false); // Can't summon yourself
}
else
{
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE737"); // ChromeRestore glyph
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
item.Icon(iconElement);
// Click handler: summon the target window by ID.
// We raise SummonWindowByIdRequested which is handled by
// AppHost to directly summon the window without creating
// a new tab (unlike _OpenWorkspaceWindow which launches
// `wt -w <name>` and creates a tab).
item.Click([weakThis{ get_weak() }, id](auto&&, auto&&) {
if (auto page{ weakThis.get() })
{
page->SummonWindowByIdRequested.raise(*page, winrt::make<SummonWindowByIdRequestedArgs>(id));
}
});
}
_workspaceFlyout.Items().Append(item);
}
}
}
// Handler for our WindowProperties's PropertyChanged event. We'll use this
// to pop the "Identify Window" toast when the user renames our window.
void TerminalPage::_windowPropertyChanged(const IInspectable& /*sender*/, const WUX::Data::PropertyChangedEventArgs& args)
@@ -5563,6 +5785,10 @@ namespace winrt::TerminalApp::implementation
return;
}
// Keep the workspace dropdown label in sync with the window name.
// Use raw WindowName() so clearing the name hides the text.
_tabRow.WorkspaceName(_WindowProperties.WindowName());
// DON'T display the confirmation if this is the name we were
// given on startup!
if (_startupState == StartupState::Initialized)
@@ -5581,15 +5807,6 @@ namespace winrt::TerminalApp::implementation
tabImpl.copy_from(winrt::get_self<Tab>(tabBase));
if (tabImpl)
{
if constexpr (Feature_TmuxControl::IsEnabled())
{
//Tmux control tab doesn't support to drag
if (_tmuxControl && _tmuxControl->TabIsTmuxControl(tabImpl))
{
return;
}
}
// First: stash the tab we started dragging.
// We're going to be asked for this.
_stashed.draggedTab = tabImpl;

View File

@@ -10,8 +10,10 @@
#include "AppKeyBindings.h"
#include "AppCommandlineArgs.h"
#include "RenameWindowRequestedArgs.g.h"
#include "SummonWindowByIdRequestedArgs.g.h"
#include "RequestMoveContentArgs.g.h"
#include "LaunchPositionRequest.g.h"
#include "WindowListRequest.g.h"
#include "Toast.h"
#include "WindowsPackageManagerFactory.h"
@@ -37,7 +39,6 @@ namespace winrt::Microsoft::Terminal::Settings
namespace winrt::TerminalApp::implementation
{
struct TerminalSettingsCache;
struct TmuxControl;
inline constexpr uint32_t DefaultRowsToScroll{ 3 };
inline constexpr std::wstring_view TabletInputServiceKey{ L"TabletInputService" };
@@ -64,6 +65,15 @@ namespace winrt::TerminalApp::implementation
_ProposedName{ name } {};
};
struct SummonWindowByIdRequestedArgs : SummonWindowByIdRequestedArgsT<SummonWindowByIdRequestedArgs>
{
WINRT_PROPERTY(uint64_t, WindowId);
public:
SummonWindowByIdRequestedArgs(uint64_t id) :
_WindowId{ id } {};
};
struct RequestMoveContentArgs : RequestMoveContentArgsT<RequestMoveContentArgs>
{
WINRT_PROPERTY(winrt::hstring, Window);
@@ -85,6 +95,17 @@ namespace winrt::TerminalApp::implementation
til::property<winrt::Microsoft::Terminal::Settings::Model::LaunchPosition> Position;
};
struct WindowListRequest : WindowListRequestT<WindowListRequest>
{
WindowListRequest() :
_WindowEntries{ winrt::single_threaded_vector<winrt::hstring>() } {}
winrt::Windows::Foundation::Collections::IVector<winrt::hstring> WindowEntries() const { return _WindowEntries; }
private:
winrt::Windows::Foundation::Collections::IVector<winrt::hstring> _WindowEntries;
};
struct WinGetSearchParams
{
winrt::Microsoft::Management::Deployment::PackageMatchField Field;
@@ -123,6 +144,7 @@ namespace winrt::TerminalApp::implementation
safe_void_coroutine RequestQuit();
safe_void_coroutine CloseWindow();
winrt::Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
void PersistState();
std::vector<IPaneContent> Panes() const;
@@ -193,6 +215,7 @@ namespace winrt::TerminalApp::implementation
til::typed_event<IInspectable, IInspectable> IdentifyWindowsRequested;
til::typed_event<IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs> RenameWindowRequested;
til::typed_event<IInspectable, IInspectable> SummonWindowRequested;
til::typed_event<IInspectable, winrt::TerminalApp::SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs> WindowSizeChanged;
til::typed_event<IInspectable, IInspectable> OpenSystemMenu;
@@ -204,6 +227,7 @@ namespace winrt::TerminalApp::implementation
til::typed_event<Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs> RequestReceiveContent;
til::typed_event<IInspectable, winrt::TerminalApp::LaunchPositionRequest> RequestLaunchPosition;
til::typed_event<IInspectable, winrt::TerminalApp::WindowListRequest> RequestWindowList;
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, TitlebarBrush, PropertyChanged.raise, nullptr);
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, FrameBrush, PropertyChanged.raise, nullptr);
@@ -226,6 +250,7 @@ namespace winrt::TerminalApp::implementation
TerminalApp::TabRowControl _tabRow{ nullptr };
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
Microsoft::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr };
Windows::UI::Xaml::Controls::MenuFlyout _workspaceFlyout{ nullptr };
winrt::TerminalApp::ColorPickupFlyout _tabColorPicker{ nullptr };
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
@@ -257,7 +282,6 @@ namespace winrt::TerminalApp::implementation
std::vector<std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>> _previouslyClosedPanesAndTabs{};
uint32_t _systemRowsToScroll{ DefaultRowsToScroll };
std::shared_ptr<TmuxControl> _tmuxControl{ nullptr };
// use a weak reference to prevent circular dependency with AppLogic
winrt::weak_ref<winrt::TerminalApp::IDialogPresenter> _dialogPresenter;
@@ -285,6 +309,8 @@ namespace winrt::TerminalApp::implementation
TerminalApp::ContentManager _manager{ nullptr };
Microsoft::Terminal::Settings::Model::WindowSettings _currentWindowSettings() const;
std::shared_ptr<TerminalSettingsCache> _terminalSettingsCache{};
struct StashedDragData
@@ -326,6 +352,7 @@ namespace winrt::TerminalApp::implementation
void _restartPaneConnection(const TerminalApp::TerminalPaneContent&, const winrt::Windows::Foundation::IInspectable&);
safe_void_coroutine _OpenNewWindow(const Microsoft::Terminal::Settings::Model::INewContentArgs newContentArgs);
safe_void_coroutine _OpenWorkspaceWindow(const winrt::hstring name);
void _OpenNewTerminalViaDropdown(const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
@@ -564,6 +591,7 @@ namespace winrt::TerminalApp::implementation
void _PopulateContextMenu(const Microsoft::Terminal::Control::TermControl& control, const Microsoft::UI::Xaml::Controls::CommandBarFlyout& sender, const bool withSelection);
void _PopulateQuickFixMenu(const Microsoft::Terminal::Control::TermControl& control, const Windows::UI::Xaml::Controls::MenuFlyout& sender);
void _PopulateWorkspaceFlyout();
winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex);
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
@@ -582,7 +610,6 @@ namespace winrt::TerminalApp::implementation
friend class TerminalAppLocalTests::TabTests;
friend class TerminalAppLocalTests::SettingsTests;
friend struct TmuxControl;
};
}

View File

@@ -19,6 +19,10 @@ namespace TerminalApp
{
String ProposedName { get; };
};
[default_interface] runtimeclass SummonWindowByIdRequestedArgs
{
UInt64 WindowId { get; };
};
[default_interface] runtimeclass RequestMoveContentArgs
{
String Window { get; };
@@ -41,8 +45,6 @@ namespace TerminalApp
String VirtualWorkingDirectory { get; set; };
String VirtualEnvVars { get; set; };
Boolean IsQuakeWindow();
};
runtimeclass LaunchPositionRequest
@@ -50,6 +52,14 @@ namespace TerminalApp
Microsoft.Terminal.Settings.Model.LaunchPosition Position;
}
// Raised by TerminalPage when it needs the list of open windows.
// The handler (AppHost) fills WindowNames synchronously.
[default_interface] runtimeclass WindowListRequest
{
// Each entry is "id\tname" (name may be empty for unnamed windows).
Windows.Foundation.Collections.IVector<String> WindowEntries { get; };
}
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
TerminalPage(WindowProperties properties, ContentManager manager);
@@ -93,6 +103,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.WindowSizeChangedEventArgs> WindowSizeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
@@ -103,5 +114,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;
event Windows.Foundation.TypedEventHandler<Object, LaunchPositionRequest> RequestLaunchPosition;
event Windows.Foundation.TypedEventHandler<Object, WindowListRequest> RequestWindowList;
}
}

View File

@@ -27,7 +27,6 @@ namespace winrt::TerminalApp::implementation
_cache{ cache },
_profile{ profile }
{
_allowTmuxControl.store(_profile.AllowTmuxControl(), std::memory_order_relaxed);
_setupControlEvents();
}
@@ -343,7 +342,6 @@ namespace winrt::TerminalApp::implementation
// Reload our profile from the settings model to propagate bell mode, icon, and close on exit mode (anything that uses _profile).
const auto profile{ settings.FindProfile(_profile.Guid()) };
_profile = profile ? profile : settings.ProfileDefaults();
_allowTmuxControl.store(_profile.AllowTmuxControl(), std::memory_order_relaxed);
if (const auto settings{ _cache->TryLookup(_profile) })
{
@@ -365,11 +363,6 @@ namespace winrt::TerminalApp::implementation
return _control.BackgroundBrush();
}
bool TerminalPaneContent::AllowTmuxControl() const noexcept
{
return _allowTmuxControl.load(std::memory_order_relaxed);
}
float TerminalPaneContent::SnapDownToGrid(const TerminalApp::PaneSnapDirection direction, const float sizeToSnap)
{
return _control.SnapDimensionToGrid(direction == PaneSnapDirection::Width, sizeToSnap);

View File

@@ -49,7 +49,6 @@ namespace winrt::TerminalApp::implementation
winrt::hstring Icon() const;
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept;
winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush();
bool AllowTmuxControl() const noexcept;
float SnapDownToGrid(const TerminalApp::PaneSnapDirection direction, const float sizeToSnap);
Windows::Foundation::Size GridUnitSize();
@@ -64,13 +63,6 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
std::shared_ptr<TerminalSettingsCache> _cache{};
bool _isDefTermSession{ false };
// Settings, UI, etc., handling occurs on the main thread.
// The EnterTmuxControl callback on the other hand occurs on the VT connection thread.
// In order to avoid threading issues, we cache the value of AllowTmuxControl here.
// The reason it's stored here and not elsewhere is because right now all decision making
// about tmux occurs at the TerminalPage (= window) layer of the app. It would not make sense
// to expose it on the IControlSettings object. TerminalPaneContent is the closest thing to it.
std::atomic<bool> _allowTmuxControl{ false };
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
bool _bellPlayerCreated{ false };

View File

@@ -18,9 +18,9 @@ namespace winrt::TerminalApp::implementation
result.UnfocusedSettings().try_as(_unfocusedSettings);
}
TerminalSettingsCache::TerminalSettingsCache(const MTSM::CascadiaSettings& settings)
TerminalSettingsCache::TerminalSettingsCache(const MTSM::CascadiaSettings& settings, const MTSM::WindowSettings& windowSettings)
{
Reset(settings);
Reset(settings, windowSettings);
}
std::optional<TerminalSettingsPair> TerminalSettingsCache::TryLookup(const MTSM::Profile& profile)
@@ -35,7 +35,7 @@ namespace winrt::TerminalApp::implementation
auto& pair{ found->second };
if (!pair.second)
{
pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first);
pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first, _windowSettings);
}
return std::optional{ TerminalSettingsPair{ *pair.second } };
}
@@ -43,9 +43,10 @@ namespace winrt::TerminalApp::implementation
return std::nullopt;
}
void TerminalSettingsCache::Reset(const MTSM::CascadiaSettings& settings)
void TerminalSettingsCache::Reset(const MTSM::CascadiaSettings& settings, const MTSM::WindowSettings& windowSettings)
{
_settings = settings;
_windowSettings = windowSettings;
// Mapping by GUID isn't _excellent_ because the defaults profile doesn't have a stable GUID; however,
// when we stabilize its guid this will become fully safe.

View File

@@ -38,12 +38,13 @@ namespace winrt::TerminalApp::implementation
struct TerminalSettingsCache
{
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
std::optional<TerminalSettingsPair> TryLookup(const Microsoft::Terminal::Settings::Model::Profile& profile);
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
private:
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
Microsoft::Terminal::Settings::Model::WindowSettings _windowSettings{ nullptr };
std::unordered_map<winrt::guid, std::pair<Microsoft::Terminal::Settings::Model::Profile, std::optional<winrt::Microsoft::Terminal::Settings::TerminalSettingsCreateResult>>> profileGuidSettingsMap;
};
}

View File

@@ -232,7 +232,7 @@ namespace winrt::TerminalApp::implementation
// that the window size is _first_ set up as something sensible, so
// leaving fullscreen returns to a reasonable size.
const auto launchMode = this->GetLaunchMode();
if (_WindowProperties->IsQuakeWindow() || WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
if (WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
{
_root->SetFocusMode(true);
}
@@ -244,7 +244,7 @@ namespace winrt::TerminalApp::implementation
_root->Maximized(true);
}
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode) && !_WindowProperties->IsQuakeWindow())
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode))
{
_root->SetFullscreen(true);
}
@@ -252,6 +252,15 @@ namespace winrt::TerminalApp::implementation
AppLogic::Current()->NotifyRootInitialized();
}
WindowLayout TerminalWindow::GetWindowLayout()
{
if (_root)
{
return _root->GetWindowLayout();
}
return nullptr;
}
void TerminalWindow::PersistState()
{
if (_root)
@@ -267,22 +276,22 @@ namespace winrt::TerminalApp::implementation
bool TerminalWindow::GetShowTabsInTitlebar()
{
return _settings.GlobalSettings().ShowTabsInTitlebar();
return _currentWindowSettings().ShowTabsInTitlebar();
}
bool TerminalWindow::GetInitialAlwaysOnTop()
{
return _settings.GlobalSettings().AlwaysOnTop();
return _currentWindowSettings().AlwaysOnTop();
}
bool TerminalWindow::GetInitialShowTabsFullscreen()
{
return _settings.GlobalSettings().ShowTabsFullscreen();
return _currentWindowSettings().ShowTabsFullscreen();
}
bool TerminalWindow::GetMinimizeToNotificationArea()
{
return _settings.GlobalSettings().MinimizeToNotificationArea();
return _currentWindowSettings().MinimizeToNotificationArea();
}
bool TerminalWindow::GetAlwaysShowNotificationIcon()
@@ -292,12 +301,12 @@ namespace winrt::TerminalApp::implementation
bool TerminalWindow::GetShowTitleInTitlebar()
{
return _settings.GlobalSettings().ShowTitleInTitlebar();
return _currentWindowSettings().ShowTitleInTitlebar();
}
Microsoft::Terminal::Settings::Model::Theme TerminalWindow::Theme()
{
return _settings.GlobalSettings().CurrentTheme();
return _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
}
// WinUI can't show 2 dialogs simultaneously. Yes, really. If you do, you get an exception.
@@ -374,7 +383,7 @@ namespace winrt::TerminalApp::implementation
auto themingLambda{ [weak](const Windows::Foundation::IInspectable& sender, const RoutedEventArgs&) {
if (const auto strong = weak.get())
{
auto theme{ strong->_settings.GlobalSettings().CurrentTheme() };
auto theme{ strong->_settings.GlobalSettings().CurrentTheme(strong->_currentWindowSettings()) };
auto requestedTheme{ theme.RequestedTheme() };
auto element{ sender.try_as<winrt::Windows::UI::Xaml::FrameworkElement>() };
while (element)
@@ -598,7 +607,7 @@ namespace winrt::TerminalApp::implementation
// --focusMode on the commandline here, and the mode in the settings.
// Below, we'll also account for if focus mode was persisted into the
// session for restoration.
bool focusMode = _appArgs && _appArgs->ParsedArgs().GetLaunchMode().value_or(_settings.GlobalSettings().LaunchMode()) == LaunchMode::FocusMode;
bool focusMode = _appArgs && _appArgs->ParsedArgs().GetLaunchMode().value_or(_currentWindowSettings().LaunchMode()) == LaunchMode::FocusMode;
const auto scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
if (const auto layout = LoadPersistedLayout())
@@ -621,7 +630,7 @@ namespace winrt::TerminalApp::implementation
if ((_appArgs && _appArgs->ParsedArgs().GetSize().has_value()) || (proposedSize.Width == 0 && proposedSize.Height == 0))
{
// Use the default profile to determine how big of a window we need.
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr) };
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr, _currentWindowSettings()) };
const til::size emptySize{};
const auto commandlineSize = _appArgs ? _appArgs->ParsedArgs().GetSize().value_or(emptySize) : til::size{};
@@ -645,7 +654,7 @@ namespace winrt::TerminalApp::implementation
// GH#2061 - If the global setting "Always show tab bar" is
// set or if "Show tabs in title bar" is set, then we'll need to add
// the height of the tab bar here.
if (_settings.GlobalSettings().ShowTabsInTitlebar() && !focusMode)
if (_currentWindowSettings().ShowTabsInTitlebar() && !focusMode)
{
// In the past, we used to actually instantiate a TitlebarControl
// and use Measure() to determine the DesiredSize of the control, to
@@ -663,7 +672,7 @@ namespace winrt::TerminalApp::implementation
static constexpr auto titlebarHeight = 40;
proposedSize.Height += (titlebarHeight)*scale;
}
else if (_settings.GlobalSettings().AlwaysShowTabs() && !focusMode)
else if (_currentWindowSettings().AlwaysShowTabs() && !focusMode)
{
// Same comment as above, but with a TabRowControl.
//
@@ -696,7 +705,7 @@ namespace winrt::TerminalApp::implementation
// GH#4620/#5801 - If the user passed --maximized or --fullscreen on the
// commandline, then use that to override the value from the settings.
const auto valueFromSettings = _settings.GlobalSettings().LaunchMode();
const auto valueFromSettings = _currentWindowSettings().LaunchMode();
const auto valueFromCommandlineArgs = _appArgs ? _appArgs->ParsedArgs().GetLaunchMode() : std::nullopt;
if (const auto layout = LoadPersistedLayout())
{
@@ -722,7 +731,7 @@ namespace winrt::TerminalApp::implementation
// - a point containing the requested initial position in pixels.
TerminalApp::InitialPosition TerminalWindow::GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY)
{
auto initialPosition{ _settings.GlobalSettings().InitialPosition() };
auto initialPosition{ _currentWindowSettings().InitialPosition() };
if (const auto layout = LoadPersistedLayout())
{
@@ -770,10 +779,15 @@ namespace winrt::TerminalApp::implementation
return !_contentBounds &&
!hadPersistedPosition &&
_settings.GlobalSettings().CenterOnLaunch() &&
_currentWindowSettings().CenterOnLaunch() &&
(_appArgs && !_appArgs->ParsedArgs().GetPosition().has_value());
}
Microsoft::Terminal::Settings::Model::Docking TerminalWindow::Docking()
{
return _currentWindowSettings().DockWindow();
}
// Method Description:
// - See Pane::CalcSnappedDimension
float TerminalWindow::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
@@ -1097,6 +1111,11 @@ namespace winrt::TerminalApp::implementation
_initialContentArgs = wil::to_vector(args);
}
void TerminalWindow::SetPersistedLayout(const winrt::Microsoft::Terminal::Settings::Model::WindowLayout& layout)
{
_cachedLayout = layout;
}
// Method Description:
// - Parse the provided commandline arguments into actions, and try to
// perform them immediately.
@@ -1188,7 +1207,7 @@ namespace winrt::TerminalApp::implementation
bool TerminalWindow::AutoHideWindow()
{
return _settings.GlobalSettings().AutoHideWindow();
return _currentWindowSettings().AutoHideWindow();
}
void TerminalWindow::UpdateSettingsHandler(const winrt::IInspectable& /*sender*/,
@@ -1207,21 +1226,22 @@ namespace winrt::TerminalApp::implementation
void TerminalWindow::WindowName(const winrt::hstring& name)
{
const auto oldIsQuakeMode = _WindowProperties->IsQuakeWindow();
const auto oldName = _WindowProperties->WindowName();
_WindowProperties->WindowName(name);
if (!_root)
if (!_root || oldName == name)
{
return;
}
const auto newIsQuakeMode = _WindowProperties->IsQuakeWindow();
if (newIsQuakeMode != oldIsQuakeMode)
{
// If we're entering Quake Mode from ~Focus Mode, then this will enter Focus Mode
// If we're entering Quake Mode from Focus Mode, then this will do nothing
// If we're leaving Quake Mode (we're already in Focus Mode), then this will do nothing
_root->SetFocusMode(true);
IsQuakeWindowChanged.raise(*this, nullptr);
}
// The window name determines which WindowSettings we use
// (via _currentWindowSettings()). Since it changed, refresh
// all downstream consumers of per-window settings:
// - TerminalPage (settings cache, tab/pane settings)
// - Theme (may differ per window)
// - Docking & host-level properties (via IsQuakeWindowChanged -> AppHost)
_root->SetSettings(_settings, true);
_RefreshThemeRoutine();
IsQuakeWindowChanged.raise(*this, nullptr);
}
void TerminalWindow::WindowId(const uint64_t& id)
{
@@ -1332,13 +1352,13 @@ namespace winrt::TerminalApp::implementation
if (!FocusMode())
{
if (!_settings.GlobalSettings().AlwaysShowTabs())
if (!_currentWindowSettings().AlwaysShowTabs())
{
// Hide the title bar = off, Always show tabs = off.
static constexpr auto titlebarHeight = 10;
pixelSize.Height += (titlebarHeight)*scale;
}
else if (!_settings.GlobalSettings().ShowTabsInTitlebar())
else if (!_currentWindowSettings().ShowTabsInTitlebar())
{
// Hide the title bar = off, Always show tabs = on.
static constexpr auto titlebarAndTabBarHeight = 40;
@@ -1419,9 +1439,9 @@ namespace winrt::TerminalApp::implementation
return _WindowName.empty() ? til::hstring_format(FMT_COMPILE(L"<{}>"), RS_(L"UnnamedWindowName")) : _WindowName;
}
bool WindowProperties::IsQuakeWindow() const noexcept
WindowSettings TerminalWindow::_currentWindowSettings() const
{
return _WindowName == L"_quake";
return _settings.WindowSettings(_WindowProperties->WindowName());
}
};

View File

@@ -44,7 +44,6 @@ namespace winrt::TerminalApp::implementation
void WindowId(const uint64_t& value);
winrt::hstring WindowIdForDisplay() const noexcept;
winrt::hstring WindowNameForDisplay() const noexcept;
bool IsQuakeWindow() const noexcept;
til::property_changed_event PropertyChanged;
@@ -71,6 +70,7 @@ namespace winrt::TerminalApp::implementation
void Create();
winrt::Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
void PersistState();
void UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args);
@@ -79,6 +79,7 @@ namespace winrt::TerminalApp::implementation
int32_t SetStartupCommandline(TerminalApp::CommandlineArgs args);
void SetStartupContent(const winrt::hstring& content, const Windows::Foundation::IReference<Windows::Foundation::Rect>& contentBounds);
void SetPersistedLayout(const winrt::Microsoft::Terminal::Settings::Model::WindowLayout& layout);
int32_t ExecuteCommandline(TerminalApp::CommandlineArgs args);
void SetSettingsStartupArgs(const std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);
@@ -134,12 +135,12 @@ namespace winrt::TerminalApp::implementation
void DismissDialog();
Microsoft::Terminal::Settings::Model::Theme Theme();
Microsoft::Terminal::Settings::Model::Docking Docking();
void UpdateSettingsHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::SettingsLoadEventArgs& arg);
void WindowName(const winrt::hstring& value);
void WindowId(const uint64_t& value);
bool IsQuakeWindow() const noexcept { return _WindowProperties->IsQuakeWindow(); }
TerminalApp::WindowProperties WindowProperties() { return *_WindowProperties; }
void AttachContent(winrt::hstring content, uint32_t tabIndex);
@@ -187,6 +188,8 @@ namespace winrt::TerminalApp::implementation
TerminalApp::ContentManager _manager{ nullptr };
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> _initialContentArgs;
Microsoft::Terminal::Settings::Model::WindowSettings _currentWindowSettings() const;
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey,
const winrt::hstring& contentKey,
HRESULT settingsLoadedResult,
@@ -221,6 +224,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
FORWARDED_TYPED_EVENT(SummonWindowByIdRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::SummonWindowByIdRequestedArgs, _root, SummonWindowByIdRequested);
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
FORWARDED_TYPED_EVENT(ShowWindowChanged, Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs, _root, ShowWindowChanged);
@@ -229,6 +233,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(RequestReceiveContent, Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs, _root, RequestReceiveContent);
FORWARDED_TYPED_EVENT(RequestLaunchPosition, Windows::Foundation::IInspectable, winrt::TerminalApp::LaunchPositionRequest, _root, RequestLaunchPosition);
FORWARDED_TYPED_EVENT(RequestWindowList, Windows::Foundation::IInspectable, winrt::TerminalApp::WindowListRequest, _root, RequestWindowList);
#ifdef UNIT_TESTING
friend class TerminalAppLocalTests::CommandlineTest;

View File

@@ -55,11 +55,13 @@ namespace TerminalApp
Int32 SetStartupCommandline(CommandlineArgs args);
void SetStartupContent(String json, Windows.Foundation.IReference<Windows.Foundation.Rect> bounds);
void SetPersistedLayout(Microsoft.Terminal.Settings.Model.WindowLayout layout);
Int32 ExecuteCommandline(CommandlineArgs args);
Boolean ShouldImmediatelyHandoffToElevated();
void HandoffToElevated();
Microsoft.Terminal.Settings.Model.WindowLayout GetWindowLayout();
void PersistState();
Windows.UI.Xaml.UIElement GetRoot();
@@ -72,6 +74,8 @@ namespace TerminalApp
Boolean AlwaysOnTop { get; };
Boolean AutoHideWindow { get; };
Boolean ShowTabsFullscreen { get; };
Microsoft.Terminal.Settings.Model.Theme Theme { get; };
Microsoft.Terminal.Settings.Model.Docking Docking { get; };
void IdentifyWindow();
void SetPersistedLayoutIdx(UInt32 idx);
@@ -105,7 +109,6 @@ namespace TerminalApp
WindowProperties WindowProperties { get; };
void WindowName(String name);
void WindowId(UInt64 id);
Boolean IsQuakeWindow();
// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.
@@ -126,6 +129,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.SystemMenuChangeArgs> SystemMenuChangeRequested;
@@ -137,6 +141,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, RequestMoveContentArgs> RequestMoveContent;
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;
event Windows.Foundation.TypedEventHandler<Object, LaunchPositionRequest> RequestLaunchPosition;
event Windows.Foundation.TypedEventHandler<Object, WindowListRequest> RequestWindowList;
void AttachContent(String content, UInt32 tabIndex);
void SendContentToOther(RequestReceiveContentArgs args);

View File

@@ -53,6 +53,16 @@ namespace winrt::TerminalApp::implementation
return static_cast<float>(minMaxCloseWidth) / 3.0f;
}
bool TitlebarControl::Focused()
{
return MinMaxCloseControl().Focused();
}
void TitlebarControl::Focused(bool focused)
{
MinMaxCloseControl().Focused(focused);
}
IInspectable TitlebarControl::Content()
{
return ContentRoot().Content();

View File

@@ -17,6 +17,9 @@ namespace winrt::TerminalApp::implementation
void ReleaseButtons();
float CaptionButtonWidth();
bool Focused();
void Focused(bool focused);
IInspectable Content();
void Content(IInspectable content);

View File

@@ -29,6 +29,7 @@ namespace TerminalApp
void ClickButton(CaptionButton button);
void ReleaseButtons();
Single CaptionButtonWidth { get; };
Boolean Focused { get; set; };
IInspectable Content;
Windows.UI.Xaml.Controls.Border DragBar { get; };

View File

@@ -1,48 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "TmuxConnection.h"
namespace winrt::TerminalApp::implementation
{
void TmuxConnection::Initialize(const Windows::Foundation::Collections::ValueSet&) const noexcept
{
}
void TmuxConnection::Start() noexcept
{
}
void TmuxConnection::WriteInput(const winrt::array_view<const char16_t> buffer)
{
TerminalInput.raise(buffer);
}
void TmuxConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
{
}
void TmuxConnection::Close() noexcept
{
StateChanged.raise(*this, nullptr);
}
winrt::guid TmuxConnection::SessionId() const noexcept
{
return {};
}
Microsoft::Terminal::TerminalConnection::ConnectionState TmuxConnection::State() const noexcept
{
return Microsoft::Terminal::TerminalConnection::ConnectionState::Connected;
}
void TmuxConnection::WriteOutput(const winrt::array_view<const char16_t> wstr)
{
if (!wstr.empty())
{
TerminalOutput.raise(wstr);
}
}
}

View File

@@ -1,31 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
namespace winrt::TerminalApp::implementation
{
struct TmuxConnection : winrt::implements<TmuxConnection, Microsoft::Terminal::TerminalConnection::ITerminalConnection>
{
// ITerminalConnection methods
void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) const noexcept;
void Start() noexcept;
void WriteInput(winrt::array_view<const char16_t> buffer);
void Resize(uint32_t rows, uint32_t columns) noexcept;
void Close() noexcept;
til::event<Microsoft::Terminal::TerminalConnection::TerminalOutputHandler> TerminalOutput;
til::typed_event<Microsoft::Terminal::TerminalConnection::ITerminalConnection, IInspectable> StateChanged;
winrt::guid SessionId() const noexcept;
Microsoft::Terminal::TerminalConnection::ConnectionState State() const noexcept;
// TmuxConnection methods
void WriteOutput(winrt::array_view<const char16_t> wstr);
til::event<Microsoft::Terminal::TerminalConnection::TerminalOutputHandler> TerminalInput;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,180 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
class Pane;
namespace winrt::TerminalApp::implementation
{
struct Tab;
struct TerminalPage;
struct TmuxConnection;
struct TmuxControl : std::enable_shared_from_this<TmuxControl>
{
TmuxControl(TerminalPage& page);
bool AcquireSingleUseLock(winrt::Microsoft::Terminal::Control::TermControl control) noexcept;
bool TabIsTmuxControl(const winrt::com_ptr<Tab>& tab);
void SplitPane(const winrt::com_ptr<Tab>& tab, winrt::Microsoft::Terminal::Settings::Model::SplitDirection direction);
void FeedInput(std::wstring_view str);
private:
enum class State
{
Init,
Attaching,
Attached,
};
enum class ResponseInfoType
{
Ignore,
DiscoverNewWindow,
DiscoverWindows,
CapturePane,
DiscoverPanes,
};
struct ResponseInfo
{
ResponseInfoType type;
union
{
struct
{
int64_t paneId;
} capturePane;
} data;
};
enum class TmuxLayoutType
{
// A single leaf pane
Pane,
// Indicates the start of a horizontal split layout
PushHorizontal,
// Indicates the start of a vertical split layout
PushVertical,
// Indicates the end of the most recent split layout
Pop,
};
struct TmuxLayout
{
TmuxLayoutType type = TmuxLayoutType::Pane;
// Only set for: Pane, PushHorizontal, PushVertical
til::CoordType width = 0;
// Only set for: Pane, PushHorizontal, PushVertical
til::CoordType height = 0;
// Only set for: Pane
int64_t id = -1;
};
struct AttachedPane
{
AttachedPane() = default;
AttachedPane(int64_t paneId, std::wstring outputBacklog);
~AttachedPane();
// Have to redefine them because they get implicitly deleted once a destructor is defined.
AttachedPane(AttachedPane&&) = default;
AttachedPane& operator=(AttachedPane&&) = default;
// Why would you want to copy this.
AttachedPane(const AttachedPane&) = delete;
AttachedPane& operator=(const AttachedPane&) = delete;
int64_t windowId = -1;
int64_t paneId = -1;
winrt::com_ptr<TmuxConnection> connection{ nullptr };
winrt::Microsoft::Terminal::Control::TermControl control{ nullptr };
std::wstring outputBacklog;
bool initialized = false;
bool ignoreOutput = false;
};
safe_void_coroutine _parseLine(std::wstring line);
void _handleAttach(); // A special case of _handleResponse()
void _handleDetach();
void _handleSessionChanged(int64_t sessionId);
void _handleWindowAdd(int64_t windowId);
void _handleWindowRenamed(int64_t windowId, winrt::hstring name);
void _handleWindowClose(int64_t windowId);
void _handleWindowPaneChanged(int64_t windowId, int64_t paneId);
void _handleLayoutChange(int64_t windowId, std::wstring_view layout);
void _handleResponse(std::wstring_view result);
void _sendSetOption(std::wstring_view option);
void _sendDiscoverWindows(int64_t sessionId);
void _handleResponseDiscoverWindows(std::wstring_view response);
void _sendDiscoverNewWindow(int64_t windowId);
void _handleResponseDiscoverNewWindow(std::wstring_view response);
void _sendCapturePane(int64_t paneId, til::CoordType history);
void _handleResponseCapturePane(const ResponseInfo& info, std::wstring_view response);
void _sendDiscoverPanes(int64_t windowId);
void _handleResponseDiscoverPanes(std::wstring_view response);
void _sendNewWindow();
void _sendKillWindow(int64_t windowId);
void _sendKillPane(int64_t paneId);
void _sendSplitPane(std::shared_ptr<Pane> pane, winrt::Microsoft::Terminal::Settings::Model::SplitDirection direction);
void _sendSelectWindow(int64_t windowId);
void _sendSelectPane(int64_t paneId);
void _sendResizeWindow(int64_t windowId, til::CoordType width, til::CoordType height);
void _sendResizePane(int64_t paneId, til::CoordType width, til::CoordType height);
void _sendSendKey(int64_t paneId, const std::wstring_view keys);
void _sendIgnoreResponse(wil::zwstring_view cmd);
void _sendWithResponseInfo(wil::zwstring_view cmd, ResponseInfo info);
std::shared_ptr<Pane> _layoutCreateRecursive(int64_t windowId, std::wstring_view& remaining, TmuxLayout parent);
std::wstring_view _layoutStripHash(std::wstring_view str);
TmuxLayout _layoutParseNextToken(std::wstring_view& remaining);
void _deliverOutputToPane(int64_t paneId, const std::wstring_view text);
winrt::com_ptr<Tab> _getTab(int64_t windowId) const;
void _newTab(int64_t windowId, winrt::hstring name, std::shared_ptr<Pane> pane);
std::pair<AttachedPane&, std::shared_ptr<Pane>> _newPane(int64_t windowId, int64_t paneId);
void _openNewTerminalViaDropdown();
TerminalPage& _page; // Non-owning, because TerminalPage owns us
winrt::Windows::System::DispatcherQueue _dispatcherQueue{ nullptr };
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _newTabMenu;
winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr };
winrt::com_ptr<Tab> _controlTab{ nullptr };
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
State _state = State::Init;
bool _inUse = false;
std::wstring _lineBuffer;
std::wstring _responseBuffer;
bool _insideOutputBlock = false;
winrt::event_token _detachKeyDownRevoker;
winrt::event_token _windowSizeChangedRevoker;
winrt::event_token _newTabClickRevoker;
std::deque<ResponseInfo> _commandQueue;
std::unordered_map<int64_t, AttachedPane> _attachedPanes;
std::unordered_map<int64_t, winrt::com_ptr<Tab>> _attachedWindows;
int64_t _sessionId = -1;
int64_t _activePaneId = -1;
int64_t _activeWindowId = -1;
til::CoordType _terminalWidth = 0;
til::CoordType _terminalHeight = 0;
winrt::Windows::UI::Xaml::Thickness _thickness{ 0, 0, 0, 0 };
float _fontWidth = 0;
float _fontHeight = 0;
std::pair<std::shared_ptr<Pane>, winrt::Microsoft::Terminal::Settings::Model::SplitDirection> _splittingPane{
nullptr,
winrt::Microsoft::Terminal::Settings::Model::SplitDirection::Right,
};
};
}

View File

@@ -31,7 +31,7 @@ Author(s):
using NewHandoffFunction = HRESULT (*)(HANDLE* in, HANDLE* out, HANDLE signal, HANDLE reference, HANDLE server, HANDLE client, const TERMINAL_STARTUP_INFO* startupInfo);
struct __declspec(uuid(__CLSID_CTerminalHandoff))
CTerminalHandoff : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, ITerminalHandoff3>
CTerminalHandoff : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, ITerminalHandoff3>
{
#pragma region ITerminalHandoff
STDMETHODIMP EstablishPtyHandoff(HANDLE* in, HANDLE* out, HANDLE signal, HANDLE reference, HANDLE server, HANDLE client, const TERMINAL_STARTUP_INFO* startupInfo) override;

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -209,7 +209,7 @@
</data>
<data name="CtrlDToClose" xml:space="preserve">
<value>Сада можете да затворите овај терминал са Ctrl+D, или да притиснете Ентер да га поново покренете.</value>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
<comment>"Ctrl+D" and "Enter" represent keys the user will press (control+D and Enter).</comment>
</data>
<data name="ProcessFailedToLaunch" xml:space="preserve">
<value>[грешка {0} приликом покретања `{1}']</value>
@@ -220,7 +220,7 @@
<value>Не може да се приступи почетном директоријуму „{0}”</value>
<comment>The first argument {0} is a path to a directory on the filesystem, as provided by the user.</comment>
</data>
<data name="ElevationRequired" xml:space="preserve">
<data name="ElevationRequired" xml:space="preserve">
<value>Тражена операција захтева веће привилегије.</value>
</data>
<data name="FileNotFound" xml:space="preserve">

View File

@@ -15,7 +15,6 @@
#include "../../renderer/atlas/AtlasEngine.h"
#include "../../renderer/base/renderer.hpp"
#include "../../renderer/uia/UiaRenderer.hpp"
#include "../../terminal/adapter/adaptDispatch.hpp"
#include "../../types/inc/CodepointWidthDetector.hpp"
#include "../../types/inc/utils.hpp"
@@ -140,20 +139,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto pfnWindowSizeChanged = [this](auto&& PH1, auto&& PH2) { _terminalWindowSizeChanged(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
_terminal->SetWindowSizeChangedCallback(pfnWindowSizeChanged);
_terminal->SetEnterTmuxControlCallback([this]() -> std::function<bool(wchar_t)> {
const auto args = winrt::make_self<EnterTmuxControlEventArgs>();
EnterTmuxControl.raise(*this, *args);
if (auto inputCallback = args->InputCallback())
{
return [inputCallback = std::move(inputCallback)](wchar_t ch) -> bool {
const auto c16 = static_cast<char16_t>(ch);
inputCallback({ &c16, 1 });
return true;
};
}
return nullptr;
});
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
@@ -1474,45 +1459,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_terminal->TrySnapOnInput();
}
void ControlCore::InjectTextAtCursor(const winrt::hstring& text)
{
if (text.empty())
{
return;
}
const auto lock = _terminal->LockForWriting();
std::wstring_view remaining{ text };
// Process one line at a time
for (;;)
{
// Get the (CR)LF position
const auto lf = std::min(remaining.size(), remaining.find(L'\n'));
// Strip off the CR
auto lineEnd = lf;
if (lineEnd != 0 && remaining[lineEnd - 1] == L'\r')
{
lineEnd -= 1;
}
// Split into line and whatever comes after
const auto line = remaining.substr(0, lineEnd);
remaining = remaining.substr(std::min(remaining.size(), lf + 1));
// This will not just print the line but also handle delay wrap, etc.
_terminal->GetAdaptDispatch().PrintString(line);
if (remaining.empty())
{
break;
}
_terminal->GetAdaptDispatch().LineFeed(DispatchTypes::LineFeedType::DependsOnMode);
}
}
FontInfo ControlCore::GetFont() const
{
return _actualFont;
@@ -1622,17 +1568,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _terminal->GetViewport().Height();
}
// Function Description:
// - Gets the width of the terminal in lines of text. This is just the
// width of the viewport.
// Return Value:
// - The width of the terminal in lines of text
int ControlCore::ViewWidth() const
{
const auto lock = _terminal->LockForReading();
return _terminal->GetViewport().Width();
}
// Function Description:
// - Gets the height of the terminal in lines of text. This includes the
// history AND the viewport.
@@ -1801,7 +1736,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called.
// Return Value:
// - <none>
SearchResults ControlCore::Search(SearchRequest request)
SearchResults ControlCore::Search(const SearchRequest& request)
{
const auto lock = _terminal->LockForWriting();
@@ -1810,15 +1745,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
WI_SetFlagIf(flags, SearchFlag::RegularExpression, request.RegularExpression);
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), request.Text, flags);
if (searchInvalidated || !request.ResetOnly)
if (searchInvalidated || request.ExecuteSearch)
{
std::vector<til::point_span> oldResults;
til::point_span oldFocused;
if (const auto focused = _terminal->GetSearchHighlightFocused())
{
oldFocused = *focused;
}
if (searchInvalidated)
{
@@ -1827,18 +1756,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_terminal->SetSearchHighlights(_searcher.Results());
}
if (!request.ResetOnly)
if (request.ExecuteSearch)
{
_searcher.FindNext(!request.GoForward);
}
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(std::max<ptrdiff_t>(0, _searcher.CurrentMatch())));
_renderer->TriggerSearchHighlight(oldResults);
}
if (const auto focused = _terminal->GetSearchHighlightFocused(); focused && *focused != oldFocused)
{
_terminal->ScrollToSearchHighlight(request.ScrollOffset);
}
if (request.ScrollIntoView)
{
_terminal->ScrollToSearchHighlight(request.ScrollOffset);
}
int32_t totalMatches = 0;

View File

@@ -23,7 +23,6 @@
#include "../../buffer/out/search.h"
#include "../../cascadia/TerminalCore/Terminal.hpp"
#include "../../renderer/inc/FontInfoDesired.hpp"
#include "../../terminal/adapter/ITermDispatch.hpp"
namespace Microsoft::Console::Render::Atlas
{
@@ -125,7 +124,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SendInput(std::wstring_view wstr);
void PasteText(const winrt::hstring& hstr);
void InjectTextAtCursor(const winrt::hstring& text);
bool CopySelectionToClipboard(bool singleLine, bool withControlSequences, const CopyFormat formats);
void SelectAll();
void ClearSelection();
@@ -174,7 +172,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
int ScrollOffset();
int ViewHeight() const;
int ViewWidth() const;
int BufferHeight() const;
bool HasSelection() const;
@@ -228,7 +225,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SetSelectionAnchor(const til::point position);
void SetEndSelectionPoint(const til::point position);
SearchResults Search(SearchRequest request);
SearchResults Search(const SearchRequest& request);
const std::vector<til::point_span>& SearchResultRows() const noexcept;
void ClearSearch();
@@ -298,9 +295,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
til::typed_event<> RefreshQuickFixUI;
til::typed_event<IInspectable, Control::WindowSizeChangedEventArgs> WindowSizeChanged;
til::typed_event<IInspectable, Control::EnterTmuxControlEventArgs> EnterTmuxControl;
til::typed_event<> CloseTerminalRequested;
til::typed_event<> RestartTerminalRequested;
til::typed_event<> Attached;
// clang-format on

View File

@@ -55,7 +55,8 @@ namespace Microsoft.Terminal.Control
Boolean GoForward;
Boolean CaseSensitive;
Boolean RegularExpression;
Boolean ResetOnly;
Boolean ExecuteSearch;
Boolean ScrollIntoView;
Int32 ScrollOffset;
};
@@ -128,7 +129,6 @@ namespace Microsoft.Terminal.Control
Microsoft.Terminal.Core.ControlKeyStates modifiers);
void SendInput(String text);
void PasteText(String text);
void InjectTextAtCursor(String text);
void SelectAll();
void ClearSelection();
Boolean ToggleBlockSelection();
@@ -199,7 +199,6 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
event Windows.Foundation.TypedEventHandler<Object, Object> RefreshQuickFixUI;
event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;
event Windows.Foundation.TypedEventHandler<Object, EnterTmuxControlEventArgs> EnterTmuxControl;
// These events are always called from the UI thread (bugs aside)
event Windows.Foundation.TypedEventHandler<Object, FontSizeChangedArgs> FontSizeChanged;

View File

@@ -21,4 +21,3 @@
#include "StringSentEventArgs.g.cpp"
#include "SearchMissingCommandEventArgs.g.cpp"
#include "WindowSizeChangedEventArgs.g.cpp"
#include "EnterTmuxControlEventArgs.g.cpp"

View File

@@ -21,7 +21,6 @@
#include "StringSentEventArgs.g.h"
#include "SearchMissingCommandEventArgs.g.h"
#include "WindowSizeChangedEventArgs.g.h"
#include "EnterTmuxControlEventArgs.g.h"
namespace winrt::Microsoft::Terminal::Control::implementation
{
@@ -266,11 +265,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
WINRT_PROPERTY(int32_t, Width);
WINRT_PROPERTY(int32_t, Height);
};
struct EnterTmuxControlEventArgs : public EnterTmuxControlEventArgsT<EnterTmuxControlEventArgs>
{
til::property<TmuxControlInputCallback> InputCallback;
};
}
namespace winrt::Microsoft::Terminal::Control::factory_implementation

View File

@@ -159,11 +159,4 @@ namespace Microsoft.Terminal.Control
Int32 Width;
Int32 Height;
}
delegate void TmuxControlInputCallback(Char[] input);
runtimeclass EnterTmuxControlEventArgs
{
void InputCallback(TmuxControlInputCallback callback);
}
}

View File

@@ -958,7 +958,7 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
for (size_t tableIndex = 0; tableIndex < 16; tableIndex++)
{
// It's using gsl::at to check the index is in bounds, but the analyzer still calls this array-to-pointer-decay
GSL_SUPPRESS(bounds .3)
GSL_SUPPRESS(bounds.3)
renderSettings.SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex));
}

View File

@@ -40,7 +40,6 @@ namespace Microsoft.Terminal.Control
Int32 ScrollOffset { get; };
Int32 ViewHeight { get; };
Int32 ViewWidth { get; };
Int32 BufferHeight { get; };
Boolean HasSelection { get; };

View File

@@ -330,7 +330,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
_revokers.WindowSizeChanged = _core.WindowSizeChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWindowSizeChanged });
_revokers.WriteToClipboard = _core.WriteToClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWriteToClipboard });
_revokers.EnterTmuxControl = _core.EnterTmuxControl(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleEnterTmuxControl });
_revokers.PasteFromClipboard = _interactivity.PasteFromClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubblePasteFromClipboard });
@@ -715,8 +714,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else
{
const auto request = SearchRequest{ _searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
_handleSearchResults(_core.Search(SearchRequest{
.Text = _searchBox->Text(),
.GoForward = goForward,
.CaseSensitive = _searchBox->CaseSensitive(),
.RegularExpression = _searchBox->RegularExpression(),
.ExecuteSearch = true,
.ScrollIntoView = true,
.ScrollOffset = _searchScrollOffset,
}));
}
}
@@ -750,8 +756,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_searchBox && _searchBox->IsOpen())
{
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, false, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
_handleSearchResults(_core.Search(SearchRequest{
.Text = text,
.GoForward = goForward,
.CaseSensitive = caseSensitive,
.RegularExpression = regularExpression,
.ExecuteSearch = true,
.ScrollIntoView = true,
.ScrollOffset = _searchScrollOffset,
}));
}
}
@@ -770,11 +783,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_searchBox && _searchBox->IsOpen())
{
// We only want to update the search results based on the new text. Set
// `resetOnly` to true so we don't accidentally update the current match index.
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
const auto result = _core.Search(request);
_handleSearchResults(result);
_handleSearchResults(_core.Search(SearchRequest{
.Text = text,
.GoForward = goForward,
.CaseSensitive = caseSensitive,
.RegularExpression = regularExpression,
.ExecuteSearch = false,
.ScrollIntoView = true,
.ScrollOffset = _searchScrollOffset,
}));
}
}
@@ -1507,11 +1524,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.SendInput(text);
}
void TermControl::InjectTextAtCursor(const winrt::hstring& text)
{
_core.InjectTextAtCursor(text);
}
// Method Description:
// - Manually handles key events for certain keys that can't be passed to us
// normally. Namely, the keys we're concerned with are F7 down and Alt up.
@@ -2673,11 +2685,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _core.ViewHeight();
}
int TermControl::ViewWidth() const
{
return _core.ViewWidth();
}
int TermControl::BufferHeight() const
{
return _core.BufferHeight();
@@ -2877,9 +2884,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
else
{
// Do we ever get here (= uninitialized terminal)? If so: How?
// Yes, we can get here, when do Pane._Split, it need to call _SetupEntranceAnimation
// which need the control's size, while this size can only be available when the control
// is initialized.
assert(false);
return { 10, 10 };
}
}
@@ -3755,8 +3760,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto goForward = _searchBox->GoForward();
const auto caseSensitive = _searchBox->CaseSensitive();
const auto regularExpression = _searchBox->RegularExpression();
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
_handleSearchResults(_core.Search(request));
_handleSearchResults(_core.Search(SearchRequest{
.Text = text,
.GoForward = goForward,
.CaseSensitive = caseSensitive,
.RegularExpression = regularExpression,
.ExecuteSearch = false,
.ScrollIntoView = false,
.ScrollOffset = _searchScrollOffset,
}));
}
void TermControl::_handleSearchResults(SearchResults results)
@@ -4041,11 +4053,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
void TermControl::_bubbleEnterTmuxControl(const IInspectable&, Control::EnterTmuxControlEventArgs args)
{
EnterTmuxControl.raise(*this, std::move(args));
}
til::CoordType TermControl::_calculateSearchScrollOffset() const
{
auto result = 0;

View File

@@ -97,7 +97,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
int ScrollOffset() const;
int ViewHeight() const;
int ViewWidth() const;
int BufferHeight() const;
bool HasSelection() const;
@@ -183,7 +182,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool RawWriteKeyEvent(const WORD vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
bool RawWriteChar(const wchar_t character, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers);
void RawWriteString(const winrt::hstring& text);
void InjectTextAtCursor(const winrt::hstring& text);
void ShowContextMenu();
bool OpenQuickFixMenu();
@@ -219,7 +217,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::typed_event<IInspectable, Control::StringSentEventArgs> StringSent;
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
til::typed_event<IInspectable, Control::WindowSizeChangedEventArgs> WindowSizeChanged;
til::typed_event<IInspectable, Control::EnterTmuxControlEventArgs> EnterTmuxControl;
// UNDER NO CIRCUMSTANCES SHOULD YOU ADD A (PROJECTED_)FORWARDED_TYPED_EVENT HERE
// Those attach the handler to the core directly, and will explode if
@@ -440,7 +437,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _bubbleSearchMissingCommand(const IInspectable& sender, const Control::SearchMissingCommandEventArgs& args);
winrt::fire_and_forget _bubbleWindowSizeChanged(const IInspectable& sender, Control::WindowSizeChangedEventArgs args);
void _bubbleEnterTmuxControl(const IInspectable& sender, Control::EnterTmuxControlEventArgs args);
til::CoordType _calculateSearchScrollOffset() const;
void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
@@ -475,7 +471,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
Control::ControlCore::SearchMissingCommand_revoker SearchMissingCommand;
Control::ControlCore::RefreshQuickFixUI_revoker RefreshQuickFixUI;
Control::ControlCore::WindowSizeChanged_revoker WindowSizeChanged;
Control::ControlCore::EnterTmuxControl_revoker EnterTmuxControl;
// These are set up in _InitializeTerminal
Control::ControlCore::RendererWarning_revoker RendererWarning;

View File

@@ -74,7 +74,6 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, Object> ReadOnlyChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FocusFollowMouseRequested;
event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;
event Windows.Foundation.TypedEventHandler<Object, EnterTmuxControlEventArgs> EnterTmuxControl;
event Windows.Foundation.TypedEventHandler<Object, CompletionsChangedEventArgs> CompletionsChanged;
@@ -131,7 +130,6 @@ namespace Microsoft.Terminal.Control
Boolean RawWriteKeyEvent(UInt16 vkey, UInt16 scanCode, Microsoft.Terminal.Core.ControlKeyStates modifiers, Boolean keyDown);
Boolean RawWriteChar(Char character, UInt16 scanCode, Microsoft.Terminal.Core.ControlKeyStates modifiers);
void RawWriteString(String text);
void InjectTextAtCursor(String text);
void BellLightOn();

View File

@@ -121,6 +121,7 @@ namespace Microsoft.Terminal.Core
String WordDelimiters { get; };
Boolean ForceVTInput { get; };
Boolean AllowKittyKeyboardMode { get; };
Boolean AllowVtChecksumReport { get; };
Boolean AllowVtClipboardWrite { get; };
Boolean TrimBlockSelection { get; };

View File

@@ -51,7 +51,6 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re
_mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, &renderer);
auto dispatch = std::make_unique<AdaptDispatch>(*this, &renderer, _renderSettings, _terminalInput);
_adaptDispatch = dispatch.get();
auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
_stateMachine = std::make_unique<StateMachine>(std::move(engine));
}
@@ -99,6 +98,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
}
_getTerminalInput().ForceDisableWin32InputMode(settings.ForceVTInput());
_getTerminalInput().ForceDisableKittyKeyboardProtocol(!settings.AllowKittyKeyboardMode());
if (settings.TabColor() == nullptr)
{
@@ -1040,12 +1040,6 @@ bool Terminal::IsFocused() const noexcept
return _focused;
}
AdaptDispatch& Microsoft::Terminal::Core::Terminal::GetAdaptDispatch() noexcept
{
_assertLocked();
return *_adaptDispatch;
}
RenderSettings& Terminal::GetRenderSettings() noexcept
{
_assertLocked();
@@ -1277,11 +1271,6 @@ void Microsoft::Terminal::Core::Terminal::SetSearchMissingCommandCallback(std::f
_pfnSearchMissingCommand.swap(pfn);
}
void Terminal::SetEnterTmuxControlCallback(std::function<std::function<bool(wchar_t)>()> pfn) noexcept
{
_pfnEnterTmuxControl = std::move(pfn);
}
void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function<void()> pfn) noexcept
{
_pfnClearQuickFix.swap(pfn);

View File

@@ -116,7 +116,6 @@ public:
int ViewEndIndex() const noexcept;
bool IsFocused() const noexcept;
::Microsoft::Console::VirtualTerminal::AdaptDispatch& GetAdaptDispatch() noexcept;
RenderSettings& GetRenderSettings() noexcept;
const RenderSettings& GetRenderSettings() const noexcept;
@@ -154,12 +153,14 @@ public:
void ShowWindow(bool showOrHide) override;
void UseAlternateScreenBuffer(const TextAttribute& attrs) override;
void UseMainScreenBuffer() override;
bool IsVtInputEnabled() const noexcept override;
void NotifyBufferRotation(const int delta) override;
void NotifyShellIntegrationMark() override;
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
void SearchMissingCommand(const std::wstring_view command) override;
std::function<bool(wchar_t)> EnterTmuxControl() override;
#pragma endregion
@@ -229,7 +230,6 @@ public:
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view, const til::CoordType)> pfn) noexcept;
void SetEnterTmuxControlCallback(std::function<std::function<bool(wchar_t)>()> pfn) noexcept;
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
void SetWindowSizeChangedCallback(std::function<void(int32_t, int32_t)> pfn) noexcept;
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
@@ -338,12 +338,10 @@ private:
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
std::function<void(std::wstring_view, unsigned int)> _pfnCompletionsChanged;
std::function<void(std::wstring_view, const til::CoordType)> _pfnSearchMissingCommand;
std::function<std::function<bool(wchar_t)>()> _pfnEnterTmuxControl;
std::function<void()> _pfnClearQuickFix;
std::function<void(int32_t, int32_t)> _pfnWindowSizeChanged;
RenderSettings _renderSettings;
::Microsoft::Console::VirtualTerminal::AdaptDispatch* _adaptDispatch = nullptr;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
::Microsoft::Console::VirtualTerminal::TerminalInput _terminalInput;

View File

@@ -364,11 +364,6 @@ void Terminal::SearchMissingCommand(const std::wstring_view command)
}
}
std::function<bool(wchar_t)> Terminal::EnterTmuxControl()
{
return _pfnEnterTmuxControl ? _pfnEnterTmuxControl() : nullptr;
}
void Terminal::NotifyBufferRotation(const int delta)
{
// Update our selection, so it doesn't move as the buffer is cycled

View File

@@ -50,21 +50,21 @@ namespace winrt::Microsoft::Terminal::Settings
return { horizAlign, vertAlign };
}
winrt::com_ptr<TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
winrt::com_ptr<TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
{
auto settings{ winrt::make_self<TerminalSettings>() };
const auto globals = appSettings.GlobalSettings();
settings->_ApplyProfileSettings(profile);
settings->_ApplyGlobalSettings(globals);
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme());
settings->_ApplyWindowSettings(windowSettings);
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme(windowSettings));
return settings;
}
winrt::com_ptr<TerminalSettings> TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
winrt::com_ptr<TerminalSettings> TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
{
const auto settings = _CreateWithProfileCommon(appSettings, profile);
const auto settings = _CreateWithProfileCommon(appSettings, profile, windowSettings);
settings->_UseBackgroundImageForWindow = false;
return settings;
}
@@ -80,9 +80,9 @@ namespace winrt::Microsoft::Terminal::Settings
// 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
TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
{
const auto settings = _CreateWithProfileCommon(appSettings, profile);
const auto settings = _CreateWithProfileCommon(appSettings, profile, windowSettings);
winrt::com_ptr<TerminalSettings> child{ nullptr };
if (const auto& unfocusedAppearance{ profile.UnfocusedAppearance() })
@@ -90,7 +90,7 @@ namespace winrt::Microsoft::Terminal::Settings
const auto globals = appSettings.GlobalSettings();
child = winrt::make_self<TerminalSettings>();
child->_parent = settings->get_strong();
child->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme());
child->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme(windowSettings));
}
return TerminalSettingsCreateResult{ settings.get(), child.get() };
@@ -114,10 +114,11 @@ namespace winrt::Microsoft::Terminal::Settings
// - A TerminalSettingsCreateResult object, which contains a pair of TerminalSettings
// objects. One for when the terminal is focused and one for when the terminal is unfocused.
TerminalSettingsCreateResult TerminalSettings::CreateWithNewTerminalArgs(const Model::CascadiaSettings& appSettings,
const Model::NewTerminalArgs& newTerminalArgs)
const Model::NewTerminalArgs& newTerminalArgs,
const Model::WindowSettings& windowSettings)
{
const auto profile = appSettings.GetProfileForArgs(newTerminalArgs);
auto settingsPair{ CreateWithProfile(appSettings, profile) };
const auto profile = appSettings.GetProfileForArgs(newTerminalArgs, windowSettings);
auto settingsPair{ CreateWithProfile(appSettings, profile, windowSettings) };
auto defaultSettings = settingsPair.DefaultSettings();
if (newTerminalArgs)
@@ -349,38 +350,38 @@ namespace winrt::Microsoft::Terminal::Settings
_ReloadEnvironmentVariables = profile.ReloadEnvironmentVariables();
_RainbowSuggestions = profile.RainbowSuggestions();
_ForceVTInput = profile.ForceVTInput();
_AllowKittyKeyboardMode = profile.AllowKittyKeyboardMode();
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
_PathTranslationStyle = profile.PathTranslationStyle();
_AllowTmuxControl = profile.AllowTmuxControl();
}
// Method Description:
// - Applies appropriate settings from the globals into the TerminalSettings object.
// - Applies appropriate settings from the window settings into the TerminalSettings object.
// Arguments:
// - globalSettings: the global property values we're applying.
// - windowSettings: the per-window property values we're applying.
// Return Value:
// - <none>
void TerminalSettings::_ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept
void TerminalSettings::_ApplyWindowSettings(const Model::WindowSettings& windowSettings) noexcept
{
_InitialRows = globalSettings.InitialRows();
_InitialCols = globalSettings.InitialCols();
_InitialRows = windowSettings.InitialRows();
_InitialCols = windowSettings.InitialCols();
_WordDelimiters = globalSettings.WordDelimiters();
_CopyOnSelect = globalSettings.CopyOnSelect();
_CopyFormatting = globalSettings.CopyFormatting();
_FocusFollowMouse = globalSettings.FocusFollowMouse();
_ScrollToZoom = globalSettings.ScrollToZoom();
_ScrollToChangeOpacity = globalSettings.ScrollToChangeOpacity();
_GraphicsAPI = globalSettings.GraphicsAPI();
_DisablePartialInvalidation = globalSettings.DisablePartialInvalidation();
_SoftwareRendering = globalSettings.SoftwareRendering();
_TextMeasurement = globalSettings.TextMeasurement();
_DefaultInputScope = globalSettings.DefaultInputScope();
_UseBackgroundImageForWindow = globalSettings.UseBackgroundImageForWindow();
_TrimBlockSelection = globalSettings.TrimBlockSelection();
_DetectURLs = globalSettings.DetectURLs();
_EnableUnfocusedAcrylic = globalSettings.EnableUnfocusedAcrylic();
_WordDelimiters = windowSettings.WordDelimiters();
_CopyOnSelect = windowSettings.CopyOnSelect();
_CopyFormatting = windowSettings.CopyFormatting();
_FocusFollowMouse = windowSettings.FocusFollowMouse();
_ScrollToZoom = windowSettings.ScrollToZoom();
_ScrollToChangeOpacity = windowSettings.ScrollToChangeOpacity();
_GraphicsAPI = windowSettings.GraphicsAPI();
_DisablePartialInvalidation = windowSettings.DisablePartialInvalidation();
_SoftwareRendering = windowSettings.SoftwareRendering();
_TextMeasurement = windowSettings.TextMeasurement();
_DefaultInputScope = windowSettings.DefaultInputScope();
_UseBackgroundImageForWindow = windowSettings.UseBackgroundImageForWindow();
_TrimBlockSelection = windowSettings.TrimBlockSelection();
_DetectURLs = windowSettings.DetectURLs();
_EnableUnfocusedAcrylic = windowSettings.EnableUnfocusedAcrylic();
}
// Method Description:

View File

@@ -57,13 +57,15 @@ namespace winrt::Microsoft::Terminal::Settings
{
TerminalSettings() = default;
static winrt::com_ptr<TerminalSettings> CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
static winrt::com_ptr<TerminalSettings> CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings);
static TerminalSettingsCreateResult CreateWithProfile(const Model::CascadiaSettings& appSettings,
const Model::Profile& profile);
const Model::Profile& profile,
const Model::WindowSettings& windowSettings);
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(const Model::CascadiaSettings& appSettings,
const Model::NewTerminalArgs& newTerminalArgs);
const Model::NewTerminalArgs& newTerminalArgs,
const Model::WindowSettings& windowSettings);
void ApplyColorScheme(const Model::ColorScheme& scheme);
@@ -92,7 +94,6 @@ namespace winrt::Microsoft::Terminal::Settings
SIMPLE_OVERRIDABLE_SETTING(bool, Elevate, false);
SIMPLE_OVERRIDABLE_SETTING(IEnvironmentVariableMapView, EnvironmentVariables, nullptr);
SIMPLE_OVERRIDABLE_SETTING(bool, ReloadEnvironmentVariables, true);
SIMPLE_OVERRIDABLE_SETTING(bool, AllowTmuxControl, false);
public:
// TerminalApp overrides these when duplicating a session
@@ -103,10 +104,10 @@ namespace winrt::Microsoft::Terminal::Settings
std::optional<std::array<Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE>> _ColorTable;
std::span<Microsoft::Terminal::Core::Color> _getColorTableImpl();
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings);
void _ApplyProfileSettings(const Model::Profile& profile);
void _ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept;
void _ApplyWindowSettings(const Model::WindowSettings& windowSettings) noexcept;
void _ApplyAppearanceSettings(const Microsoft::Terminal::Settings::Model::IAppearanceConfig& appearance,
const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes,
const winrt::Microsoft::Terminal::Settings::Model::Theme currentTheme);

View File

@@ -4,7 +4,6 @@
#include "pch.h"
#include "Actions.h"
#include "Actions.g.cpp"
#include "NavigateToPageArgs.g.h"
#include "LibraryResources.h"
#include "../TerminalSettingsModel/AllShortcutActions.h"
@@ -24,8 +23,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
_ViewModel = args.ViewModel().as<Editor::ActionsViewModel>();
_ViewModel.CurrentPage(ActionsSubPage::Base);
get_self<ActionsViewModel>(_ViewModel)->MarkAsVisited();
auto vmImpl = get_self<ActionsViewModel>(_ViewModel);
vmImpl->MarkAsVisited();
_layoutUpdatedRevoker = LayoutUpdated(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) {
// Only let this succeed once.
_layoutUpdatedRevoker.revoke();

View File

@@ -164,17 +164,33 @@
Style="{StaticResource KeyBindingNameTextBlockStyle}"
Text="{x:Bind DisplayName, Mode=OneWay}" />
<!-- Key Chord Text -->
<Border Grid.Column="1"
Padding="8,4,8,4"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(FirstKeyChordText)}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
Text="{x:Bind FirstKeyChordText, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
</Border>
<Grid Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
ColumnSpacing="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0"
Padding="8,4,8,4"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(FirstKeyChordText)}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
Text="{x:Bind FirstKeyChordText, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
</Border>
<Border Grid.Column="1"
Padding="8,4,8,4"
Style="{ThemeResource KeyChordBorderStyle}"
ToolTipService.ToolTip="{x:Bind AdditionalKeyChordTooltipText, Mode=OneWay}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(AdditionalKeyChordCountText)}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
Text="{x:Bind AdditionalKeyChordCountText, Mode=OneWay}" />
</Border>
</Grid>
</Grid>
</ListViewItem>
</DataTemplate>
@@ -182,8 +198,7 @@
</Page.Resources>
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<StackPanel MaxWidth="600"
HorizontalAlignment="Left"
<StackPanel HorizontalAlignment="Stretch"
Spacing="8"
Style="{StaticResource SettingsStackStyle}">
<HyperlinkButton x:Uid="Actions_Disclaimer"

View File

@@ -137,7 +137,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
winrt::hstring CommandViewModel::DisplayNameAndKeyChordAutomationPropName()
{
return DisplayName() + L", " + FirstKeyChordText();
auto result = DisplayName() + L", " + FirstKeyChordText();
const auto size = _KeyChordList.Size();
if (size > 1)
{
result = result + L" " + hstring{ RS_fmt(L"Actions_AdditionalKeyChords", winrt::to_hstring(size - 1)) };
}
return result;
}
winrt::hstring CommandViewModel::FirstKeyChordText()
@@ -149,6 +155,35 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return L"";
}
winrt::hstring CommandViewModel::AdditionalKeyChordCountText()
{
const auto size = _KeyChordList.Size();
if (size > 1)
{
return winrt::hstring{ L"+" + winrt::to_hstring(size - 1) };
}
return L"";
}
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText()
{
const auto size = _KeyChordList.Size();
if (size <= 1)
{
return L"";
}
std::wstring result;
for (uint32_t i = 1; i < size; ++i)
{
if (!result.empty())
{
result += L"\n";
}
result += std::wstring_view{ _KeyChordList.GetAt(i).KeyChordText() };
}
return winrt::hstring{ result };
}
winrt::hstring CommandViewModel::ID()
{
return _command.ID();
@@ -175,6 +210,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
kbdVM->IsInEditMode(true);
_RegisterKeyChordVMEvents(*kbdVM);
KeyChordList().Append(*kbdVM);
FocusContainer.raise(*this, *kbdVM);
}
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName()
@@ -220,7 +256,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
break;
}
}
actionsPageVM.DeleteKeyChord(args);
if (args)
{
actionsPageVM.DeleteKeyChord(args);
}
}
});
kcVM.PropertyChanged([weakThis{ get_weak() }](const IInspectable& sender, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) {
@@ -499,7 +538,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
auto lifetime = get_strong();
static constexpr winrt::guid clientGuidFiles{ 0xbd00ae34, 0x839b, 0x43f6, { 0x8b, 0x94, 0x12, 0x37, 0x1a, 0xfe, 0xea, 0xb5 } };
const auto parentHwnd{ reinterpret_cast<HWND>(_WindowRoot.GetHostingWindow()) };
const auto windowRoot = WindowRoot();
if (!windowRoot)
{
co_return;
}
const auto parentHwnd{ reinterpret_cast<HWND>(windowRoot.GetHostingWindow()) };
auto path = co_await OpenFilePicker(parentHwnd, [](auto&& dialog) {
THROW_IF_FAILED(dialog->SetClientGuid(clientGuidFiles));
try
@@ -522,8 +567,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
auto lifetime = get_strong();
static constexpr winrt::guid clientGuidFolders{ 0xa611027, 0x42be, 0x4665, { 0xaf, 0xf1, 0x3f, 0x22, 0x26, 0xe9, 0xf7, 0x4d } };
;
const auto parentHwnd{ reinterpret_cast<HWND>(_WindowRoot.GetHostingWindow()) };
const auto windowRoot = WindowRoot();
if (!windowRoot)
{
co_return;
}
const auto parentHwnd{ reinterpret_cast<HWND>(windowRoot.GetHostingWindow()) };
auto path = co_await OpenFilePicker(parentHwnd, [](auto&& dialog) {
THROW_IF_FAILED(dialog->SetClientGuid(clientGuidFolders));
try
@@ -1032,6 +1082,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// if we're in edit mode, populate the text box with the current keys
ProposedKeys(_currentKeys);
}
else if (!_currentKeys)
{
// we have left edit mode but don't have any current keys - delete this view model
DeleteKeyChord();
}
}
void KeyChordViewModel::AcceptChanges()

View File

@@ -37,7 +37,6 @@ Abstract:
#pragma once
#include "ActionsViewModel.g.h"
#include "NavigateToCommandArgs.g.h"
#include "CommandViewModel.g.h"
#include "ArgWrapper.g.h"
#include "ActionArgsViewModel.g.h"
@@ -48,21 +47,6 @@ Abstract:
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct NavigateToCommandArgs : NavigateToCommandArgsT<NavigateToCommandArgs>
{
public:
NavigateToCommandArgs(CommandViewModel command, Editor::IHostedInWindow windowRoot) :
_Command(command),
_WeakWindowRoot(windowRoot) {}
Editor::IHostedInWindow WindowRoot() const noexcept { return _WeakWindowRoot.get(); }
Editor::CommandViewModel Command() const noexcept { return _Command; }
private:
winrt::weak_ref<Editor::IHostedInWindow> _WeakWindowRoot;
Editor::CommandViewModel _Command{ nullptr };
};
struct ModifyKeyChordEventArgs : ModifyKeyChordEventArgsT<ModifyKeyChordEventArgs>
{
public:
@@ -90,6 +74,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
winrt::hstring DisplayNameAndKeyChordAutomationPropName();
winrt::hstring FirstKeyChordText();
winrt::hstring AdditionalKeyChordCountText();
winrt::hstring AdditionalKeyChordTooltipText();
winrt::hstring ID();
bool IsUserAction();
@@ -141,6 +127,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
winrt::hstring Type() const noexcept { return _descriptor.Type; };
Model::ArgTypeHint TypeHint() const noexcept { return _descriptor.TypeHint; };
bool Required() const noexcept { return _descriptor.Required; };
Editor::IHostedInWindow WindowRoot() const noexcept { return _WeakWindowRoot.get(); }
void WindowRoot(const Editor::IHostedInWindow& value) { _WeakWindowRoot = value; }
// We cannot use the macro here because we need to implement additional logic for the setter
Windows::Foundation::IInspectable EnumValue() const noexcept { return _EnumValue; };
@@ -186,10 +174,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
VIEW_MODEL_OBSERVABLE_PROPERTY(Editor::ColorSchemeViewModel, DefaultColorScheme, nullptr);
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::IInspectable, Value, nullptr);
WINRT_PROPERTY(Windows::Foundation::Collections::IVector<winrt::hstring>, ColorSchemeNamesList, nullptr);
WINRT_PROPERTY(Editor::IHostedInWindow, WindowRoot, nullptr);
private:
Model::ArgDescriptor _descriptor;
winrt::weak_ref<Editor::IHostedInWindow> _WeakWindowRoot{ nullptr };
Windows::Foundation::IInspectable _EnumValue{ nullptr };
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry> _EnumList;
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::FlagEntry> _FlagList;

View File

@@ -35,12 +35,6 @@ namespace Microsoft.Terminal.Settings.Editor
CommandViewModel ViewModel { get; };
}
runtimeclass NavigateToCommandArgs
{
CommandViewModel Command { get; };
IHostedInWindow WindowRoot { get; };
}
runtimeclass ModifyKeyChordEventArgs
{
Microsoft.Terminal.Control.KeyChord OldKeys { get; };
@@ -61,6 +55,8 @@ namespace Microsoft.Terminal.Settings.Editor
// View-model specific
String DisplayName { get; };
String FirstKeyChordText { get; };
String AdditionalKeyChordCountText { get; };
String AdditionalKeyChordTooltipText { get; };
String DisplayNameAndKeyChordAutomationPropName { get; };
// UI side (command list page)

View File

@@ -26,8 +26,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void AddProfile::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::AddProfilePageNavigationState>();
BringIntoViewWhenLoaded(_State.ElementToFocus());
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
_State = args.ViewModel().as<Editor::AddProfilePageNavigationState>();
BringIntoViewWhenLoaded(args.ElementToFocus());
TraceLoggingWrite(
g_hTerminalSettingsEditorProvider,

View File

@@ -26,9 +26,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
struct AddProfilePageNavigationState : AddProfilePageNavigationStateT<AddProfilePageNavigationState>
{
public:
AddProfilePageNavigationState(const Model::CascadiaSettings& settings, const hstring& elementToFocus = {}) :
_Settings{ settings },
_ElementToFocus{ elementToFocus } {}
AddProfilePageNavigationState(const Model::CascadiaSettings& settings) :
_Settings{ settings } {}
void RequestAddNew()
{
@@ -43,7 +42,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
til::event<AddNewArgs> AddNew;
WINRT_PROPERTY(Model::CascadiaSettings, Settings, nullptr);
WINRT_PROPERTY(hstring, ElementToFocus);
};
struct AddProfile : public HasScrollViewer<AddProfile>, AddProfileT<AddProfile>

View File

@@ -8,8 +8,6 @@ namespace Microsoft.Terminal.Settings.Editor
runtimeclass AddProfilePageNavigationState
{
Microsoft.Terminal.Settings.Model.CascadiaSettings Settings;
String ElementToFocus { get; };
void RequestAddNew();
void RequestDuplicate(Guid profile);
event AddNewArgs AddNew;

View File

@@ -1444,10 +1444,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
safe_void_coroutine Appearances::BackgroundImage_Click(const IInspectable&, const RoutedEventArgs&)
{
auto lifetime = get_strong();
const auto lifetime = get_strong();
const auto parentHwnd{ reinterpret_cast<HWND>(WindowRoot().GetHostingWindow()) };
auto file = co_await OpenImagePicker(parentHwnd);
const auto windowRoot = WindowRoot();
if (!windowRoot)
{
co_return;
}
const auto parentHwnd{ reinterpret_cast<HWND>(windowRoot.GetHostingWindow()) };
const auto file = co_await OpenImagePicker(parentHwnd);
if (!file.empty())
{
Appearance().SetBackgroundImagePath(file);

View File

@@ -193,6 +193,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// CursorShape visibility logic
bool IsVintageCursor() const;
Editor::IHostedInWindow WindowRoot() const noexcept { return _WeakWindowRoot.get(); }
void WindowRoot(const Editor::IHostedInWindow& value) noexcept { _WeakWindowRoot = value; }
Windows::Foundation::Collections::IObservableVector<Editor::Font> FilteredFontList();
bool ShowAllFonts() const noexcept;
void ShowAllFonts(bool value);
@@ -220,12 +223,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
DEPENDENCY_PROPERTY(Editor::AppearanceViewModel, Appearance);
WINRT_PROPERTY(Editor::ProfileViewModel, SourceProfile, nullptr);
WINRT_PROPERTY(IHostedInWindow, WindowRoot, nullptr);
GETSET_BINDABLE_ENUM_SETTING(BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch, Appearance().BackgroundImageStretchMode);
GETSET_BINDABLE_ENUM_SETTING(IntenseTextStyle, Microsoft::Terminal::Settings::Model::IntenseStyle, Appearance().IntenseTextStyle);
private:
winrt::weak_ref<Editor::IHostedInWindow> _WeakWindowRoot{ nullptr };
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker;
std::array<Windows::UI::Xaml::Controls::Primitives::ToggleButton, 9> _BIAlignmentButtons;
Windows::Foundation::Collections::IMap<uint16_t, Microsoft::Terminal::Settings::Editor::EnumEntry> _FontWeightMap;

View File

@@ -4,7 +4,6 @@
#include "pch.h"
#include "ColorSchemes.h"
#include "ColorTableEntry.g.cpp"
#include "NavigateToPageArgs.g.h"
#include "ColorSchemes.g.cpp"
using namespace winrt;
@@ -37,7 +36,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
_ViewModel = args.ViewModel().as<Editor::ColorSchemesPageViewModel>();
_ViewModel.CurrentPage(ColorSchemesSubPage::Base);
BringIntoViewWhenLoaded(args.ElementToFocus());
_layoutUpdatedRevoker = LayoutUpdated(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) {

View File

@@ -55,6 +55,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
hstring ColorSchemesPageViewModel::TakeElementToFocus()
{
const auto elementToFocus = _elementToFocus;
_elementToFocus.clear();
return elementToFocus;
}
void ColorSchemesPageViewModel::CurrentScheme(const Editor::ColorSchemeViewModel& newSelectedScheme)
{
if (_CurrentScheme != newSelectedScheme)

View File

@@ -17,6 +17,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
ColorSchemesPageViewModel(const Model::CascadiaSettings& settings);
void UpdateSettings(const Model::CascadiaSettings& settings);
hstring TakeElementToFocus();
void PutElementToFocus(const hstring& elementName) { _elementToFocus = elementName; }
void CurrentScheme(const Editor::ColorSchemeViewModel& newSelectedScheme);
Editor::ColorSchemeViewModel CurrentScheme();
bool HasCurrentScheme() const noexcept;
@@ -37,11 +40,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WINRT_OBSERVABLE_PROPERTY(ColorSchemesSubPage, CurrentPage, _propertyChangedHandlers, ColorSchemesSubPage::Base);
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ColorSchemeViewModel>, AllColorSchemes, _propertyChangedHandlers, nullptr);
WINRT_PROPERTY(hstring, ElementToFocus);
private:
Editor::ColorSchemeViewModel _CurrentScheme{ nullptr };
Model::CascadiaSettings _settings;
hstring _elementToFocus;
Windows::Foundation::Collections::IMap<Editor::ColorSchemeViewModel, Model::ColorScheme> _viewModelToSchemeMap;
void _MakeColorSchemeVMsHelper();

View File

@@ -6,7 +6,6 @@
#include "EnumEntry.h"
#include "Compatibility.g.cpp"
#include "CompatibilityViewModel.g.cpp"
#include "NavigateToPageArgs.g.h"
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Microsoft::Terminal::Settings::Model;

View File

@@ -25,7 +25,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), AllowHeadless);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DebugFeaturesEnabled);
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.GlobalSettings().TextMeasurement);
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.WindowSettingsDefaults().TextMeasurement);
private:
Model::CascadiaSettings _settings;

View File

@@ -8,7 +8,9 @@
#include "../TerminalSettingsModel/AllShortcutActions.h"
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::Foundation::Collections;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
@@ -18,8 +20,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void EditAction::OnNavigatedTo(const NavigationEventArgs& e)
{
const auto args = e.Parameter().as<Editor::NavigateToCommandArgs>();
_ViewModel = args.Command();
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
_ViewModel = args.ViewModel().as<Editor::CommandViewModel>();
_propagateWindowRootRevoker = _ViewModel.PropagateWindowRootRequested(
winrt::auto_revoke,
[windowRoot = args.WindowRoot()](const IInspectable&, const Editor::ArgWrapper& wrapper) {
@@ -36,6 +38,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
if (auto kcVM{ args.try_as<KeyChordViewModel>() })
{
// Force a layout update in case this key chord was newly added
page->KeyChordListView().ScrollIntoView(*kcVM);
page->KeyChordListView().UpdateLayout();
if (const auto& container = page->KeyChordListView().ContainerFromItem(*kcVM))
{
container.as<Controls::ListViewItem>().Focus(FocusState::Programmatic);
@@ -49,5 +54,94 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
CommandNameTextBox().Focus(FocusState::Programmatic);
});
// Initialize AutoSuggestBox with current action and store last valid action
if (_ViewModel.ProposedShortcutActionName())
{
const auto currentAction = winrt::unbox_value<winrt::hstring>(_ViewModel.ProposedShortcutActionName());
ShortcutActionBox().Text(currentAction);
_lastValidAction = currentAction;
}
}
void EditAction::ShortcutActionBox_GotFocus(const IInspectable& sender, const RoutedEventArgs&)
{
// Only rebuild the list if we don't have a cached list or if the cached list is filtered
if (!_filteredActions || !_currentActionFilter.empty())
{
// Open the suggestions list with all available actions
std::vector<winrt::hstring> allActions;
for (const auto& action : _ViewModel.AvailableShortcutActions())
{
allActions.push_back(action);
}
_filteredActions = winrt::single_threaded_observable_vector(std::move(allActions));
_currentActionFilter = L"";
sender.as<AutoSuggestBox>().ItemsSource(_filteredActions);
}
sender.as<AutoSuggestBox>().IsSuggestionListOpen(true);
}
void EditAction::ShortcutActionBox_TextChanged(const AutoSuggestBox& sender, const AutoSuggestBoxTextChangedEventArgs& args)
{
if (args.Reason() == AutoSuggestionBoxTextChangeReason::UserInput)
{
const auto searchText = sender.Text();
std::vector<winrt::hstring> filtered;
for (const auto& action : _ViewModel.AvailableShortcutActions())
{
// TODO: Update this to use fzf later
if (til::contains_linguistic_insensitive(action, searchText))
{
filtered.push_back(action);
}
}
_filteredActions = winrt::single_threaded_observable_vector(std::move(filtered));
_currentActionFilter = searchText;
sender.ItemsSource(_filteredActions);
}
}
void EditAction::ShortcutActionBox_SuggestionChosen(const AutoSuggestBox& sender, const AutoSuggestBoxSuggestionChosenEventArgs& args)
{
if (const auto selectedAction = args.SelectedItem().try_as<winrt::hstring>())
{
sender.Text(*selectedAction);
}
}
void EditAction::ShortcutActionBox_QuerySubmitted(const AutoSuggestBox& sender, const AutoSuggestBoxQuerySubmittedEventArgs& args)
{
const auto submittedText = args.QueryText();
for (const auto& action : _ViewModel.AvailableShortcutActions())
{
if (action == submittedText)
{
_ViewModel.ProposedShortcutActionName(winrt::box_value(submittedText));
_lastValidAction = submittedText;
return;
}
}
// If we get here, we never found a match.
// Revert to the last valid action
sender.Text(_lastValidAction);
}
void EditAction::ShortcutActionBox_LostFocus(const IInspectable& sender, const RoutedEventArgs&)
{
// The auto suggest box does a weird thing where it reverts to the last query text when you
// keyboard navigate out of it. Intercept it here and keep the correct text.
const auto box = sender.as<AutoSuggestBox>();
const auto currentText = box.Text();
if (currentText != _lastValidAction && !_lastValidAction.empty())
{
box.Text(_lastValidAction);
}
}
}

View File

@@ -20,11 +20,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WINRT_OBSERVABLE_PROPERTY(Editor::CommandViewModel, ViewModel, PropertyChanged.raise, nullptr);
void ShortcutActionBox_GotFocus(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
void ShortcutActionBox_TextChanged(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox& sender, const winrt::Windows::UI::Xaml::Controls::AutoSuggestBoxTextChangedEventArgs& args);
void ShortcutActionBox_SuggestionChosen(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox& sender, const winrt::Windows::UI::Xaml::Controls::AutoSuggestBoxSuggestionChosenEventArgs& args);
void ShortcutActionBox_QuerySubmitted(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox& sender, const winrt::Windows::UI::Xaml::Controls::AutoSuggestBoxQuerySubmittedEventArgs& args);
void ShortcutActionBox_LostFocus(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
private:
friend struct EditActionT<EditAction>; // for Xaml to bind events
winrt::Windows::UI::Xaml::FrameworkElement::LayoutUpdated_revoker _layoutUpdatedRevoker;
Editor::CommandViewModel::PropagateWindowRootRequested_revoker _propagateWindowRootRevoker;
Editor::CommandViewModel::FocusContainer_revoker _focusContainerRevoker;
winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> _filteredActions{ nullptr };
winrt::hstring _lastValidAction;
winrt::hstring _currentActionFilter;
};
}

View File

@@ -136,7 +136,7 @@
</Style>
<Style x:Key="KeyChordEditorStyle"
TargetType="local:KeyChordListener">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<x:Int32 x:Key="EditButtonSize">32</x:Int32>
@@ -157,63 +157,64 @@
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
</Style>
<Style x:Key="TextBlockGroupingStyle"
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
<Setter Property="Margin" Value="0,0,0,4" />
<Setter Property="FontSize" Value="16" />
</Style>
<!-- Templates -->
<DataTemplate x:Key="KeyChordTemplate"
x:DataType="local:KeyChordViewModel">
<ListViewItem IsTabStop="False"
Style="{StaticResource KeyBindingContainerStyle}">
<Grid Padding="2,0,2,0"
<Grid Padding="-4,0,0,0"
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Background="{ThemeResource AppBarItemBackgroundThemeBrush}"
Click="{x:Bind ToggleEditMode}"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
Text="{x:Bind KeyChordText, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
</Button>
<Grid Grid.Column="0"
ColumnSpacing="8"
Visibility="{x:Bind IsInEditMode, Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Edit Mode: Key Chord Listener -->
<local:KeyChordListener Grid.Column="0"
Keys="{x:Bind ProposedKeys, Mode=TwoWay}"
Style="{StaticResource KeyChordEditorStyle}" />
<!-- Cancel editing the action -->
<Button x:Uid="Actions_CancelButton"
Grid.Column="1"
AutomationProperties.Name="{x:Bind CancelButtonName}"
Click="{x:Bind CancelChanges}"
Style="{StaticResource EditButtonStyle}">
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE711;" />
</Button>
<!-- Accept changes -->
<Button x:Uid="Actions_AcceptButton"
Grid.Column="2"
AutomationProperties.Name="{x:Bind AcceptButtonName}"
Click="{x:Bind AcceptChanges}"
Flyout="{x:Bind AcceptChangesFlyout, Mode=OneWay}"
Style="{StaticResource AccentEditButtonStyle}">
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE8FB;" />
</Button>
</Grid>
<Button Grid.Column="1"
<local:KeyChordListener Grid.Column="0"
Keys="{x:Bind ProposedKeys, Mode=TwoWay}"
Style="{StaticResource KeyChordEditorStyle}"
Visibility="{x:Bind IsInEditMode, Mode=OneWay}" />
<Button x:Uid="Actions_CancelButton"
Grid.Column="1"
Margin="8,0,0,0"
AutomationProperties.Name="{x:Bind CancelButtonName}"
Click="{x:Bind CancelChanges}"
Style="{StaticResource EditButtonStyle}"
Visibility="{x:Bind IsInEditMode, Mode=OneWay}">
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE711;" />
</Button>
<Button x:Uid="Actions_AcceptButton"
Grid.Column="2"
Margin="8,0,8,0"
AutomationProperties.Name="{x:Bind AcceptButtonName}"
Click="{x:Bind AcceptChanges}"
Flyout="{x:Bind AcceptChangesFlyout, Mode=OneWay}"
Style="{StaticResource AccentEditButtonStyle}"
Visibility="{x:Bind IsInEditMode, Mode=OneWay}">
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE8FB;" />
</Button>
<Button Grid.Column="3"
HorizontalAlignment="Left"
AutomationProperties.Name="{x:Bind DeleteButtonName}"
Style="{StaticResource DeleteSmallButtonStyle}">
<Button.Content>
@@ -243,13 +244,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<muxc:NumberBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
LargeChange="1"
Maximum="100"
@@ -267,13 +269,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<muxc:NumberBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
LargeChange="1"
Maximum="999"
@@ -291,13 +294,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<muxc:NumberBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
LargeChange="1"
Maximum="999"
@@ -315,13 +319,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<muxc:NumberBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
LargeChange="1"
Maximum="999"
@@ -339,13 +344,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<muxc:NumberBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
LargeChange="1"
Maximum="999"
@@ -363,13 +369,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<muxc:NumberBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
LargeChange="0.2"
Maximum="1"
@@ -387,7 +394,7 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto"
<ColumnDefinition Width="*"
MinWidth="196" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
@@ -408,13 +415,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<ComboBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
@@ -482,13 +490,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<ToggleSwitch Grid.Column="1"
HorizontalAlignment="Left"
AutomationProperties.Name="{x:Bind Name}"
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}" />
</Grid>
@@ -501,13 +510,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<CheckBox Grid.Column="1"
HorizontalAlignment="Left"
AutomationProperties.Name="{x:Bind Name}"
IsChecked="{x:Bind UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
IsThreeState="True" />
@@ -526,13 +536,14 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextWrapping="WrapWholeWords" />
<ComboBox Grid.Column="1"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name}"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
@@ -586,7 +597,7 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
@@ -608,7 +619,7 @@
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
@@ -646,73 +657,99 @@
<Border MaxWidth="{StaticResource StandardControlMaxWidth}"
Margin="{StaticResource SettingStackMargin}">
<Grid MaxWidth="600"
Margin="{StaticResource SettingStackMargin}"
HorizontalAlignment="Left"
ColumnSpacing="16"
RowSpacing="8">
<Grid Margin="{StaticResource SettingStackMargin}"
HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Uid="Actions_Name"
<TextBlock x:Uid="Actions_CommandDetails"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,12"
VerticalAlignment="Center"
Style="{StaticResource TextBlockGroupingStyle}" />
<TextBlock x:Uid="Actions_Name"
Grid.Row="1"
Grid.Column="0"
Margin="0,0,0,8"
VerticalAlignment="Center" />
<TextBox x:Name="CommandNameTextBox"
Grid.Row="0"
Grid.Row="1"
Grid.Column="1"
Width="300"
HorizontalAlignment="Left"
Margin="0,0,0,8"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
<TextBlock x:Uid="Actions_ShortcutAction"
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center" />
<ComboBox Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
ItemsSource="{x:Bind ViewModel.AvailableShortcutActions, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.ProposedShortcutActionName, Mode=TwoWay}" />
<TextBlock x:Uid="Actions_Arguments"
Grid.Row="2"
Grid.Column="0"
Margin="0,0,0,12"
VerticalAlignment="Center" />
<AutoSuggestBox x:Name="ShortcutActionBox"
Grid.Row="2"
Grid.Column="1"
Margin="0,0,0,12"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
GotFocus="ShortcutActionBox_GotFocus"
LostFocus="ShortcutActionBox_LostFocus"
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
SuggestionChosen="ShortcutActionBox_SuggestionChosen"
TextChanged="ShortcutActionBox_TextChanged" />
<TextBlock x:Uid="Actions_Keybindings"
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,12"
VerticalAlignment="Center"
Style="{StaticResource TextBlockGroupingStyle}" />
<ListView x:Name="KeyChordListView"
x:Uid="Actions_KeyBindingsListView"
Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,12"
ItemTemplate="{StaticResource KeyChordTemplate}"
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
SelectionMode="None">
<ListView.Footer>
<Button Margin="0,4,0,0"
Click="{x:Bind ViewModel.AddKeybinding_Click}">
<TextBlock x:Uid="Actions_AddKeyChord" />
</Button>
</ListView.Footer>
</ListView>
<TextBlock x:Uid="Actions_Arguments"
Grid.Row="5"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,12"
VerticalAlignment="Center"
Style="{StaticResource TextBlockGroupingStyle}"
Visibility="{x:Bind ViewModel.ActionArgsVM.HasArgs, Mode=OneWay}" />
<ItemsControl Grid.Row="2"
Grid.Column="1"
<ItemsControl Grid.Row="6"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,12"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
IsTabStop="False"
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}" />
<TextBlock x:Uid="Actions_Keybindings"
Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center" />
<ListView x:Name="KeyChordListView"
x:Uid="Actions_KeyBindingsListView"
Grid.Row="3"
Grid.Column="1"
ItemTemplate="{StaticResource KeyChordTemplate}"
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
SelectionMode="None">
<ListView.Header>
<Button Click="{x:Bind ViewModel.AddKeybinding_Click}">
<TextBlock x:Uid="Actions_AddKeyChord" />
</Button>
</ListView.Header>
</ListView>
<Button Grid.Row="4"
<Button Grid.Row="7"
Grid.Column="0"
IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
Style="{StaticResource DeleteButtonStyle}">

Some files were not shown because too many files have changed in this diff Show More