mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 22:06:56 +00:00
Compare commits
46 Commits
dev/cazamo
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f75166e87a | ||
|
|
9e0ff8835f | ||
|
|
fd5ddfb4c0 | ||
|
|
d2fcfdc6b3 | ||
|
|
34b3029fb1 | ||
|
|
45ddf94067 | ||
|
|
abb06e1918 | ||
|
|
eb2899e267 | ||
|
|
0a3fbdefb3 | ||
|
|
9f0cd70ae9 | ||
|
|
127775118d | ||
|
|
343db95021 | ||
|
|
f20c549d15 | ||
|
|
300bc2b513 | ||
|
|
b6375cc028 | ||
|
|
67669a35c5 | ||
|
|
e20e1f7bf9 | ||
|
|
c81c66b406 | ||
|
|
83b9569ce0 | ||
|
|
830935d500 | ||
|
|
bc4e6129ef | ||
|
|
d9d824a840 | ||
|
|
c310e0280f | ||
|
|
1f85191baf | ||
|
|
ed5b59d248 | ||
|
|
527b369de7 | ||
|
|
7798d2e958 | ||
|
|
0c5ec71e62 | ||
|
|
497bb2f7d1 | ||
|
|
c05cb107e5 | ||
|
|
5f1ecb005a | ||
|
|
692f06beb6 | ||
|
|
21754fabf2 | ||
|
|
8e4642dc13 | ||
|
|
3e912e78a7 | ||
|
|
61f86e1116 | ||
|
|
27aae1f245 | ||
|
|
89d82638ab | ||
|
|
a449899789 | ||
|
|
cdf4bd9209 | ||
|
|
8f3d1d8d01 | ||
|
|
3ec372c176 | ||
|
|
71409f84f7 | ||
|
|
6723ca2239 | ||
|
|
c8549bebed | ||
|
|
8d94edd7b0 |
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
|
||||
contact_links:
|
||||
- name: Microsoft Security Response Center 🔐
|
||||
|
||||
3
.github/actions/spelling/excludes.txt
vendored
3
.github/actions/spelling/excludes.txt
vendored
@@ -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\.
|
||||
|
||||
5
.github/actions/spelling/expect/expect.txt
vendored
5
.github/actions/spelling/expect/expect.txt
vendored
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ()
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
36
dep/vcpkg-overlay-ports/jsoncpp/portfile.cmake
Normal file
36
dep/vcpkg-overlay-ports/jsoncpp/portfile.cmake
Normal 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")
|
||||
17
dep/vcpkg-overlay-ports/jsoncpp/vcpkg.json
Normal file
17
dep/vcpkg-overlay-ports/jsoncpp/vcpkg.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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*)
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}" />
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,5 +9,7 @@ namespace TerminalApp
|
||||
TabRowControl();
|
||||
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
|
||||
Boolean ShowElevationShield;
|
||||
Boolean ShowWindowsButton;
|
||||
String WorkspaceName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=""
|
||||
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=""
|
||||
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="" />
|
||||
<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>
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace winrt::TerminalApp::implementation
|
||||
void ReleaseButtons();
|
||||
float CaptionButtonWidth();
|
||||
|
||||
bool Focused();
|
||||
void Focused(bool focused);
|
||||
|
||||
IInspectable Content();
|
||||
void Content(IInspectable content);
|
||||
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -21,4 +21,3 @@
|
||||
#include "StringSentEventArgs.g.cpp"
|
||||
#include "SearchMissingCommandEventArgs.g.cpp"
|
||||
#include "WindowSizeChangedEventArgs.g.cpp"
|
||||
#include "EnterTmuxControlEventArgs.g.cpp"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -159,11 +159,4 @@ namespace Microsoft.Terminal.Control
|
||||
Int32 Width;
|
||||
Int32 Height;
|
||||
}
|
||||
|
||||
delegate void TmuxControlInputCallback(Char[] input);
|
||||
|
||||
runtimeclass EnterTmuxControlEventArgs
|
||||
{
|
||||
void InputCallback(TmuxControlInputCallback callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
Int32 ScrollOffset { get; };
|
||||
Int32 ViewHeight { get; };
|
||||
Int32 ViewWidth { get; };
|
||||
Int32 BufferHeight { get; };
|
||||
|
||||
Boolean HasSelection { get; };
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*/) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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="" />
|
||||
</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="" />
|
||||
</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="" />
|
||||
</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="" />
|
||||
</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
Reference in New Issue
Block a user