From 34d81b1c461b1dc1f5950ab75a95092fb5ee2784 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 2 Mar 2022 00:02:08 +0100 Subject: [PATCH 01/67] Fix fail-fast due to unlocked FreeProcessData call (#12599) 2b202ce6 introduced a bug, where FreeProcessData was called without the console lock being held. The previous code can be found in 40e3dea, on line 441-454. ## PR Checklist * [x] Closes MSFT:21372705 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed None, as this fix is purely theoretic, but it matches the stack trace and 40e3dea clearly wasn't correctly ported to strict C++ either. --- src/server/IoDispatchers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/server/IoDispatchers.cpp b/src/server/IoDispatchers.cpp index 1488b2b71d8..0c90da80581 100644 --- a/src/server/IoDispatchers.cpp +++ b/src/server/IoDispatchers.cpp @@ -287,8 +287,6 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API LockConsole(); const auto cleanup = wil::scope_exit([&]() noexcept { - UnlockConsole(); - if (!NT_SUCCESS(Status)) { pReceiveMsg->SetReplyStatus(Status); @@ -298,6 +296,9 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API gci.ProcessHandleList.FreeProcessData(ProcessData); } } + + // FreeProcessData() above requires the console to be locked. + UnlockConsole(); }); DWORD const dwProcessId = (DWORD)pReceiveMsg->Descriptor.Process; From c481dd4d1087a01a9288abb880f0f4076d6a2814 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 10 Mar 2022 23:45:27 +0000 Subject: [PATCH 02/67] Merged PR 7045816: clean up outdated dirs files Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev cba7e7f88987f549c6c6d47649e77a6b8d4cb874 --- src/dirs | 1 - src/terminal/input/dirs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/dirs b/src/dirs index f8132613980..3b6880002ae 100644 --- a/src/dirs +++ b/src/dirs @@ -2,7 +2,6 @@ DIRS=\ staging \ buffer \ interactivity \ - dep \ host \ propsheet \ propslib \ diff --git a/src/terminal/input/dirs b/src/terminal/input/dirs index dc14638bf5f..a723a0cec35 100644 --- a/src/terminal/input/dirs +++ b/src/terminal/input/dirs @@ -1,2 +1 @@ DIRS=lib \ - ut_adapter \ From 472d462f69d11aecf030536af3729f4675c10a19 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 10 Mar 2022 13:27:19 +0100 Subject: [PATCH 03/67] Fix activation context generation for conhost (#12653) This regressed in 2b202ce6, which removed `ACTCTX_FLAG_RESOURCE_NAME_VALID` during `CreateActCtxW` under the assumption that an executable only has one manifest. conhost has two however and we need to pick the correct one. On OpenConsole this causes the expected `ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET`. Closes MSFT:38355907 (cherry picked from commit c820af46b7c2e1c1362dd7a5eac4500d345bede0) --- src/host/init.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/host/init.cpp b/src/host/init.cpp index 8ab26062fe5..76c4a8b050a 100644 --- a/src/host/init.cpp +++ b/src/host/init.cpp @@ -32,7 +32,8 @@ void InitSideBySide() actctx.cbSize = sizeof(actctx); // We set ACTCTX_FLAG_HMODULE_VALID, but leave hModule as nullptr. // A nullptr HMODULE refers to the current process/executable. - actctx.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT | ACTCTX_FLAG_HMODULE_VALID; + actctx.lpResourceName = MAKEINTRESOURCE(IDR_SYSTEM_MANIFEST); + actctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT | ACTCTX_FLAG_HMODULE_VALID; HANDLE const hActCtx = CreateActCtxW(&actctx); @@ -44,8 +45,9 @@ void InitSideBySide() { auto const error = GetLastError(); - // Don't log if it's already set. This whole ordeal is to make sure one is set if there isn't one already. - // If one is already set... good! + // OpenConsole ships with a single manifest at ID 1, while conhost ships with 2 at ID 1 + // and IDR_SYSTEM_MANIFEST. If we call CreateActCtxW() with IDR_SYSTEM_MANIFEST inside + // OpenConsole anyways, nothing happens and we get ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET. if (ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET != error) { RIPMSG1(RIP_WARNING, "InitSideBySide failed create an activation context. Error: %d\r\n", error); From 8f180c2b2db6d7781a71002e9272a5a430e374ac Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Mon, 21 Mar 2022 23:07:34 +0000 Subject: [PATCH 04/67] Merged PR 7088613: [Git2Git] Merged PR 7088552: Silence TVS by using %d (int) instead of %td (ptrdiff_t) [Git2Git] Merged PR 7088552: Silence TVS by using %d (int) instead of %td (ptrdiff_t) Silence TVS by using %d (int) instead of %td (ptrdiff_t) This commit also includes an automatic sources.dep fix. Fixes MSFT-38106841 Fixes MSFT-38106866 Related work items: #38106841, #38106866 Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 5983633fe90cccdb1165ab28935bd704414bb6f2 Related work items: #38106841, #38106866 --- src/host/proxy/sources.dep | 3 +++ src/inc/til/point.h | 2 +- src/inc/til/size.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/host/proxy/sources.dep b/src/host/proxy/sources.dep index 6b254b27a36..47d8c3dbb10 100644 --- a/src/host/proxy/sources.dep +++ b/src/host/proxy/sources.dep @@ -1,3 +1,6 @@ +BUILD_PASS0_CONSUMES= \ + onecore\inetcore\published\sdk\inc|PASS0 \ + PUBLIC_PASS0_CONSUMES= \ minkernel\published\base|PASS0 \ onecore\com\published\idlole\publish|PASS0 \ diff --git a/src/inc/til/point.h b/src/inc/til/point.h index 4741a67c8d8..98bd50c6d54 100644 --- a/src/inc/til/point.h +++ b/src/inc/til/point.h @@ -226,7 +226,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" std::wstring to_string() const { - return wil::str_printf(L"(X:%td, Y:%td)", x, y); + return wil::str_printf(L"(X:%d, Y:%d)", x, y); } }; } diff --git a/src/inc/til/size.h b/src/inc/til/size.h index 22422bccf7d..199f836a3a0 100644 --- a/src/inc/til/size.h +++ b/src/inc/til/size.h @@ -206,7 +206,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" std::wstring to_string() const { - return wil::str_printf(L"[W:%td, H:%td]", width, height); + return wil::str_printf(L"[W:%d, H:%d]", width, height); } }; }; From fd4fa664602d25fc2d3b52d82346e048b7328d66 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Wed, 23 Mar 2022 20:01:52 +0000 Subject: [PATCH 05/67] PR 7101178: Remove the OneCore redirects for MapVkey/VkeyScan/GetKeyState In !1806141, MapVirtualKey and VkKeyScan became part of OneCore (yeah, in 2018!). GetKeyState I can't quite figure out... but it looks like the places we would use it (Win32 Window and Selection) already either don't exist (window) or don't work (selection) in OneCore conhost. Removing these redirects reduces our maintenance burden quite a bit. Because we had to run all keyboard code through the service locator, anything that had a dependency on key translation needed to link the entire console host. Therefore, for anything that conhost depended upon, so did the unit test binaries. Ugh. I chose to keep TranslateCharsetInfo, even though it looks like gdi32 is hosted in OneCore and the code appears as though it would work. It was not in my critical path, and is a very basic local lookup that only powers whether gridlines are available and the console's "Lang ID". TEST RESULTS FROM ONECORE Microsoft.Console.Host.FeatureTests.dll Summary: Total=408, Passed=140, Failed=266, Blocked=0, Not Run=0, Skipped=2 I do not know how to make sure that the feature tests run properly on OneCore. It looks like ModuleSetup is failing, which is unlikely to be related to this change (especially given that conhost *does* launch.) If I re-run the categories individually, they either pass or get marked as skipped intentionally. Microsoft.Console.Host.IntegrityTests.dll Summary: Total=5, Passed=0, Failed=5, Blocked=0, Not Run=0, Skipped=0 Same. Microsoft.Console.Interactivity.Win32.UnitTests.dll Summary: Total=392, Passed=392, Failed=0, Blocked=0, Not Run=0, Skipped=0 Microsoft.Console.TextBuffer.UnitTests.dll Summary: Total=27, Passed=27, Failed=0, Blocked=0, Not Run=0, Skipped=0 Microsoft.Console.Host.UIAutomationTests.dll Summary: Total=6, Passed=0, Failed=0, Blocked=6, Not Run=0, Skipped=0 Microsoft.Console.Types.UnitTests.dll Summary: Total=8, Passed=8, Failed=0, Blocked=0, Not Run=0, Skipped=0 Microsoft.Terminal.Til.UnitTests.dll Summary: Total=290, Passed=290, Failed=0, Blocked=0, Not Run=0, Skipped=0 Microsoft.Console.VirtualTerminal.Parser.UnitTests.dll Summary: Total=748, Passed=747, Failed=0, Blocked=0, Not Run=0, Skipped=1 Microsoft.Console.VirtualTerminal.Adapter.UnitTests.dll Summary: Total=222, Passed=222, Failed=0, Blocked=0, Not Run=0, Skipped=0 Microsoft.Console.Host.UnitTests.dll Summary: Total=5235, Passed=5222, Failed=0, Blocked=12, Not Run=0, Skipped=1 Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev c4c0267e1139d8d205bc9995da7906e5b09f03db Related work items: MSFT-38632962 --- src/host/input.cpp | 16 +-- src/host/selectionInput.cpp | 7 +- src/host/stream.cpp | 2 +- src/host/ut_host/ClipboardTests.cpp | 19 +-- src/interactivity/base/EventSynthesis.cpp | 4 - src/interactivity/base/VtApiRedirection.cpp | 27 ----- .../base/lib/InteractivityBase.vcxproj | 3 +- .../lib/InteractivityBase.vcxproj.filters | 5 +- src/interactivity/base/sources.inc | 1 - src/interactivity/inc/IInputServices.hpp | 3 - src/interactivity/inc/VtApiRedirection.hpp | 29 ----- src/interactivity/onecore/ConIoSrvComm.cpp | 112 ------------------ src/interactivity/onecore/ConIoSrvComm.hpp | 7 -- src/interactivity/win32/InputServices.cpp | 15 --- src/interactivity/win32/InputServices.hpp | 3 - .../ut_adapter/Adapter.UnitTests.vcxproj | 24 ---- src/terminal/adapter/ut_adapter/inputTest.cpp | 4 - src/terminal/adapter/ut_adapter/sources | 87 -------------- src/terminal/input/mouseInput.cpp | 3 - src/terminal/input/terminalInput.cpp | 4 - .../parser/InputStateMachineEngine.cpp | 4 - .../parser/ut_parser/InputEngineTest.cpp | 4 - src/terminal/parser/ut_parser/sources | 98 +-------------- 23 files changed, 23 insertions(+), 458 deletions(-) delete mode 100644 src/interactivity/base/VtApiRedirection.cpp delete mode 100644 src/interactivity/inc/VtApiRedirection.hpp diff --git a/src/host/input.cpp b/src/host/input.cpp index 58c876a328e..9f9582ebd47 100644 --- a/src/host/input.cpp +++ b/src/host/input.cpp @@ -52,35 +52,35 @@ ULONG GetControlKeyState(const LPARAM lParam) { ULONG ControlKeyState = 0; - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_LMENU) & KEY_PRESSED) + if (GetKeyState(VK_LMENU) & KEY_PRESSED) { ControlKeyState |= LEFT_ALT_PRESSED; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_RMENU) & KEY_PRESSED) + if (GetKeyState(VK_RMENU) & KEY_PRESSED) { ControlKeyState |= RIGHT_ALT_PRESSED; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_LCONTROL) & KEY_PRESSED) + if (GetKeyState(VK_LCONTROL) & KEY_PRESSED) { ControlKeyState |= LEFT_CTRL_PRESSED; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_RCONTROL) & KEY_PRESSED) + if (GetKeyState(VK_RCONTROL) & KEY_PRESSED) { ControlKeyState |= RIGHT_CTRL_PRESSED; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_SHIFT) & KEY_PRESSED) + if (GetKeyState(VK_SHIFT) & KEY_PRESSED) { ControlKeyState |= SHIFT_PRESSED; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_NUMLOCK) & KEY_TOGGLED) + if (GetKeyState(VK_NUMLOCK) & KEY_TOGGLED) { ControlKeyState |= NUMLOCK_ON; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_SCROLL) & KEY_TOGGLED) + if (GetKeyState(VK_SCROLL) & KEY_TOGGLED) { ControlKeyState |= SCROLLLOCK_ON; } - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_CAPITAL) & KEY_TOGGLED) + if (GetKeyState(VK_CAPITAL) & KEY_TOGGLED) { ControlKeyState |= CAPSLOCK_ON; } diff --git a/src/host/selectionInput.cpp b/src/host/selectionInput.cpp index cab5aa88b6f..e36db3a5848 100644 --- a/src/host/selectionInput.cpp +++ b/src/host/selectionInput.cpp @@ -22,11 +22,10 @@ using Microsoft::Console::Interactivity::ServiceLocator; Selection::KeySelectionEventResult Selection::HandleKeySelectionEvent(const INPUT_KEY_INFO* const pInputKeyInfo) { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - const auto inputServices = ServiceLocator::LocateInputServices(); FAIL_FAST_IF(!IsInSelectingState()); const WORD wVirtualKeyCode = pInputKeyInfo->GetVirtualKey(); - const bool ctrlPressed = WI_IsFlagSet(inputServices->GetKeyState(VK_CONTROL), KEY_PRESSED); + const bool ctrlPressed = WI_IsFlagSet(GetKeyState(VK_CONTROL), KEY_PRESSED); // if escape or ctrl-c, cancel selection if (!IsMouseButtonDown()) @@ -612,7 +611,7 @@ bool Selection::HandleKeyboardLineSelectionEvent(const INPUT_KEY_INFO* const pIn // - void Selection::CheckAndSetAlternateSelection() { - _fUseAlternateSelection = !!(ServiceLocator::LocateInputServices()->GetKeyState(VK_MENU) & KEY_PRESSED); + _fUseAlternateSelection = !!(GetKeyState(VK_MENU) & KEY_PRESSED); } // Routine Description: @@ -905,7 +904,7 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe } // see if shift is down. if so, we're extending the selection. otherwise, we're resetting the anchor - if (ServiceLocator::LocateInputServices()->GetKeyState(VK_SHIFT) & KEY_PRESSED) + if (GetKeyState(VK_SHIFT) & KEY_PRESSED) { // if we're just starting to "extend" our selection from moving around as a cursor // then attempt to set the alternate selection state based on the ALT key right now diff --git a/src/host/stream.cpp b/src/host/stream.cpp index 6f642ddd992..692761e341a 100644 --- a/src/host/stream.cpp +++ b/src/host/stream.cpp @@ -153,7 +153,7 @@ using Microsoft::Console::Interactivity::ServiceLocator; } else { - const short zeroVkeyData = ServiceLocator::LocateInputServices()->VkKeyScanW(0); + const short zeroVkeyData = VkKeyScanW(0); const byte zeroVKey = LOBYTE(zeroVkeyData); const byte zeroControlKeyState = HIBYTE(zeroVkeyData); diff --git a/src/host/ut_host/ClipboardTests.cpp b/src/host/ut_host/ClipboardTests.cpp index fb389757ec4..3cc38e2c2f6 100644 --- a/src/host/ut_host/ClipboardTests.cpp +++ b/src/host/ut_host/ClipboardTests.cpp @@ -15,10 +15,6 @@ #include -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../../interactivity/inc/VtApiRedirection.hpp" -#endif - #include "../../inc/consoletaeftemplates.hpp" using namespace WEX::Common; @@ -161,7 +157,6 @@ class ClipboardTests std::deque> events = Clipboard::Instance().TextToKeyEvents(wstr.c_str(), wstr.size()); VERIFY_ARE_EQUAL(wstr.size() * 2, events.size()); - IInputServices* pInputServices = ServiceLocator::LocateInputServices(); for (wchar_t wch : wstr) { std::deque keydownPattern{ true, false }; @@ -172,9 +167,9 @@ class ClipboardTests keyEvent.reset(static_cast(events.front().release())); events.pop_front(); - const short keyState = pInputServices->VkKeyScanW(wch); + const short keyState = VkKeyScanW(wch); VERIFY_ARE_NOT_EQUAL(-1, keyState); - const WORD virtualScanCode = static_cast(pInputServices->MapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC)); + const WORD virtualScanCode = static_cast(MapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC)); VERIFY_ARE_EQUAL(wch, keyEvent->GetCharData()); VERIFY_ARE_EQUAL(isKeyDown, keyEvent->IsKeyDown()); @@ -198,8 +193,6 @@ class ClipboardTests wstr.size()); VERIFY_ARE_EQUAL((wstr.size() + uppercaseCount) * 2, events.size()); - IInputServices* pInputServices = ServiceLocator::LocateInputServices(); - VERIFY_IS_NOT_NULL(pInputServices); for (wchar_t wch : wstr) { std::deque keydownPattern{ true, false }; @@ -213,9 +206,9 @@ class ClipboardTests events.pop_front(); const short keyScanError = -1; - const short keyState = pInputServices->VkKeyScanW(wch); + const short keyState = VkKeyScanW(wch); VERIFY_ARE_NOT_EQUAL(keyScanError, keyState); - const WORD virtualScanCode = static_cast(pInputServices->MapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC)); + const WORD virtualScanCode = static_cast(MapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC)); if (std::isupper(wch)) { @@ -229,9 +222,9 @@ class ClipboardTests keyEvent2.reset(static_cast(events.front().release())); events.pop_front(); - const short keyState2 = pInputServices->VkKeyScanW(wch); + const short keyState2 = VkKeyScanW(wch); VERIFY_ARE_NOT_EQUAL(keyScanError, keyState2); - const WORD virtualScanCode2 = static_cast(pInputServices->MapVirtualKeyW(LOBYTE(keyState2), MAPVK_VK_TO_VSC)); + const WORD virtualScanCode2 = static_cast(MapVirtualKeyW(LOBYTE(keyState2), MAPVK_VK_TO_VSC)); if (isKeyDown) { diff --git a/src/interactivity/base/EventSynthesis.cpp b/src/interactivity/base/EventSynthesis.cpp index e73c0672739..0b26b7ca5b4 100644 --- a/src/interactivity/base/EventSynthesis.cpp +++ b/src/interactivity/base/EventSynthesis.cpp @@ -5,10 +5,6 @@ #include "../inc/EventSynthesis.hpp" #include "../../types/inc/convert.hpp" -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../inc/VtApiRedirection.hpp" -#endif - #pragma hdrstop // TODO: MSFT 14150722 - can these const values be generated at diff --git a/src/interactivity/base/VtApiRedirection.cpp b/src/interactivity/base/VtApiRedirection.cpp deleted file mode 100644 index d7bfef8d496..00000000000 --- a/src/interactivity/base/VtApiRedirection.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#include "precomp.h" - -#include "../inc/VtApiRedirection.hpp" - -#include "../inc/ServiceLocator.hpp" - -#pragma hdrstop - -using namespace Microsoft::Console::Interactivity; - -UINT VTRedirMapVirtualKeyW(_In_ UINT uCode, _In_ UINT uMapType) -{ - return ServiceLocator::LocateInputServices()->MapVirtualKeyW(uCode, uMapType); -} - -SHORT VTRedirVkKeyScanW(_In_ WCHAR ch) -{ - return ServiceLocator::LocateInputServices()->VkKeyScanW(ch); -} - -SHORT VTRedirGetKeyState(_In_ int nVirtKey) -{ - return ServiceLocator::LocateInputServices()->GetKeyState(nVirtKey); -} diff --git a/src/interactivity/base/lib/InteractivityBase.vcxproj b/src/interactivity/base/lib/InteractivityBase.vcxproj index 33913e1377b..5f3f7c4e8e5 100644 --- a/src/interactivity/base/lib/InteractivityBase.vcxproj +++ b/src/interactivity/base/lib/InteractivityBase.vcxproj @@ -41,7 +41,6 @@ - @@ -52,4 +51,4 @@ - \ No newline at end of file + diff --git a/src/interactivity/base/lib/InteractivityBase.vcxproj.filters b/src/interactivity/base/lib/InteractivityBase.vcxproj.filters index 23e8c2130e5..4c7b8495037 100644 --- a/src/interactivity/base/lib/InteractivityBase.vcxproj.filters +++ b/src/interactivity/base/lib/InteractivityBase.vcxproj.filters @@ -77,9 +77,6 @@ Header Files - - Header Files - Header Files @@ -96,4 +93,4 @@ - \ No newline at end of file + diff --git a/src/interactivity/base/sources.inc b/src/interactivity/base/sources.inc index 00bfdaf13e3..69e423131c2 100644 --- a/src/interactivity/base/sources.inc +++ b/src/interactivity/base/sources.inc @@ -39,7 +39,6 @@ SOURCES = \ ..\ApiDetector.cpp \ ..\InteractivityFactory.cpp \ ..\ServiceLocator.cpp \ - ..\VtApiRedirection.cpp \ ..\EventSynthesis.cpp \ ..\RemoteConsoleControl.cpp \ ..\HostSignalInputThread.cpp \ diff --git a/src/interactivity/inc/IInputServices.hpp b/src/interactivity/inc/IInputServices.hpp index 30166108291..390a76a5e40 100644 --- a/src/interactivity/inc/IInputServices.hpp +++ b/src/interactivity/inc/IInputServices.hpp @@ -19,9 +19,6 @@ namespace Microsoft::Console::Interactivity class IInputServices { public: - virtual UINT MapVirtualKeyW(_In_ UINT uCode, _In_ UINT uMapType) = 0; - virtual SHORT VkKeyScanW(_In_ WCHAR ch) = 0; - virtual SHORT GetKeyState(_In_ int nVirtKey) = 0; virtual BOOL TranslateCharsetInfo(_Inout_ DWORD FAR* lpSrc, _Out_ LPCHARSETINFO lpCs, _In_ DWORD dwFlags) = 0; virtual ~IInputServices() = 0; diff --git a/src/interactivity/inc/VtApiRedirection.hpp b/src/interactivity/inc/VtApiRedirection.hpp deleted file mode 100644 index 14dcc1cc8da..00000000000 --- a/src/interactivity/inc/VtApiRedirection.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation -Licensed under the MIT license. - -Module Name: -- VtApiRedirection.h - -Abstract: -- Redefines several input-related API's that are not available on OneCore such - that they be redirected through the ServiceLocator via the IInputServices - interface. -- This ensures that all calls to these API's are executed as normal when the - console is running on big Windows, but that they are also redirected to the - Console IO Server when it is running on a OneCore system, where the OneCore - implementations live. - -Author: -- HeGatta Apr.25.2017 ---*/ - -#pragma once - -#define MapVirtualKeyW(x, y) VTRedirMapVirtualKeyW(x, y) -#define VkKeyScanW(x) VTRedirVkKeyScanW(x) -#define GetKeyState(x) VTRedirGetKeyState(x) - -UINT VTRedirMapVirtualKeyW(_In_ UINT uCode, _In_ UINT uMapType); -SHORT VTRedirVkKeyScanW(_In_ WCHAR ch); -SHORT VTRedirGetKeyState(_In_ int nVirtKey); diff --git a/src/interactivity/onecore/ConIoSrvComm.cpp b/src/interactivity/onecore/ConIoSrvComm.cpp index cdeebed38c3..e781f6b786a 100644 --- a/src/interactivity/onecore/ConIoSrvComm.cpp +++ b/src/interactivity/onecore/ConIoSrvComm.cpp @@ -532,70 +532,6 @@ VOID ConIoSrvComm::CleanupForHeadless(const NTSTATUS status) return Status; } -[[nodiscard]] NTSTATUS ConIoSrvComm::RequestMapVirtualKey(_In_ UINT uCode, _In_ UINT uMapType, _Out_ UINT* puReturnValue) -{ - NTSTATUS Status; - - Status = EnsureConnection(); - if (NT_SUCCESS(Status)) - { - CIS_MSG Message = { 0 }; - Message.Type = CIS_MSG_TYPE_MAPVIRTUALKEY; - Message.MapVirtualKeyParams.Code = uCode; - Message.MapVirtualKeyParams.MapType = uMapType; - - Status = SendRequestReceiveReply(&Message); - if (NT_SUCCESS(Status)) - { - *puReturnValue = Message.MapVirtualKeyParams.ReturnValue; - } - } - - return Status; -} - -[[nodiscard]] NTSTATUS ConIoSrvComm::RequestVkKeyScan(_In_ WCHAR wCharacter, _Out_ SHORT* psReturnValue) -{ - NTSTATUS Status; - - Status = EnsureConnection(); - if (NT_SUCCESS(Status)) - { - CIS_MSG Message = { 0 }; - Message.Type = CIS_MSG_TYPE_VKKEYSCAN; - Message.VkKeyScanParams.Character = wCharacter; - - Status = SendRequestReceiveReply(&Message); - if (NT_SUCCESS(Status)) - { - *psReturnValue = Message.VkKeyScanParams.ReturnValue; - } - } - - return Status; -} - -[[nodiscard]] NTSTATUS ConIoSrvComm::RequestGetKeyState(_In_ int iVirtualKey, _Out_ SHORT* psReturnValue) -{ - NTSTATUS Status; - - Status = EnsureConnection(); - if (NT_SUCCESS(Status)) - { - CIS_MSG Message = { 0 }; - Message.Type = CIS_MSG_TYPE_GETKEYSTATE; - Message.GetKeyStateParams.VirtualKey = iVirtualKey; - - Status = SendRequestReceiveReply(&Message); - if (NT_SUCCESS(Status)) - { - *psReturnValue = Message.GetKeyStateParams.ReturnValue; - } - } - - return Status; -} - [[nodiscard]] USHORT ConIoSrvComm::GetDisplayMode() const { return _displayMode; @@ -610,54 +546,6 @@ PVOID ConIoSrvComm::GetSharedViewBase() const #pragma region IInputServices Members -UINT ConIoSrvComm::MapVirtualKeyW(UINT uCode, UINT uMapType) -{ - NTSTATUS Status = STATUS_SUCCESS; - - UINT ReturnValue; - Status = RequestMapVirtualKey(uCode, uMapType, &ReturnValue); - - if (!NT_SUCCESS(Status)) - { - ReturnValue = 0; - SetLastError(ERROR_PROC_NOT_FOUND); - } - - return ReturnValue; -} - -SHORT ConIoSrvComm::VkKeyScanW(WCHAR ch) -{ - NTSTATUS Status = STATUS_SUCCESS; - - SHORT ReturnValue; - Status = RequestVkKeyScan(ch, &ReturnValue); - - if (!NT_SUCCESS(Status)) - { - ReturnValue = 0; - SetLastError(ERROR_PROC_NOT_FOUND); - } - - return ReturnValue; -} - -SHORT ConIoSrvComm::GetKeyState(int nVirtKey) -{ - NTSTATUS Status = STATUS_SUCCESS; - - SHORT ReturnValue; - Status = RequestGetKeyState(nVirtKey, &ReturnValue); - - if (!NT_SUCCESS(Status)) - { - ReturnValue = 0; - SetLastError(ERROR_PROC_NOT_FOUND); - } - - return ReturnValue; -} - BOOL ConIoSrvComm::TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags) { SetLastError(ERROR_SUCCESS); diff --git a/src/interactivity/onecore/ConIoSrvComm.hpp b/src/interactivity/onecore/ConIoSrvComm.hpp index 1a0a827e55d..4a52ed53617 100644 --- a/src/interactivity/onecore/ConIoSrvComm.hpp +++ b/src/interactivity/onecore/ConIoSrvComm.hpp @@ -40,10 +40,6 @@ namespace Microsoft::Console::Interactivity::OneCore [[nodiscard]] NTSTATUS RequestSetCursor(_In_ CD_IO_CURSOR_INFORMATION* const pCdCursorInformation) const; [[nodiscard]] NTSTATUS RequestUpdateDisplay(_In_ SHORT RowIndex) const; - [[nodiscard]] NTSTATUS RequestMapVirtualKey(_In_ UINT uCode, _In_ UINT uMapType, _Out_ UINT* puReturnValue); - [[nodiscard]] NTSTATUS RequestVkKeyScan(_In_ WCHAR wCharacter, _Out_ SHORT* psReturnValue); - [[nodiscard]] NTSTATUS RequestGetKeyState(_In_ int iVirtualKey, _Out_ SHORT* psReturnValue); - [[nodiscard]] USHORT GetDisplayMode() const; PVOID GetSharedViewBase() const; @@ -51,9 +47,6 @@ namespace Microsoft::Console::Interactivity::OneCore VOID CleanupForHeadless(const NTSTATUS status); // IInputServices Members - UINT MapVirtualKeyW(UINT uCode, UINT uMapType); - SHORT VkKeyScanW(WCHAR ch); - SHORT GetKeyState(int nVirtKey); BOOL TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags); [[nodiscard]] NTSTATUS InitializeBgfx(); diff --git a/src/interactivity/win32/InputServices.cpp b/src/interactivity/win32/InputServices.cpp index 3d798e25899..44014fd9284 100644 --- a/src/interactivity/win32/InputServices.cpp +++ b/src/interactivity/win32/InputServices.cpp @@ -9,21 +9,6 @@ using namespace Microsoft::Console::Interactivity::Win32; -UINT InputServices::MapVirtualKeyW(UINT uCode, UINT uMapType) -{ - return ::MapVirtualKeyW(uCode, uMapType); -} - -SHORT InputServices::VkKeyScanW(WCHAR ch) -{ - return ::VkKeyScanW(ch); -} - -SHORT InputServices::GetKeyState(int nVirtKey) -{ - return ::GetKeyState(nVirtKey); -} - BOOL InputServices::TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags) { return ::TranslateCharsetInfo(lpSrc, lpCs, dwFlags); diff --git a/src/interactivity/win32/InputServices.hpp b/src/interactivity/win32/InputServices.hpp index 1df8da3c8ef..00d74b1cabb 100644 --- a/src/interactivity/win32/InputServices.hpp +++ b/src/interactivity/win32/InputServices.hpp @@ -21,9 +21,6 @@ namespace Microsoft::Console::Interactivity::Win32 public: // Inherited via IInputServices ~InputServices() = default; - UINT MapVirtualKeyW(UINT uCode, UINT uMapType); - SHORT VkKeyScanW(WCHAR ch); - SHORT GetKeyState(int nVirtKey); BOOL TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags); }; } diff --git a/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj b/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj index b4e5ba6a2c1..b1ce6a9d73e 100644 --- a/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj +++ b/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj @@ -24,30 +24,9 @@ {0cf235bd-2da0-407e-90ee-c467e8bbc714} - - {06ec74cb-9a12-429c-b551-8562ec954746} - {06ec74cb-9a12-429c-b551-8562ec964846} - - {06ec74cb-9a12-429c-b551-8532ec964726} - - - {345fd5a4-b32b-4f29-bd1c-b033bd2c35cc} - - - {af0a096a-8b3a-4949-81ef-7df8f0fee91f} - - - {1c959542-bac2-4e55-9a6d-13251914cbb9} - - - {18d09a24-8240-42d6-8cb6-236eee820262} - - - {2fd12fbb-1ddb-46d8-b818-1023c624caca} - {18d09a24-8240-42d6-8cb6-236eee820263} @@ -57,9 +36,6 @@ {dcf55140-ef6a-4736-a403-957e4f7430bb} - - {0cf235bd-2da0-407e-90ee-c467e8bbc714} - diff --git a/src/terminal/adapter/ut_adapter/inputTest.cpp b/src/terminal/adapter/ut_adapter/inputTest.cpp index fe19266a474..42f75ae726b 100644 --- a/src/terminal/adapter/ut_adapter/inputTest.cpp +++ b/src/terminal/adapter/ut_adapter/inputTest.cpp @@ -9,10 +9,6 @@ #include "../../input/terminalInput.hpp" -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../../../interactivity/inc/VtApiRedirection.hpp" -#endif - using namespace WEX::Common; using namespace WEX::Logging; using namespace WEX::TestExecution; diff --git a/src/terminal/adapter/ut_adapter/sources b/src/terminal/adapter/ut_adapter/sources index 73a19ce6f86..7bf618415a3 100644 --- a/src/terminal/adapter/ut_adapter/sources +++ b/src/terminal/adapter/ut_adapter/sources @@ -41,101 +41,14 @@ TARGETLIBS = \ $(ONECORE_INTERNAL_SDK_LIB_PATH)\onecoreuuid.lib \ $(ONECOREUAP_INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \ $(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\onecore_internal.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\propsys.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d2d1.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\dwrite.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\dxgi.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d3d11.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d3dcompiler.lib \ - $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\api-ms-win-mm-playsound-l1.lib \ - $(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-dwmapi-ext-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-edputil-policy-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-dc-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-dc-create-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-draw-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-font-l1.lib \ - $(ONECOREWINDOWS_INTERNAL_LIB_PATH_L)\ext-ms-win-gdi-internal-desktop-l1-1-0.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-caret-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-dialogbox-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-draw-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-gui-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-menu-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-misc-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-mouse-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-rectangle-ext-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-server-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-window-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-gdi-object-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-gdi-rgn-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-cursor-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-dc-access-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \ - $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \ - $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \ - $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \ - $(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \ $(WINCORE_OBJ_PATH)\console\open\src\buffer\out\lib\$(O)\conbufferout.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\host\lib\$(O)\conhostv2.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\tsf\$(O)\contsf.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\propslib\$(O)\conprops.lib \ $(WINCORE_OBJ_PATH)\console\open\src\terminal\adapter\lib\$(O)\ConTermAdapter.lib \ $(WINCORE_OBJ_PATH)\console\open\src\terminal\input\lib\$(O)\ConTermInput.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\terminal\parser\lib\$(O)\ConTermParser.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\renderer\base\lib\$(O)\ConRenderBase.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\renderer\gdi\lib\$(O)\ConRenderGdi.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\renderer\wddmcon\lib\$(O)\ConRenderWddmCon.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\renderer\vt\lib\$(O)\ConRenderVt.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\server\lib\$(O)\ConServer.lib \ $(WINCORE_OBJ_PATH)\console\open\src\interactivity\base\lib\$(O)\ConInteractivityBaseLib.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\interactivity\win32\lib\$(O)\ConInteractivityWin32Lib.lib \ - $(WINCORE_OBJ_PATH)\console\open\src\interactivity\onecore\lib\$(O)\ConInteractivityOneCoreLib.lib \ $(WINCORE_OBJ_PATH)\console\open\src\types\lib\$(O)\ConTypes.lib \ DELAYLOAD = \ - PROPSYS.dll; \ - D2D1.dll; \ - DWrite.dll; \ - DXGI.dll; \ - D3D11.dll; \ - OLEAUT32.dll; \ - api-ms-win-mm-playsound-l1.dll; \ - api-ms-win-shcore-scaling-l1.dll; \ - api-ms-win-shell-dataobject-l1.dll; \ - api-ms-win-shell-namespace-l1.dll; \ - ext-ms-win-dwmapi-ext-l1.dll; \ - ext-ms-win-edputil-policy-l1.dll; \ - ext-ms-win-gdi-dc-l1.dll; \ - ext-ms-win-gdi-dc-create-l1.dll; \ - ext-ms-win-gdi-draw-l1.dll; \ - ext-ms-win-gdi-font-l1.dll; \ - ext-ms-win-gdi-internal-desktop-l1.dll; \ - ext-ms-win-ntuser-caret-l1.dll; \ - ext-ms-win-ntuser-dialogbox-l1.dll; \ - ext-ms-win-ntuser-draw-l1.dll; \ ext-ms-win-ntuser-keyboard-l1.dll; \ - ext-ms-win-ntuser-gui-l1.dll; \ - ext-ms-win-ntuser-menu-l1.dll; \ - ext-ms-win-ntuser-misc-l1.dll; \ - ext-ms-win-ntuser-mouse-l1.dll; \ - ext-ms-win-ntuser-rectangle-ext-l1.dll; \ - ext-ms-win-ntuser-server-l1.dll; \ - ext-ms-win-ntuser-window-l1.dll; \ - ext-ms-win-rtcore-gdi-object-l1.dll; \ - ext-ms-win-rtcore-gdi-rgn-l1.dll; \ - ext-ms-win-rtcore-ntuser-cursor-l1.dll; \ - ext-ms-win-rtcore-ntuser-dc-access-l1.dll; \ - ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \ - ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \ - ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \ - ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \ - ext-ms-win-shell-shell32-l1.dll; \ - ext-ms-win-uiacore-l1.dll; \ - ext-ms-win-uxtheme-themes-l1.dll; \ DLOAD_ERROR_HANDLER = kernelbase diff --git a/src/terminal/input/mouseInput.cpp b/src/terminal/input/mouseInput.cpp index e20578e6606..82d8c358303 100644 --- a/src/terminal/input/mouseInput.cpp +++ b/src/terminal/input/mouseInput.cpp @@ -8,9 +8,6 @@ using namespace Microsoft::Console::VirtualTerminal; -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../../interactivity/inc/VtApiRedirection.hpp" -#endif static constexpr int s_MaxDefaultCoordinate = 94; // Alternate scroll sequences diff --git a/src/terminal/input/terminalInput.cpp b/src/terminal/input/terminalInput.cpp index 19bd1b3d8cd..1408ad56cbd 100644 --- a/src/terminal/input/terminalInput.cpp +++ b/src/terminal/input/terminalInput.cpp @@ -10,10 +10,6 @@ #define WIL_SUPPORT_BITOPERATION_PASCAL_NAMES #include -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../../interactivity/inc/VtApiRedirection.hpp" -#endif - #include "../../inc/unicode.hpp" #include "../../types/inc/Utf16Parser.hpp" diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp index ca469663849..e609b0cec56 100644 --- a/src/terminal/parser/InputStateMachineEngine.cpp +++ b/src/terminal/parser/InputStateMachineEngine.cpp @@ -9,10 +9,6 @@ #include "../../inc/unicode.hpp" #include "ascii.hpp" -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../../interactivity/inc/VtApiRedirection.hpp" -#endif - using namespace Microsoft::Console::VirtualTerminal; struct CsiToVkey diff --git a/src/terminal/parser/ut_parser/InputEngineTest.cpp b/src/terminal/parser/ut_parser/InputEngineTest.cpp index cb1ef806251..0cd5c025e7f 100644 --- a/src/terminal/parser/ut_parser/InputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/InputEngineTest.cpp @@ -18,10 +18,6 @@ #include #include -#ifdef BUILD_ONECORE_INTERACTIVITY -#include "../../../interactivity/inc/VtApiRedirection.hpp" -#endif - using namespace WEX::Common; using namespace WEX::Logging; using namespace WEX::TestExecution; diff --git a/src/terminal/parser/ut_parser/sources b/src/terminal/parser/ut_parser/sources index 57b201b9985..54846ecf1dc 100644 --- a/src/terminal/parser/ut_parser/sources +++ b/src/terminal/parser/ut_parser/sources @@ -26,113 +26,21 @@ SOURCES = \ StateMachineTest.cpp \ Base64Test.cpp \ -# The InputEngineTest requires VTRedirMapVirtualKeyW, which means we need the -# ServiceLocator, which means we need the entire host and all it's dependencies, -# as well as the -DBUILD_ONECORE_INTERACTIVITY above - TARGETLIBS = \ $(TARGETLIBS) \ $(ONECORE_INTERNAL_SDK_LIB_PATH)\onecoreuuid.lib \ $(ONECOREUAP_INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \ $(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\onecore_internal.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\propsys.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d2d1.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\dwrite.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\dxgi.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d3d11.lib \ - $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d3dcompiler.lib \ - $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\api-ms-win-mm-playsound-l1.lib \ - $(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-dwmapi-ext-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-edputil-policy-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-dc-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-dc-create-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-draw-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-font-l1.lib \ - $(ONECOREWINDOWS_INTERNAL_LIB_PATH_L)\ext-ms-win-gdi-internal-desktop-l1-1-0.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-caret-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-dialogbox-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-draw-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-gui-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-menu-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-misc-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-mouse-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-rectangle-ext-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-server-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-window-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-gdi-object-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-gdi-rgn-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-cursor-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-dc-access-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \ - $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \ - $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \ - $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \ - $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \ - $(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \ - $(CONSOLE_OBJ_PATH)\buffer\out\lib\$(O)\conbufferout.lib \ - $(CONSOLE_OBJ_PATH)\host\lib\$(O)\conhostv2.lib \ - $(CONSOLE_OBJ_PATH)\tsf\$(O)\contsf.lib \ - $(CONSOLE_OBJ_PATH)\propslib\$(O)\conprops.lib \ - $(CONSOLE_OBJ_PATH)\terminal\input\lib\$(O)\ConTermInput.lib \ - $(CONSOLE_OBJ_PATH)\terminal\adapter\lib\$(O)\ConTermAdapter.lib \ + $(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-mouse-l1.lib \ $(CONSOLE_OBJ_PATH)\terminal\parser\lib\$(O)\ConTermParser.lib \ - $(CONSOLE_OBJ_PATH)\renderer\base\lib\$(O)\ConRenderBase.lib \ - $(CONSOLE_OBJ_PATH)\renderer\gdi\lib\$(O)\ConRenderGdi.lib \ - $(CONSOLE_OBJ_PATH)\renderer\wddmcon\lib\$(O)\ConRenderWddmCon.lib \ - $(CONSOLE_OBJ_PATH)\renderer\vt\lib\$(O)\ConRenderVt.lib \ - $(CONSOLE_OBJ_PATH)\server\lib\$(O)\ConServer.lib \ + $(CONSOLE_OBJ_PATH)\terminal\input\lib\$(O)\ConTermInput.lib \ $(CONSOLE_OBJ_PATH)\interactivity\base\lib\$(O)\ConInteractivityBaseLib.lib \ - $(CONSOLE_OBJ_PATH)\interactivity\win32\lib\$(O)\ConInteractivityWin32Lib.lib \ - $(CONSOLE_OBJ_PATH)\interactivity\onecore\lib\$(O)\ConInteractivityOneCoreLib.lib \ $(CONSOLE_OBJ_PATH)\types\lib\$(O)\ConTypes.lib \ DELAYLOAD = \ - PROPSYS.dll; \ - D2D1.dll; \ - DWrite.dll; \ - DXGI.dll; \ - D3D11.dll; \ - OLEAUT32.dll; \ - api-ms-win-mm-playsound-l1.dll; \ - api-ms-win-shcore-scaling-l1.dll; \ - api-ms-win-shell-dataobject-l1.dll; \ - api-ms-win-shell-namespace-l1.dll; \ - ext-ms-win-dwmapi-ext-l1.dll; \ - ext-ms-win-edputil-policy-l1.dll; \ - ext-ms-win-gdi-dc-l1.dll; \ - ext-ms-win-gdi-dc-create-l1.dll; \ - ext-ms-win-gdi-draw-l1.dll; \ - ext-ms-win-gdi-font-l1.dll; \ - ext-ms-win-gdi-internal-desktop-l1.dll; \ - ext-ms-win-ntuser-caret-l1.dll; \ - ext-ms-win-ntuser-dialogbox-l1.dll; \ - ext-ms-win-ntuser-draw-l1.dll; \ ext-ms-win-ntuser-keyboard-l1.dll; \ - ext-ms-win-ntuser-gui-l1.dll; \ - ext-ms-win-ntuser-menu-l1.dll; \ - ext-ms-win-ntuser-message-l1.dll; \ - ext-ms-win-ntuser-misc-l1.dll; \ - ext-ms-win-ntuser-mouse-l1.dll; \ - ext-ms-win-ntuser-rectangle-ext-l1.dll; \ - ext-ms-win-ntuser-server-l1.dll; \ - ext-ms-win-ntuser-sysparams-ext-l1.dll; \ - ext-ms-win-ntuser-window-l1.dll; \ - ext-ms-win-rtcore-gdi-object-l1.dll; \ - ext-ms-win-rtcore-gdi-rgn-l1.dll; \ - ext-ms-win-rtcore-ntuser-cursor-l1.dll; \ - ext-ms-win-rtcore-ntuser-dc-access-l1.dll; \ - ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \ - ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \ - ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \ - ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \ - ext-ms-win-shell-shell32-l1.dll; \ - ext-ms-win-uiacore-l1.dll; \ - ext-ms-win-uxtheme-themes-l1.dll; \ + ext-ms-win-rtcore-ntuser-mouse-l1.dll; \ DLOAD_ERROR_HANDLER = kernelbase From c857f83aea13e1726c40b72f36bd71050007c1a0 Mon Sep 17 00:00:00 2001 From: abdoulkkonate <73804112+abdoulkkonate@users.noreply.github.com> Date: Mon, 31 Jan 2022 11:57:48 -0800 Subject: [PATCH 06/67] Replaced the sizeof parameter of the if statement with ARRAYSIZE (#12273) The pull request fixes the issue where "sizeof" parameter was use instead of "ARRAYSIZE". ## PR Checklist * [x] Closes #xxx * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments This was a pretty straight forward issue, i just replace sizeof which gives the byte size with ARRAYSIZE which give the number of elements in the array. (cherry picked from commit 5fa1ba8dab00259b1a4f5824460752d3f4346b3b) --- src/interactivity/win32/SystemConfigurationProvider.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interactivity/win32/SystemConfigurationProvider.cpp b/src/interactivity/win32/SystemConfigurationProvider.cpp index af37c4c5cd9..0e3dbb790ab 100644 --- a/src/interactivity/win32/SystemConfigurationProvider.cpp +++ b/src/interactivity/win32/SystemConfigurationProvider.cpp @@ -174,9 +174,9 @@ void SystemConfigurationProvider::GetSettingsFromLink( const DWORD dwLinkLen = SearchPathW(pwszCurrDir, pwszAppName, nullptr, ARRAYSIZE(wszIconLocation), wszIconLocation, nullptr); // If we cannot find the application in the path, then try to fall back and see if the window title is a valid path and use that. - if (dwLinkLen <= 0 || dwLinkLen > sizeof(wszIconLocation)) + if (dwLinkLen <= 0 || dwLinkLen > ARRAYSIZE(wszIconLocation)) { - if (PathFileExistsW(pwszTitle) && (wcslen(pwszTitle) < sizeof(wszIconLocation))) + if (PathFileExistsW(pwszTitle) && (wcslen(pwszTitle) < ARRAYSIZE(wszIconLocation))) { StringCchCopyW(wszIconLocation, ARRAYSIZE(wszIconLocation), pwszTitle); } From 4abd57e16972b94f8b6784b12168a91cc6b39573 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 9 Feb 2022 00:08:00 +0100 Subject: [PATCH 07/67] XtermEngine: Explicitly emit cursor state on the first frame (#12434) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes an issue, where we failed to emit a DECTCEM sequence to hide the cursor if it was hidden before XtermEngine's first frame was finalized. Even in such cases we need to emit a DECTCEM sequence in order to ensure we're in a consistent state. ## Validation Steps Performed * Added test✅ * Run #12401's repro steps around 30 times✅ Closes #12401 (cherry picked from commit dbb70778d470e163c16b30dda0f294a9cbda07a0) --- .github/actions/spelling/expect/expect.txt | 1 + src/host/ut_host/VtRendererTests.cpp | 125 +++++++-------------- src/renderer/vt/XtermEngine.cpp | 25 ++--- src/renderer/vt/XtermEngine.hpp | 11 +- 4 files changed, 58 insertions(+), 104 deletions(-) diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 84fcd8e14b5..e3277a26eed 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -2437,6 +2437,7 @@ TREX triaged triaging TRIANGLESTRIP +Tribool TRIMZEROHEADINGS truetype trx diff --git a/src/host/ut_host/VtRendererTests.cpp b/src/host/ut_host/VtRendererTests.cpp index 9678380e674..c9ef9e8371a 100644 --- a/src/host/ut_host/VtRendererTests.cpp +++ b/src/host/ut_host/VtRendererTests.cpp @@ -90,7 +90,29 @@ class Microsoft::Console::Render::VtRendererTest void TestPaint(VtEngine& engine, std::function pfn); Viewport SetUpViewport(); - void VerifyExpectedInputsDrained(); + void VerifyFirstPaint(VtEngine& engine) + { + // Verify the first BeginPaint emits a clear and go home + qExpectedInput.push_back("\x1b[2J"); + // Verify the first EndPaint sets the cursor state + qExpectedInput.push_back("\x1b[?25l"); + VERIFY_IS_TRUE(engine._firstPaint); + TestPaint(engine, [&]() { + VERIFY_IS_FALSE(engine._firstPaint); + }); + } + + void VerifyExpectedInputsDrained() + { + if (!qExpectedInput.empty()) + { + for (const auto& exp : qExpectedInput) + { + Log::Error(NoThrowString().Format(L"EXPECTED INPUT NEVER RECEIVED: %hs", exp.c_str())); + } + VERIFY_FAIL(L"there should be no remaining un-drained expected input"); + } + } }; Viewport VtRendererTest::SetUpViewport() @@ -103,18 +125,6 @@ Viewport VtRendererTest::SetUpViewport() return Viewport::FromInclusive(view); } -void VtRendererTest::VerifyExpectedInputsDrained() -{ - if (!qExpectedInput.empty()) - { - for (const auto& exp : qExpectedInput) - { - Log::Error(NoThrowString().Format(L"EXPECTED INPUT NEVER RECEIVED: %hs", exp.c_str())); - } - VERIFY_FAIL(L"there should be no remaining un-drained expected input"); - } -} - bool VtRendererTest::WriteCallback(const char* const pch, size_t const cch) { std::string actualString = std::string(pch, cch); @@ -212,12 +222,7 @@ void VtRendererTest::Xterm256TestInvalidate() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); const Viewport view = SetUpViewport(); @@ -402,12 +407,7 @@ void VtRendererTest::Xterm256TestColors() RenderSettings renderSettings; RenderData renderData; - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -585,12 +585,7 @@ void VtRendererTest::Xterm256TestCursor() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -766,12 +761,7 @@ void VtRendererTest::Xterm256TestExtendedAttributes() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -907,12 +897,7 @@ void VtRendererTest::XtermTestInvalidate() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -1096,12 +1081,7 @@ void VtRendererTest::XtermTestColors() RenderSettings renderSettings; RenderData renderData; - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -1234,12 +1214,7 @@ void VtRendererTest::XtermTestCursor() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -1412,12 +1387,7 @@ void VtRendererTest::TestWrapping() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_firstPaint); - }); + VerifyFirstPaint(*engine); Viewport view = SetUpViewport(); @@ -1465,8 +1435,10 @@ void VtRendererTest::TestResize() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear and go home + // Verify the first BeginPaint emits a clear and go home qExpectedInput.push_back("\x1b[2J"); + // Verify the first EndPaint sets the cursor state + qExpectedInput.push_back("\x1b[?25l"); VERIFY_IS_TRUE(engine->_firstPaint); VERIFY_IS_TRUE(engine->_suppressResizeRepaint); @@ -1502,21 +1474,6 @@ void VtRendererTest::TestCursorVisibility() auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2); engine->SetTestCallback(pfn); - // Verify the first paint emits a clear - qExpectedInput.push_back("\x1b[2J"); - VERIFY_IS_TRUE(engine->_firstPaint); - VERIFY_IS_FALSE(engine->_lastCursorIsVisible); - VERIFY_IS_TRUE(engine->_nextCursorIsVisible); - TestPaint(*engine, [&]() { - // During StartPaint, we'll mark the cursor as off. make sure that happens. - VERIFY_IS_FALSE(engine->_nextCursorIsVisible); - VERIFY_IS_FALSE(engine->_firstPaint); - }); - - // The cursor wasn't painted in the last frame. - VERIFY_IS_FALSE(engine->_lastCursorIsVisible); - VERIFY_IS_FALSE(engine->_nextCursorIsVisible); - COORD origin{ 0, 0 }; VERIFY_ARE_NOT_EQUAL(origin, engine->_lastText); @@ -1527,8 +1484,8 @@ void VtRendererTest::TestCursorVisibility() // Frame 1: Paint the cursor at the home position. At the end of the frame, // the cursor should be on. Because we're moving the cursor with CUP, we // need to disable the cursor during this frame. + qExpectedInput.push_back("\x1b[2J"); TestPaint(*engine, [&]() { - VERIFY_IS_FALSE(engine->_lastCursorIsVisible); VERIFY_IS_FALSE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); @@ -1539,10 +1496,13 @@ void VtRendererTest::TestCursorVisibility() VERIFY_IS_TRUE(engine->_nextCursorIsVisible); VERIFY_IS_TRUE(engine->_needToDisableCursor); + // GH#12401: + // The other tests verify that the cursor is explicitly hidden on the + // first frame (VerifyFirstPaint). This test on the other hand does + // the opposite by calling PaintCursor() during the first paint cycle. qExpectedInput.push_back("\x1b[?25h"); }); - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_TRUE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); @@ -1550,7 +1510,6 @@ void VtRendererTest::TestCursorVisibility() // frame, the cursor should be on, the same as before. We aren't moving the // cursor during this frame, so _needToDisableCursor will stay false. TestPaint(*engine, [&]() { - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_FALSE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); @@ -1561,7 +1520,6 @@ void VtRendererTest::TestCursorVisibility() VERIFY_IS_FALSE(engine->_needToDisableCursor); }); - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_TRUE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); @@ -1569,7 +1527,6 @@ void VtRendererTest::TestCursorVisibility() // should be on, the same as before. Because we're moving the cursor with // CUP, we need to disable the cursor during this frame. TestPaint(*engine, [&]() { - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_FALSE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); @@ -1580,7 +1537,6 @@ void VtRendererTest::TestCursorVisibility() VERIFY_SUCCEEDED(engine->PaintCursor(options)); - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_TRUE(engine->_nextCursorIsVisible); VERIFY_IS_TRUE(engine->_needToDisableCursor); @@ -1590,7 +1546,6 @@ void VtRendererTest::TestCursorVisibility() qExpectedInput.push_back("\x1b[?25h"); }); - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_TRUE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); @@ -1598,14 +1553,12 @@ void VtRendererTest::TestCursorVisibility() // should be off. Log::Comment(NoThrowString().Format(L"Painting without calling PaintCursor will hide the cursor")); TestPaint(*engine, [&]() { - VERIFY_IS_TRUE(engine->_lastCursorIsVisible); VERIFY_IS_FALSE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); qExpectedInput.push_back("\x1b[?25l"); }); - VERIFY_IS_FALSE(engine->_lastCursorIsVisible); VERIFY_IS_FALSE(engine->_nextCursorIsVisible); VERIFY_IS_FALSE(engine->_needToDisableCursor); } diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp index 4b3807df270..cb8004cfd0f 100644 --- a/src/renderer/vt/XtermEngine.cpp +++ b/src/renderer/vt/XtermEngine.cpp @@ -15,7 +15,9 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, VtEngine(std::move(hPipe), initialViewport), _fUseAsciiOnly(fUseAsciiOnly), _needToDisableCursor(false), - _lastCursorIsVisible(false), + // GH#12401: Ensure a DECTCEM cursor show/hide sequence + // is emitted on the first frame no matter what. + _lastCursorIsVisible(Tribool::Invalid), _nextCursorIsVisible(true) { // Set out initial cursor position to -1, -1. This will force our initial @@ -98,31 +100,20 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, { // If the cursor was previously visible, let's hide it for this frame, // by prepending a cursor off. - if (_lastCursorIsVisible) + if (_lastCursorIsVisible != Tribool::False) { _buffer.insert(0, "\x1b[?25l"); - _lastCursorIsVisible = false; + _lastCursorIsVisible = Tribool::False; } // If the cursor was NOT previously visible, then that's fine! we don't // need to worry, it's already off. } - // If the cursor is moving from off -> on (including cases where we just - // disabled if for this frame), show the cursor at the end of the frame - if (_nextCursorIsVisible && !_lastCursorIsVisible) + if (_lastCursorIsVisible != static_cast(_nextCursorIsVisible)) { - RETURN_IF_FAILED(_ShowCursor()); + RETURN_IF_FAILED(_nextCursorIsVisible ? _ShowCursor() : _HideCursor()); + _lastCursorIsVisible = static_cast(_nextCursorIsVisible); } - // Otherwise, if the cursor previously was visible, and it should be hidden - // (on -> off), hide it at the end of the frame. - else if (!_nextCursorIsVisible && _lastCursorIsVisible) - { - RETURN_IF_FAILED(_HideCursor()); - } - - // Update our tracker of what we thought the last cursor state of the - // terminal was. - _lastCursorIsVisible = _nextCursorIsVisible; RETURN_IF_FAILED(VtEngine::EndPaint()); diff --git a/src/renderer/vt/XtermEngine.hpp b/src/renderer/vt/XtermEngine.hpp index 1cda1782710..2e2b58affea 100644 --- a/src/renderer/vt/XtermEngine.hpp +++ b/src/renderer/vt/XtermEngine.hpp @@ -54,9 +54,18 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view str) noexcept override; protected: + // I'm using a non-class enum here, so that the values + // are trivially convertible and comparable to bool. + enum class Tribool : uint8_t + { + False = 0, + True, + Invalid, + }; + const bool _fUseAsciiOnly; bool _needToDisableCursor; - bool _lastCursorIsVisible; + Tribool _lastCursorIsVisible; bool _nextCursorIsVisible; [[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept override; From 07c2a597d231e69a022c0afa4970caa1f9eb4d6a Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 8 Feb 2022 15:55:27 -0800 Subject: [PATCH 08/67] Validate cursor position in UIA UTR ctor (#12436) This adds some validation in the `UiaTextRange` ctor for the cursor position. #8730 was caused by creating a `UiaTextRange` at the cursor position when it was in a delayed state (meaning it's purposefully hanging off of the right edge of the buffer). Normally, `Cursor` maintains a flag to keep track of when that occurs, but Windows Terminal isn't maintaining that properly in `Terminal::WriteBuffer`. The _correct_ approach would be to fix `WriteBuffer` then leverage that flag for validation in `UiaTextRange`. However, messing with `WriteBuffer` is a little too risky for our comfort right now. So we'll do the second half of that by checking if the cursor position is valid. Since the cursor is really only expected to be out of bounds when it's in that delayed state, we get the same result (just maybe a tad slower than simply checking a flag). Closes #8730 Filed #12440 to track changes in `Terminal::_WriteBuffer` for delayed EOL wrap. ## Validation Steps Performed While using magnifier, input/delete wrapped text in input buffer. (cherry picked from commit 5dcf5262b46a1dbdf11bc536fe88439df437e211) --- src/types/UiaTextRangeBase.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 58a6f4f982f..4587b08416b 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -42,9 +42,15 @@ HRESULT UiaTextRangeBase::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ std::wstring_view wordDelimiters) noexcept try { + RETURN_HR_IF_NULL(E_INVALIDARG, pData); RETURN_IF_FAILED(RuntimeClassInitialize(pData, pProvider, wordDelimiters)); + // GH#8730: The cursor position may be in a delayed state, resulting in it being out of bounds. + // If that's the case, clamp it to be within bounds. + // TODO GH#12440: We should be able to just check some fields off of the Cursor object, + // but Windows Terminal isn't updating those flags properly. _start = cursor.GetPosition(); + pData->GetTextBuffer().GetSize().Clamp(_start); _end = _start; UiaTracing::TextRange::Constructor(*this); From 6cd3e6a24d93ba5f628b9134916c1bfd9b2252cd Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 15 Feb 2022 08:30:46 -0600 Subject: [PATCH 09/67] Fix a memory leak in onecore interactivity (#12340) As noted in #6759: > `RtlCreateUnicodeString` creates a copy of the string on the process heap and the `PortName` variable has local-scope. The string doesn't get freed with `RtlFreeUnicodeString` before the function returns creating a memory leak. > `CIS_ALPC_PORT_NAME` is a constant string and the `PortName` variable should instead be initialized using the `RTL_CONSTANT_STRING` macro: > > ```c++ > static UNICODE_STRING PortName = RTL_CONSTANT_STRING(CIS_ALPC_PORT_NAME); > ``` I actually built this in the OS repo to make sure it'll still build, because this code doesn't even build outside Windows. * [x] Closes #6759 * I work here. (cherry picked from commit 349b76795f4f2cd5369d088305d69e5b96e4238e) --- src/interactivity/onecore/ConIoSrvComm.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/interactivity/onecore/ConIoSrvComm.cpp b/src/interactivity/onecore/ConIoSrvComm.cpp index e781f6b786a..c65ad00c0c7 100644 --- a/src/interactivity/onecore/ConIoSrvComm.cpp +++ b/src/interactivity/onecore/ConIoSrvComm.cpp @@ -71,12 +71,11 @@ ConIoSrvComm::~ConIoSrvComm() [[nodiscard]] NTSTATUS ConIoSrvComm::Connect() { - BOOL Ret = TRUE; NTSTATUS Status = STATUS_SUCCESS; // Port handle and name. HANDLE PortHandle; - UNICODE_STRING PortName; + static UNICODE_STRING PortName = RTL_CONSTANT_STRING(CIS_ALPC_PORT_NAME); // Generic Object Manager attributes for the port object and ALPC-specific // port attributes. @@ -98,13 +97,6 @@ ConIoSrvComm::~ConIoSrvComm() // Structure used to iterate over the handles given to us by the server. ALPC_MESSAGE_HANDLE_INFORMATION HandleInfo; - // Initialize the server port name. - Ret = RtlCreateUnicodeString(&PortName, CIS_ALPC_PORT_NAME); - if (!Ret) - { - return STATUS_NO_MEMORY; - } - // Initialize the attributes of the port object. InitializeObjectAttributes(&ObjectAttributes, NULL, From 9c1fe1fa78d30f5cd59ba004306c041fcfaa5413 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 11 Mar 2022 22:14:06 +0100 Subject: [PATCH 10/67] Fix overflow in Viewport::FromDimensions (#12669) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes one source of potential integer overflows from the Viewport class. Other parts were left untouched, as this entire class of overflow issues gets fixed all at once, as soon as we replace COORD with til::coord (etc.). ## PR Checklist * [x] Closes #5271 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Call `ScrollConsoleScreenBufferW` with out of bounds coordinates * Doesn't crash ✅ (cherry picked from commit a4a6dfcc8d691dafd5601c82ff2014aec823a7d5) --- src/renderer/base/renderer.cpp | 3 +-- src/types/viewport.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 41208fc0346..ebe63ddbad0 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -677,8 +677,7 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine) for (const auto& dirtyRect : dirtyAreas) { - // Shortcut: don't bother redrawing if the width is 0. - if (dirtyRect.left == dirtyRect.right) + if (!dirtyRect) { continue; } diff --git a/src/types/viewport.cpp b/src/types/viewport.cpp index ac3ac498f49..a135546f558 100644 --- a/src/types/viewport.cpp +++ b/src/types/viewport.cpp @@ -46,7 +46,12 @@ Viewport Viewport::FromDimensions(const COORD origin, const short width, const short height) noexcept { - return Viewport::FromExclusive({ origin.X, origin.Y, origin.X + width, origin.Y + height }); + return Viewport::FromInclusive({ + origin.X, + origin.Y, + base::saturated_cast(origin.X + width - 1), + base::saturated_cast(origin.Y + height - 1), + }); } // Function Description: @@ -60,7 +65,12 @@ Viewport Viewport::FromDimensions(const COORD origin, Viewport Viewport::FromDimensions(const COORD origin, const COORD dimensions) noexcept { - return Viewport::FromExclusive({ origin.X, origin.Y, origin.X + dimensions.X, origin.Y + dimensions.Y }); + return Viewport::FromInclusive({ + origin.X, + origin.Y, + base::saturated_cast(origin.X + dimensions.X - 1), + base::saturated_cast(origin.Y + dimensions.Y - 1), + }); } // Function Description: From 442a46e787ae7492bd42fc1692fc2fd49a0196f6 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 17 Mar 2022 20:13:33 +0100 Subject: [PATCH 11/67] Fix uninitialized memory access in GetConsoleTitleA test (#12699) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `WideCharToMultiByte` doesn't write a final null-byte by default. `til::u16u8` avoids the problem. ## PR Checklist * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Test passes in Debug builds ✅ (cherry picked from commit 5072ee640fd6f50b7681e37e8e8be76ef32d4767) --- src/host/ut_host/ApiRoutinesTests.cpp | 28 ++++----------------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/host/ut_host/ApiRoutinesTests.cpp b/src/host/ut_host/ApiRoutinesTests.cpp index a8dfcf4c143..36e8a156c01 100644 --- a/src/host/ut_host/ApiRoutinesTests.cpp +++ b/src/host/ut_host/ApiRoutinesTests.cpp @@ -215,30 +215,10 @@ class ApiRoutinesTests TEST_METHOD(ApiGetConsoleTitleA) { CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.SetTitle(L"Test window title."); - - const auto title = gci.GetTitle(); - - int const iBytesNeeded = WideCharToMultiByte(gci.OutputCP, - 0, - title.data(), - gsl::narrow_cast(title.size()), - nullptr, - 0, - nullptr, - nullptr); - wistd::unique_ptr pszExpected = wil::make_unique_nothrow(iBytesNeeded); - VERIFY_IS_NOT_NULL(pszExpected); - - VERIFY_WIN32_BOOL_SUCCEEDED(WideCharToMultiByte(gci.OutputCP, - 0, - title.data(), - gsl::narrow_cast(title.size()), - pszExpected.get(), - iBytesNeeded, - nullptr, - nullptr)); + // SetTitle() runs some extra code. Let's not skip it since this is a test. + gci.SetTitle(L"Test window title."); + const auto pszExpected = til::u16u8(gci.GetTitle()); char pszTitle[MAX_PATH]; // most applications use MAX_PATH size_t cchWritten = 0; @@ -249,7 +229,7 @@ class ApiRoutinesTests // NOTE: W version of API returns string length. A version of API returns buffer length (string + null). VERIFY_ARE_EQUAL(gci.GetTitle().length() + 1, cchWritten); VERIFY_ARE_EQUAL(gci.GetTitle().length(), cchNeeded); - VERIFY_ARE_EQUAL(WEX::Common::String(pszExpected.get()), WEX::Common::String(pszTitle)); + VERIFY_ARE_EQUAL(std::string_view{ pszExpected }, std::string_view{ pszTitle }); } TEST_METHOD(ApiGetConsoleTitleW) From 31c66efae026b841123efc6999aeb91eec878d7d Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Sat, 19 Mar 2022 00:55:25 +0100 Subject: [PATCH 12/67] Make conhost history deduplication case-sensitive (#12700) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The legacy console used to use case-sensitive history deduplication and this change reverts the logic to restore ye olde history functionality. This commit additionally changes the other remaining `std::equal` plus `std::towlower` check into a `CompareStringOrdinal` call, just because that's what MSDN suggests to use in such situations. ## PR Checklist * [x] Closes #4186 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Enter `test /v` * Enter `test /V` * Browsing through the history yields both items ✅ (cherry picked from commit 6bc2b4af09cf3032e2fccd405302ffac70fd348c) --- src/host/history.cpp | 13 ++----------- src/host/ut_host/CommandLineTests.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/host/history.cpp b/src/host/history.cpp index 2b5adf86290..5c655d647e4 100644 --- a/src/host/history.cpp +++ b/src/host/history.cpp @@ -72,14 +72,9 @@ void CommandHistory::s_ResizeAll(const size_t commands) } } -static bool CaseInsensitiveEquality(wchar_t a, wchar_t b) -{ - return ::towlower(a) == ::towlower(b); -} - bool CommandHistory::IsAppNameMatch(const std::wstring_view other) const { - return std::equal(_appName.cbegin(), _appName.cend(), other.cbegin(), other.cend(), CaseInsensitiveEquality); + return CompareStringOrdinal(_appName.data(), gsl::narrow(_appName.size()), other.data(), gsl::narrow(other.size()), TRUE) == CSTR_EQUAL; } // Routine Description: @@ -534,11 +529,7 @@ std::wstring CommandHistory::Remove(const SHORT iDel) const auto& storedCommand = _commands.at(indexFound); if ((WI_IsFlagClear(options, MatchOptions::ExactMatch) && (givenCommand.size() <= storedCommand.size())) || (givenCommand.size() == storedCommand.size())) { - if (std::equal(storedCommand.begin(), - storedCommand.begin() + givenCommand.size(), - givenCommand.begin(), - givenCommand.end(), - CaseInsensitiveEquality)) + if (til::starts_with(storedCommand, givenCommand)) { return true; } diff --git a/src/host/ut_host/CommandLineTests.cpp b/src/host/ut_host/CommandLineTests.cpp index 78f253b1b13..6062690ea2a 100644 --- a/src/host/ut_host/CommandLineTests.cpp +++ b/src/host/ut_host/CommandLineTests.cpp @@ -450,20 +450,21 @@ class CommandLineTests VERIFY_SUCCEEDED(m_pHistory->Add(L"I'm a little teapot", false)); VERIFY_SUCCEEDED(m_pHistory->Add(L"short and stout", false)); VERIFY_SUCCEEDED(m_pHistory->Add(L"inflammable", false)); + VERIFY_SUCCEEDED(m_pHistory->Add(L"Indestructible", false)); - SetPrompt(cookedReadData, L"i"); + SetPrompt(cookedReadData, L"I"); auto& commandLine = CommandLine::Instance(); commandLine._cycleMatchingCommandHistoryToPrompt(cookedReadData); - VerifyPromptText(cookedReadData, L"inflammable"); + VerifyPromptText(cookedReadData, L"Indestructible"); - // make sure we skip to the next "i" history item + // make sure we skip to the next "I" history item commandLine._cycleMatchingCommandHistoryToPrompt(cookedReadData); VerifyPromptText(cookedReadData, L"I'm a little teapot"); // should cycle back to the start of the command history commandLine._cycleMatchingCommandHistoryToPrompt(cookedReadData); - VerifyPromptText(cookedReadData, L"inflammable"); + VerifyPromptText(cookedReadData, L"Indestructible"); } TEST_METHOD(CmdlineCtrlHomeFullwidthChars) From 660c000ee0d029e6bc469d017a6486ed9ebe82d8 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 22 Mar 2022 00:32:45 +0100 Subject: [PATCH 13/67] Force LTR / logical order for text in GdiEngine (#12722) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some applications like `vim -H` implement their own BiDi reordering. Previously we used `PolyTextOutW` which supported such arrangements, but with a0527a1 and the switch to `ExtTextOutW` we broke such applications. This commit restores the old behavior by reimplementing the basics of `ExtTextOutW`'s internal workings while enforcing LTR ordering. ## Validation Steps Performed * Create a text file with "ץחסק פחופפסנ חס קוח ז׳חסש ץקקטק פחטסץ" Viewing the text file with `vim -H` presents the contents as expected ✅ * Printing enwik8 is as fast as before ✅ * Font fallback for various eastern scripts in enwik8 works as expected ✅ * `DECDWL` double-width sequences ✅ * Horizontal scrolling (apart from producing expected artifacts) ✅ Closes #12294 (cherry picked from commit d97d9f0fcf89c3c772fcf8c776321e5cb01e26e6) --- .github/actions/spelling/expect/expect.txt | 6 +++ src/renderer/gdi/gdirenderer.hpp | 6 ++- src/renderer/gdi/lib/gdi.vcxproj | 7 +++- src/renderer/gdi/paint.cpp | 49 ++++++++++++++++++++-- src/renderer/gdi/precomp.h | 3 +- src/renderer/gdi/state.cpp | 19 +++------ 6 files changed, 70 insertions(+), 20 deletions(-) diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index e3277a26eed..2b04658e5b3 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -239,6 +239,7 @@ CHARSETINFO chcp checkbox checkboxes +Checkin chh Childitem chk @@ -915,6 +916,7 @@ getwriter GFEh Gfun gfx +GGI GHIJK GHIJKL GHIJKLM @@ -1092,6 +1094,7 @@ ifndef IFont ifstream IGNOREEND +IGNORELANGUAGE IHigh IHosted iid @@ -1458,6 +1461,7 @@ mscorlib msctf msctls msdata +MSDL msdn msft MSGCMDLINEF @@ -2229,6 +2233,7 @@ srect srv srvinit srvpipe +ssa ssh sstream stackoverflow @@ -2554,6 +2559,7 @@ USESHOWWINDOW USESIZE USESTDHANDLES ushort +usp USRDLL utf utils diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp index 6ae3b0e20ea..8b0cab05b4d 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -91,6 +91,8 @@ namespace Microsoft::Console::Render const int nIndex, const LONG dwNewLong) noexcept; + static bool FontHasWesternScript(HDC hdc); + bool _fPaintStarted; til::rect _invalidCharacters; @@ -138,13 +140,15 @@ namespace Microsoft::Console::Render COLORREF _lastFg; COLORREF _lastBg; - enum class FontType : size_t + enum class FontType : uint8_t { + Undefined, Default, Italic, Soft }; FontType _lastFontType; + bool _fontHasWesternScript = false; XFORM _currentLineTransform; LineRendition _currentLineRendition; diff --git a/src/renderer/gdi/lib/gdi.vcxproj b/src/renderer/gdi/lib/gdi.vcxproj index 1a1b96b3b62..bf1fe0758f9 100644 --- a/src/renderer/gdi/lib/gdi.vcxproj +++ b/src/renderer/gdi/lib/gdi.vcxproj @@ -6,7 +6,7 @@ gdi RendererGdi ConRenderGdi - StaticLibrary + StaticLibrary @@ -22,6 +22,11 @@ + + + usp10.lib;%(AdditionalDependencies) + + diff --git a/src/renderer/gdi/paint.cpp b/src/renderer/gdi/paint.cpp index 598ce348987..2a7c38ff443 100644 --- a/src/renderer/gdi/paint.cpp +++ b/src/renderer/gdi/paint.cpp @@ -11,6 +11,15 @@ using namespace Microsoft::Console::Render; +// This is an excerpt of GDI's FontHasWesternScript() as +// used by InternalTextOut() which is part of ExtTextOutW(). +bool GdiEngine::FontHasWesternScript(HDC hdc) +{ + WORD glyphs[4]; + return (GetGlyphIndicesW(hdc, L"dMr\"", 4, glyphs, GGI_MARK_NONEXISTING_GLYPHS) == 4) && + (glyphs[0] != 0xFFFF && glyphs[1] != 0xFFFF && glyphs[2] != 0xFFFF && glyphs[3] != 0xFFFF); +} + // Routine Description: // - Prepares internal structures for a painting operation. // Arguments: @@ -54,6 +63,8 @@ using namespace Microsoft::Console::Render; _debugContext = GetDC(_debugWindow); #endif + _lastFontType = FontType::Undefined; + return S_OK; } @@ -445,10 +456,42 @@ using namespace Microsoft::Console::Render; for (size_t i = 0; i != _cPolyText; ++i) { const auto& t = _pPolyText[i]; - if (!ExtTextOutW(_hdcMemoryContext, t.x, t.y, t.uiFlags, &t.rcl, t.lpstr, t.n, t.pdx)) + + // The following if/else replicates the essentials of how ExtTextOutW() without ETO_IGNORELANGUAGE works. + // See InternalTextOut(). + // + // Unlike the original, we don't check for `GetTextCharacterExtra(hdc) != 0`, + // because we don't ever call SetTextCharacterExtra() anyways. + // + // GH#12294: + // Additionally we set ss.fOverrideDirection to TRUE, because we need to present RTL + // text in logical order in order to be compatible with applications like `vim -H`. + if (_fontHasWesternScript && ScriptIsComplex(t.lpstr, t.n, SIC_COMPLEX) == S_FALSE) { - hr = E_FAIL; - break; + if (!ExtTextOutW(_hdcMemoryContext, t.x, t.y, t.uiFlags | ETO_IGNORELANGUAGE, &t.rcl, t.lpstr, t.n, t.pdx)) + { + hr = E_FAIL; + break; + } + } + else + { + SCRIPT_STATE ss{}; + ss.fOverrideDirection = TRUE; + + SCRIPT_STRING_ANALYSIS ssa; + hr = ScriptStringAnalyse(_hdcMemoryContext, t.lpstr, t.n, 0, -1, SSA_GLYPHS | SSA_FALLBACK, 0, nullptr, &ss, t.pdx, nullptr, nullptr, &ssa); + if (FAILED(hr)) + { + break; + } + + hr = ScriptStringOut(ssa, t.x, t.y, t.uiFlags, &t.rcl, 0, 0, FALSE); + std::ignore = ScriptStringFree(&ssa); + if (FAILED(hr)) + { + break; + } } } diff --git a/src/renderer/gdi/precomp.h b/src/renderer/gdi/precomp.h index 9043621d11e..4b402939d5e 100644 --- a/src/renderer/gdi/precomp.h +++ b/src/renderer/gdi/precomp.h @@ -16,8 +16,9 @@ Module Name: // This includes support libraries from the CRT, STL, WIL, and GSL #include "LibraryIncludes.h" -#include +#include #include +#include #ifndef _NTSTATUS_DEFINED #define _NTSTATUS_DEFINED diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp index 17b939591c2..0d36d39c6cd 100644 --- a/src/renderer/gdi/state.cpp +++ b/src/renderer/gdi/state.cpp @@ -29,7 +29,7 @@ GdiEngine::GdiEngine() : _fInvalidRectUsed(false), _lastFg(INVALID_COLOR), _lastBg(INVALID_COLOR), - _lastFontType(FontType::Default), + _lastFontType(FontType::Undefined), _currentLineTransform(IDENTITY_XFORM), _currentLineRendition(LineRendition::SingleWidth), _fPaintStarted(false), @@ -142,15 +142,6 @@ GdiEngine::~GdiEngine() _hwndTargetWindow = hwnd; _hdcMemoryContext = hdcNewMemoryContext; - // If we have a font, apply it to the context. - if (nullptr != _hfont) - { - LOG_HR_IF_NULL(E_FAIL, SelectFont(_hdcMemoryContext, _hfont)); - } - - // Record the fact that the selected font is the default. - _lastFontType = FontType::Default; - if (nullptr != hdcRealWindow) { LOG_HR_IF(E_FAIL, !(ReleaseDC(_hwndTargetWindow, hdcRealWindow))); @@ -327,6 +318,7 @@ GdiEngine::~GdiEngine() break; } _lastFontType = fontType; + _fontHasWesternScript = FontHasWesternScript(_hdcMemoryContext); } return S_OK; @@ -348,9 +340,6 @@ GdiEngine::~GdiEngine() // Select into DC RETURN_HR_IF_NULL(E_FAIL, SelectFont(_hdcMemoryContext, hFont.get())); - // Record the fact that the selected font is the default. - _lastFontType = FontType::Default; - // Save off the font metrics for various other calculations RETURN_HR_IF(E_FAIL, !(GetTextMetricsW(_hdcMemoryContext, &_tmFontMetrics))); @@ -456,7 +445,9 @@ GdiEngine::~GdiEngine() const SIZE cellSize, const size_t centeringHint) noexcept { - // If the soft font is currently selected, replace it with the default font. + // If we previously called SelectFont(_hdcMemoryContext, _softFont), it will + // still hold a reference to the _softFont object we're planning to overwrite. + // --> First revert back to the standard _hfont, lest we have dangling pointers. if (_lastFontType == FontType::Soft) { RETURN_HR_IF_NULL(E_FAIL, SelectFont(_hdcMemoryContext, _hfont)); From a06db87d7e762628ffed41bdc7c8bc16d8555830 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Wed, 23 Mar 2022 21:58:19 +0000 Subject: [PATCH 14/67] Merged PR 7106028: Delay-load usp10 in the Windows build PR #12722 introduced a dependency on usp10.dll. The Script* APIs are split between gdi32 and usp10, so we needed to add a new entry to the sources files for anybody who consumed the GDI renderer. --- src/host/sources.inc | 2 ++ src/interactivity/win32/ut_interactivity_win32/sources | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/host/sources.inc b/src/host/sources.inc index 042622c404e..6ab23269b8d 100644 --- a/src/host/sources.inc +++ b/src/host/sources.inc @@ -176,6 +176,7 @@ TARGETLIBS = \ $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \ $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \ $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \ + $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-usp10-l1.lib \ $(WINCORE_OBJ_PATH)\console\open\src\host\lib\$(O)\conhostv2.lib \ $(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \ $(WINCORE_OBJ_PATH)\console\open\src\buffer\out\lib\$(O)\conbufferout.lib \ @@ -210,6 +211,7 @@ DELAYLOAD = \ api-ms-win-shell-namespace-l1.dll; \ ext-ms-win-dwmapi-ext-l1.dll; \ ext-ms-win-edputil-policy-l1.dll; \ + ext-ms-win-usp10-l1.dll; \ ext-ms-win-gdi-dc-l1.dll; \ ext-ms-win-gdi-dc-create-l1.dll; \ ext-ms-win-gdi-draw-l1.dll; \ diff --git a/src/interactivity/win32/ut_interactivity_win32/sources b/src/interactivity/win32/ut_interactivity_win32/sources index 0be29330cb6..cf6c8f6bdf3 100644 --- a/src/interactivity/win32/ut_interactivity_win32/sources +++ b/src/interactivity/win32/ut_interactivity_win32/sources @@ -75,6 +75,7 @@ TARGETLIBS = \ $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \ $(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \ $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \ + $(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-usp10-l1.lib \ $(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \ $(WINCORE_OBJ_PATH)\console\open\src\buffer\out\lib\$(O)\conbufferout.lib \ $(WINCORE_OBJ_PATH)\console\open\src\host\lib\$(O)\conhostv2.lib \ @@ -137,6 +138,7 @@ DELAYLOAD = \ ext-ms-win-shell-shell32-l1.dll; \ ext-ms-win-uiacore-l1.dll; \ ext-ms-win-uxtheme-themes-l1.dll; \ + ext-ms-win-usp10-l1.dll; \ DLOAD_ERROR_HANDLER = kernelbase From d44117c755d547d7885bf015a57839f15e2ea395 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 23 Mar 2022 14:20:03 -0700 Subject: [PATCH 15/67] [Conhost] Notify UIA when letter deleted via backspace (#12735) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request Fixes a bug in ConHost where Narrator wouldn't read the deleted letter after the user pressed backspace. ## References MSFT:31748387 ## Detailed Description of the Pull Request / Additional comments `WriteCharsLegacy()` already calls `NotifyAccessibilityEventing()` when text is inserted into the buffer ([see code](https://github.com/microsoft/terminal/blob/855e1360c0ff810decf862f1d90e15b5f49e7bbd/src/host/_stream.cpp#L559-L563)). However, when backspace is pressed, the entire if-condition is skipped over, resulting in the accessibility event not being fired. `WriteCharsLegacy()` has a separate branch that is dedicated to handling backspace, so I added a call to the relevant logic to notify UIA at the end of that. ## Validation Steps Performed ✅ Backspace deletes a character and Narrator reads it ✅ Backspace still works with NVDA and JAWS (unchanged behavior) ✅ if the input buffer had wrapped text, the above scenario works as expected ✅ scenario works for CMD, PowerShell Core, and WSL --- src/host/_stream.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/host/_stream.cpp b/src/host/_stream.cpp index dfe8fd51e14..f7849ef991f 100644 --- a/src/host/_stream.cpp +++ b/src/host/_stream.cpp @@ -765,6 +765,15 @@ using Microsoft::Console::VirtualTerminal::StateMachine; Status = AdjustCursorPosition(screenInfo, CursorPosition, dwFlags & WC_KEEP_CURSOR_VISIBLE, psScrollY); } } + // Notify accessibility to read the backspaced character. + // See GH:12735, MSFT:31748387 + if (screenInfo.HasAccessibilityEventing()) + { + if (IConsoleWindow* pConsoleWindow = ServiceLocator::LocateConsoleWindow()) + { + LOG_IF_FAILED(pConsoleWindow->SignalUia(UIA_Text_TextChangedEventId)); + } + } break; } case UNICODE_TAB: From 73f02024d29cf558e42633f93e707631c306bf6f Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 24 Mar 2022 00:48:08 +0100 Subject: [PATCH 16/67] AtlasEngine: Fix grayscale blending shader (#12734) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5964060 contains a regression were the grayscale blending algorithm used the gamma corrected foreground color as the pixel color, instead of blending that color with the background color first. Due to that the background color got lost / got set to black. This breaks any dark-on-bright outputs. ## PR Checklist * [x] I work here * [x] Tests added/passed ## Validation Steps Performed All 3 "antialiasing" settings work just like in DxEngine. ✅ --- src/renderer/atlas/dwrite.hlsl | 3 ++- src/renderer/atlas/shader_ps.hlsl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/renderer/atlas/dwrite.hlsl b/src/renderer/atlas/dwrite.hlsl index 0f5c683bc5b..ad7493275b7 100644 --- a/src/renderer/atlas/dwrite.hlsl +++ b/src/renderer/atlas/dwrite.hlsl @@ -81,7 +81,8 @@ float4 DWrite_GrayscaleBlend(float4 gammaRatios, float grayscaleEnhancedContrast float blendEnhancedContrast = contrastBoost + DWrite_ApplyLightOnDarkContrastAdjustment(grayscaleEnhancedContrast, foregroundStraight); float intensity = DWrite_CalcColorIntensity(foregroundStraight); float contrasted = DWrite_EnhanceContrast(glyphAlpha, blendEnhancedContrast); - return foregroundColor * DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios); + float alphaCorrected = DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios); + return alphaCorrected * foregroundColor; } // Call this function to get the same gamma corrected alpha blending effect diff --git a/src/renderer/atlas/shader_ps.hlsl b/src/renderer/atlas/shader_ps.hlsl index fadbf3469d5..789cd98b00a 100644 --- a/src/renderer/atlas/shader_ps.hlsl +++ b/src/renderer/atlas/shader_ps.hlsl @@ -147,7 +147,8 @@ float4 main(float4 pos: SV_Position): SV_Target // See DWrite_GrayscaleBlend float intensity = DWrite_CalcColorIntensity(foregroundStraight); float contrasted = DWrite_EnhanceContrast(glyph.a, blendEnhancedContrast); - color = fg * DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios); + float4 alphaCorrected = DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios); + color = alphaBlendPremultiplied(color, alphaCorrected * fg); } } } From a638e0161b3a1fee2e564dd92e12eb8d51331a2c Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 24 Mar 2022 00:25:04 +0000 Subject: [PATCH 17/67] PR 7106673: [Git2Git] Remove the rest of IInputServices Since RS1 (CL 3427806), gdi32 has been available on OneCoreUAP-based editions of Windows. Therefore, we no longer need the indirect call to TranslateCharsetInfo and without that, IInputServices doesn't have a reason to exist. In an ideal world. Unfortunately, we actually do use IInputServices as a backhanded way to get at the ConIoSrvComm from other OneCoreInteractivity components... we also use it in a trick we play in RundownAndExit to make sure that the ConIoSrv connection tears down at the right time. I've replaced that trick with an equally dirty trick, but one that is *very explicit* about what it's doing. This change would break CJK+Grid Lines and GetConsoleLangID on OneCore-based editions that do not host the extension apiset ext-ms-win-gdi-font-l1... so we're falling back to the old ConIoSrvComm implementation directly in `dbcs.cpp`. Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 74ca635710701c45cda9eefd13dafc6f180feb49 Related work items: MSFT-38632962 --- src/host/dbcs.cpp | 32 +++++++++++-- .../base/InteractivityFactory.cpp | 43 ----------------- .../base/InteractivityFactory.hpp | 1 - src/interactivity/base/ServiceLocator.cpp | 40 +++++----------- .../base/lib/InteractivityBase.vcxproj | 1 - .../lib/InteractivityBase.vcxproj.filters | 3 -- src/interactivity/inc/IInputServices.hpp | 33 ------------- .../inc/IInteractivityFactory.hpp | 2 - src/interactivity/inc/Module.hpp | 1 - src/interactivity/inc/ServiceLocator.hpp | 13 ++--- src/interactivity/onecore/BgfxEngine.cpp | 4 +- src/interactivity/onecore/ConIoSrvComm.cpp | 47 +++++-------------- src/interactivity/onecore/ConIoSrvComm.hpp | 10 ++-- .../onecore/ConsoleInputThread.cpp | 9 +--- .../onecore/ConsoleInputThread.hpp | 5 -- src/interactivity/onecore/WindowMetrics.cpp | 2 +- .../onecore/lib/onecore.LIB.vcxproj | 2 - .../onecore/lib/onecore.LIB.vcxproj.filters | 8 +--- src/interactivity/win32/InputServices.cpp | 15 ------ src/interactivity/win32/InputServices.hpp | 26 ---------- src/interactivity/win32/lib/win32.LIB.vcxproj | 2 - .../win32/lib/win32.LIB.vcxproj.filters | 8 +--- src/interactivity/win32/sources.inc | 1 - 23 files changed, 69 insertions(+), 239 deletions(-) delete mode 100644 src/interactivity/inc/IInputServices.hpp delete mode 100644 src/interactivity/win32/InputServices.cpp delete mode 100644 src/interactivity/win32/InputServices.hpp diff --git a/src/host/dbcs.cpp b/src/host/dbcs.cpp index eebfcf52a7e..2a25141f159 100644 --- a/src/host/dbcs.cpp +++ b/src/host/dbcs.cpp @@ -127,12 +127,36 @@ bool IsDBCSLeadByteConsole(const CHAR ch, const CPINFO* const pCPInfo) BYTE CodePageToCharSet(const UINT uiCodePage) { - CHARSETINFO csi; + CHARSETINFO csi{}; - const auto inputServices = ServiceLocator::LocateInputServices(); - if (nullptr == inputServices || !inputServices->TranslateCharsetInfo((DWORD*)IntToPtr(uiCodePage), &csi, TCI_SRCCODEPAGE)) + if (!TranslateCharsetInfo((DWORD*)IntToPtr(uiCodePage), &csi, TCI_SRCCODEPAGE)) { - csi.ciCharset = OEM_CHARSET; + // On OneCore-based editions of Windows, the extension APIset containing + // TranslateCharsetInfo is not hosted. OneCoreUAP hosts it, but the lower + // editions do not. If we find that we failed to delay-load it, fall back + // to our "simple" OneCore-OK implementation. + if (GetLastError() == ERROR_PROC_NOT_FOUND) + { + switch (uiCodePage) + { + case CP_JAPANESE: + csi.ciCharset = SHIFTJIS_CHARSET; + break; + case CP_CHINESE_SIMPLIFIED: + csi.ciCharset = GB2312_CHARSET; + break; + case CP_KOREAN: + csi.ciCharset = HANGEUL_CHARSET; + break; + case CP_CHINESE_TRADITIONAL: + csi.ciCharset = CHINESEBIG5_CHARSET; + break; + } + } + else + { + csi.ciCharset = OEM_CHARSET; + } } return (BYTE)csi.ciCharset; diff --git a/src/interactivity/base/InteractivityFactory.cpp b/src/interactivity/base/InteractivityFactory.cpp index 3c69ebb46bf..fd93f6ec158 100644 --- a/src/interactivity/base/InteractivityFactory.cpp +++ b/src/interactivity/base/InteractivityFactory.cpp @@ -18,7 +18,6 @@ #include "../win32/AccessibilityNotifier.hpp" #include "../win32/ConsoleControl.hpp" #include "../win32/ConsoleInputThread.hpp" -#include "../win32/InputServices.hpp" #include "../win32/WindowDpiApi.hpp" #include "../win32/WindowMetrics.hpp" #include "../win32/SystemConfigurationProvider.hpp" @@ -282,48 +281,6 @@ using namespace Microsoft::Console::Interactivity; return status; } -[[nodiscard]] NTSTATUS InteractivityFactory::CreateInputServices(_Inout_ std::unique_ptr& services) -{ - NTSTATUS status = STATUS_SUCCESS; - - ApiLevel level; - status = ApiDetector::DetectNtUserWindow(&level); - - if (NT_SUCCESS(status)) - { - std::unique_ptr newServices; - try - { - switch (level) - { - case ApiLevel::Win32: - newServices = std::make_unique(); - break; - -#ifdef BUILD_ONECORE_INTERACTIVITY - case ApiLevel::OneCore: - newServices = std::make_unique(); - break; -#endif - default: - status = STATUS_INVALID_LEVEL; - break; - } - } - catch (...) - { - status = NTSTATUS_FROM_HRESULT(wil::ResultFromCaughtException()); - } - - if (NT_SUCCESS(status)) - { - services.swap(newServices); - } - } - - return status; -} - // Method Description: // - Attempts to instantiate a "pseudo window" for when we're operating in // pseudoconsole mode. There are some tools (cygwin & derivatives) that use diff --git a/src/interactivity/base/InteractivityFactory.hpp b/src/interactivity/base/InteractivityFactory.hpp index bf08158343f..97ac10d3b9f 100644 --- a/src/interactivity/base/InteractivityFactory.hpp +++ b/src/interactivity/base/InteractivityFactory.hpp @@ -25,7 +25,6 @@ namespace Microsoft::Console::Interactivity [[nodiscard]] NTSTATUS CreateWindowMetrics(_Inout_ std::unique_ptr& metrics); [[nodiscard]] NTSTATUS CreateAccessibilityNotifier(_Inout_ std::unique_ptr& notifier); [[nodiscard]] NTSTATUS CreateSystemConfigurationProvider(_Inout_ std::unique_ptr& provider); - [[nodiscard]] NTSTATUS CreateInputServices(_Inout_ std::unique_ptr& services); [[nodiscard]] NTSTATUS CreatePseudoWindow(HWND& hwnd); }; diff --git a/src/interactivity/base/ServiceLocator.cpp b/src/interactivity/base/ServiceLocator.cpp index 3bc691abdc6..91a56d2e5a8 100644 --- a/src/interactivity/base/ServiceLocator.cpp +++ b/src/interactivity/base/ServiceLocator.cpp @@ -21,10 +21,11 @@ std::unique_ptr ServiceLocator::s_windowMetrics; std::unique_ptr ServiceLocator::s_accessibilityNotifier; std::unique_ptr ServiceLocator::s_highDpiApi; std::unique_ptr ServiceLocator::s_systemConfigurationProvider; -std::unique_ptr ServiceLocator::s_inputServices; IConsoleWindow* ServiceLocator::s_consoleWindow = nullptr; +void (*ServiceLocator::s_oneCoreTeardownFunction)() = nullptr; + Globals ServiceLocator::s_globals; bool ServiceLocator::s_pseudoWindowInitialized = false; @@ -34,6 +35,12 @@ wil::unique_hwnd ServiceLocator::s_pseudoWindow = nullptr; #pragma region Public Methods +void ServiceLocator::SetOneCoreTeardownFunction(void (*pfn)()) noexcept +{ + FAIL_FAST_IF(nullptr != s_oneCoreTeardownFunction); + s_oneCoreTeardownFunction = pfn; +} + [[noreturn]] void ServiceLocator::RundownAndExit(const HRESULT hr) { // MSFT:15506250 @@ -59,14 +66,13 @@ wil::unique_hwnd ServiceLocator::s_pseudoWindow = nullptr; // We don't want to have other execution in the system get stuck, so this is a great // place to clean up and notify any objects or threads in the system that have to cleanup safely before // we head into TerminateProcess and tear everything else down less gracefully. - - // TODO: MSFT: 14397093 - Expand graceful rundown beyond just the Hot Bug input services case. - - if (s_inputServices.get() != nullptr) + if (s_oneCoreTeardownFunction) { - s_inputServices.reset(nullptr); + s_oneCoreTeardownFunction(); } + // TODO: MSFT: 14397093 - Expand graceful rundown beyond just the Hot Bug input services case. + ExitProcess(hr); } @@ -267,28 +273,6 @@ ISystemConfigurationProvider* ServiceLocator::LocateSystemConfigurationProvider( return s_systemConfigurationProvider.get(); } -IInputServices* ServiceLocator::LocateInputServices() -{ - NTSTATUS status = STATUS_SUCCESS; - - if (!s_inputServices) - { - if (s_interactivityFactory.get() == nullptr) - { - status = ServiceLocator::LoadInteractivityFactory(); - } - - if (NT_SUCCESS(status)) - { - status = s_interactivityFactory->CreateInputServices(s_inputServices); - } - } - - LOG_IF_NTSTATUS_FAILED(status); - - return s_inputServices.get(); -} - Globals& ServiceLocator::LocateGlobals() { return s_globals; diff --git a/src/interactivity/base/lib/InteractivityBase.vcxproj b/src/interactivity/base/lib/InteractivityBase.vcxproj index 5f3f7c4e8e5..0161b56daa4 100644 --- a/src/interactivity/base/lib/InteractivityBase.vcxproj +++ b/src/interactivity/base/lib/InteractivityBase.vcxproj @@ -36,7 +36,6 @@ - diff --git a/src/interactivity/base/lib/InteractivityBase.vcxproj.filters b/src/interactivity/base/lib/InteractivityBase.vcxproj.filters index 4c7b8495037..5b833a07127 100644 --- a/src/interactivity/base/lib/InteractivityBase.vcxproj.filters +++ b/src/interactivity/base/lib/InteractivityBase.vcxproj.filters @@ -62,9 +62,6 @@ Header Files - - Header Files - Header Files diff --git a/src/interactivity/inc/IInputServices.hpp b/src/interactivity/inc/IInputServices.hpp deleted file mode 100644 index 390a76a5e40..00000000000 --- a/src/interactivity/inc/IInputServices.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation -Licensed under the MIT license. - -Module Name: -- IInputServices.hpp - -Abstract: -- Defines the methods used by the console to process input. - -Author(s): -- Hernan Gatta (HeGatta) 29-Mar-2017 ---*/ - -#pragma once - -namespace Microsoft::Console::Interactivity -{ - class IInputServices - { - public: - virtual BOOL TranslateCharsetInfo(_Inout_ DWORD FAR* lpSrc, _Out_ LPCHARSETINFO lpCs, _In_ DWORD dwFlags) = 0; - virtual ~IInputServices() = 0; - - protected: - IInputServices() {} - - IInputServices(IInputServices const&) = delete; - IInputServices& operator=(IInputServices const&) = delete; - }; - - inline IInputServices::~IInputServices() {} -} diff --git a/src/interactivity/inc/IInteractivityFactory.hpp b/src/interactivity/inc/IInteractivityFactory.hpp index 4996f30d689..65c28428b4f 100644 --- a/src/interactivity/inc/IInteractivityFactory.hpp +++ b/src/interactivity/inc/IInteractivityFactory.hpp @@ -23,7 +23,6 @@ Author(s): #include "IWindowMetrics.hpp" #include "IAccessibilityNotifier.hpp" #include "ISystemConfigurationProvider.hpp" -#include "IInputServices.hpp" #include @@ -40,7 +39,6 @@ namespace Microsoft::Console::Interactivity [[nodiscard]] virtual NTSTATUS CreateWindowMetrics(_Inout_ std::unique_ptr& metrics) = 0; [[nodiscard]] virtual NTSTATUS CreateAccessibilityNotifier(_Inout_ std::unique_ptr& notifier) = 0; [[nodiscard]] virtual NTSTATUS CreateSystemConfigurationProvider(_Inout_ std::unique_ptr& provider) = 0; - [[nodiscard]] virtual NTSTATUS CreateInputServices(_Inout_ std::unique_ptr& services) = 0; [[nodiscard]] virtual NTSTATUS CreatePseudoWindow(HWND& hwnd) = 0; }; diff --git a/src/interactivity/inc/Module.hpp b/src/interactivity/inc/Module.hpp index cea667e43c0..320566a6e7b 100644 --- a/src/interactivity/inc/Module.hpp +++ b/src/interactivity/inc/Module.hpp @@ -24,7 +24,6 @@ namespace Microsoft::Console::Interactivity ConsoleInputThread, ConsoleWindowMetrics, HighDpiApi, - InputServices, SystemConfigurationProvider }; } diff --git a/src/interactivity/inc/ServiceLocator.hpp b/src/interactivity/inc/ServiceLocator.hpp index 41e27bcdf9f..5b6aaee499f 100644 --- a/src/interactivity/inc/ServiceLocator.hpp +++ b/src/interactivity/inc/ServiceLocator.hpp @@ -30,6 +30,8 @@ namespace Microsoft::Console::Interactivity class ServiceLocator final { public: + static void SetOneCoreTeardownFunction(void (*pfn)()) noexcept; + [[noreturn]] static void RundownAndExit(const HRESULT hr); // N.B.: Location methods without corresponding creation methods @@ -78,13 +80,6 @@ namespace Microsoft::Console::Interactivity return static_cast(LocateHighDpiApi()); } - static IInputServices* LocateInputServices(); - template - static T* LocateInputServices() - { - return static_cast(LocateInputServices()); - } - static ISystemConfigurationProvider* LocateSystemConfigurationProvider(); static Globals& LocateGlobals(); @@ -110,7 +105,9 @@ namespace Microsoft::Console::Interactivity static std::unique_ptr s_windowMetrics; static std::unique_ptr s_highDpiApi; static std::unique_ptr s_systemConfigurationProvider; - static std::unique_ptr s_inputServices; + + // See the big block comment in RundownAndExit for more info. + static void (*s_oneCoreTeardownFunction)(); static Globals s_globals; static bool s_pseudoWindowInitialized; diff --git a/src/interactivity/onecore/BgfxEngine.cpp b/src/interactivity/onecore/BgfxEngine.cpp index 87484455935..b3bdd606651 100644 --- a/src/interactivity/onecore/BgfxEngine.cpp +++ b/src/interactivity/onecore/BgfxEngine.cpp @@ -87,7 +87,7 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid PVOID OldRunBase; PVOID NewRunBase; - Status = ServiceLocator::LocateInputServices()->RequestUpdateDisplay(0); + Status = ConIoSrvComm::GetConIoSrvComm()->RequestUpdateDisplay(0); if (NT_SUCCESS(Status)) { @@ -189,7 +189,7 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid CursorInfo.Height = options.ulCursorHeightPercent; CursorInfo.IsVisible = TRUE; - NTSTATUS Status = ServiceLocator::LocateInputServices()->RequestSetCursor(&CursorInfo); + NTSTATUS Status = ConIoSrvComm::GetConIoSrvComm()->RequestSetCursor(&CursorInfo); return HRESULT_FROM_NT(Status); } diff --git a/src/interactivity/onecore/ConIoSrvComm.cpp b/src/interactivity/onecore/ConIoSrvComm.cpp index c65ad00c0c7..f33e2cb1a08 100644 --- a/src/interactivity/onecore/ConIoSrvComm.cpp +++ b/src/interactivity/onecore/ConIoSrvComm.cpp @@ -24,6 +24,19 @@ extern void UnlockConsole(); using namespace Microsoft::Console::Render; using namespace Microsoft::Console::Interactivity::OneCore; +static std::unique_ptr s_conIoSrvComm; +ConIoSrvComm* ConIoSrvComm::GetConIoSrvComm() +{ + static bool initialized = []() { + s_conIoSrvComm = std::make_unique(); + ServiceLocator::SetOneCoreTeardownFunction([] { + s_conIoSrvComm.reset(nullptr); + }); + return true; + }(); + return s_conIoSrvComm.get(); +} + ConIoSrvComm::ConIoSrvComm() : _inputPipeThreadHandle(nullptr), _pipeReadHandle(INVALID_HANDLE_VALUE), @@ -536,40 +549,6 @@ PVOID ConIoSrvComm::GetSharedViewBase() const #pragma endregion -#pragma region IInputServices Members - -BOOL ConIoSrvComm::TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags) -{ - SetLastError(ERROR_SUCCESS); - - if (TCI_SRCCODEPAGE == dwFlags) - { - *lpCs = { 0 }; - - DWORD dwSrc = (DWORD)lpSrc; - switch (dwSrc) - { - case CP_JAPANESE: - lpCs->ciCharset = SHIFTJIS_CHARSET; - return TRUE; - case CP_CHINESE_SIMPLIFIED: - lpCs->ciCharset = GB2312_CHARSET; - return TRUE; - case CP_KOREAN: - lpCs->ciCharset = HANGEUL_CHARSET; - return TRUE; - case CP_CHINESE_TRADITIONAL: - lpCs->ciCharset = CHINESEBIG5_CHARSET; - return TRUE; - } - } - - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; -} - -#pragma endregion - [[nodiscard]] NTSTATUS ConIoSrvComm::InitializeBgfx() { NTSTATUS Status; diff --git a/src/interactivity/onecore/ConIoSrvComm.hpp b/src/interactivity/onecore/ConIoSrvComm.hpp index 4a52ed53617..b94c1f226f6 100644 --- a/src/interactivity/onecore/ConIoSrvComm.hpp +++ b/src/interactivity/onecore/ConIoSrvComm.hpp @@ -17,7 +17,6 @@ Author(s): #include #include "ConIoSrv.h" -#include "../../inc/IInputServices.hpp" #include "BgfxEngine.hpp" #include "../../renderer/wddmcon/wddmconrenderer.hpp" @@ -26,11 +25,13 @@ Author(s): namespace Microsoft::Console::Interactivity::OneCore { - class ConIoSrvComm final : public IInputServices + class ConIoSrvComm final { public: ConIoSrvComm(); - ~ConIoSrvComm() override; + ~ConIoSrvComm(); + + static ConIoSrvComm* GetConIoSrvComm(); [[nodiscard]] NTSTATUS Connect(); VOID ServiceInputPipe(); @@ -46,9 +47,6 @@ namespace Microsoft::Console::Interactivity::OneCore VOID CleanupForHeadless(const NTSTATUS status); - // IInputServices Members - BOOL TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags); - [[nodiscard]] NTSTATUS InitializeBgfx(); [[nodiscard]] NTSTATUS InitializeWddmCon(); diff --git a/src/interactivity/onecore/ConsoleInputThread.cpp b/src/interactivity/onecore/ConsoleInputThread.cpp index b49b06fbf2b..53a3949c882 100644 --- a/src/interactivity/onecore/ConsoleInputThread.cpp +++ b/src/interactivity/onecore/ConsoleInputThread.cpp @@ -19,7 +19,7 @@ using namespace Microsoft::Console::Interactivity::OneCore; DWORD WINAPI ConsoleInputThreadProcOneCore(LPVOID /*lpParam*/) { Globals& globals = ServiceLocator::LocateGlobals(); - ConIoSrvComm* const Server = ServiceLocator::LocateInputServices(); + ConIoSrvComm* const Server = ConIoSrvComm::GetConIoSrvComm(); NTSTATUS Status = Server->Connect(); @@ -114,7 +114,7 @@ HANDLE ConsoleInputThread::Start() hThread = CreateThread(nullptr, 0, ConsoleInputThreadProcOneCore, - _pConIoSrvComm, + nullptr, 0, &dwThreadId); if (hThread) @@ -125,8 +125,3 @@ HANDLE ConsoleInputThread::Start() return hThread; } - -ConIoSrvComm* ConsoleInputThread::GetConIoSrvComm() -{ - return _pConIoSrvComm; -} diff --git a/src/interactivity/onecore/ConsoleInputThread.hpp b/src/interactivity/onecore/ConsoleInputThread.hpp index fef4fedee91..f47072f9d2e 100644 --- a/src/interactivity/onecore/ConsoleInputThread.hpp +++ b/src/interactivity/onecore/ConsoleInputThread.hpp @@ -25,10 +25,5 @@ namespace Microsoft::Console::Interactivity::OneCore { public: HANDLE Start(); - - ConIoSrvComm* GetConIoSrvComm(); - - private: - ConIoSrvComm* _pConIoSrvComm; }; } diff --git a/src/interactivity/onecore/WindowMetrics.cpp b/src/interactivity/onecore/WindowMetrics.cpp index ed38cac4fd6..f5721094576 100644 --- a/src/interactivity/onecore/WindowMetrics.cpp +++ b/src/interactivity/onecore/WindowMetrics.cpp @@ -46,7 +46,7 @@ RECT WindowMetrics::GetMinClientRectInPixels() USHORT DisplayMode; // Fetch a reference to the Console IO Server. - Server = ServiceLocator::LocateInputServices(); + Server = ConIoSrvComm::GetConIoSrvComm(); // Figure out what kind of display we are using. DisplayMode = Server->GetDisplayMode(); diff --git a/src/interactivity/onecore/lib/onecore.LIB.vcxproj b/src/interactivity/onecore/lib/onecore.LIB.vcxproj index 70c6fb4cb26..69fb551c0f8 100644 --- a/src/interactivity/onecore/lib/onecore.LIB.vcxproj +++ b/src/interactivity/onecore/lib/onecore.LIB.vcxproj @@ -20,7 +20,6 @@ - Create @@ -33,7 +32,6 @@ - diff --git a/src/interactivity/onecore/lib/onecore.LIB.vcxproj.filters b/src/interactivity/onecore/lib/onecore.LIB.vcxproj.filters index 3d23865a357..203fc8a4bae 100644 --- a/src/interactivity/onecore/lib/onecore.LIB.vcxproj.filters +++ b/src/interactivity/onecore/lib/onecore.LIB.vcxproj.filters @@ -39,9 +39,6 @@ Source Files - - Source Files - @@ -68,8 +65,5 @@ Header Files - - Header Files - - \ No newline at end of file + diff --git a/src/interactivity/win32/InputServices.cpp b/src/interactivity/win32/InputServices.cpp deleted file mode 100644 index 44014fd9284..00000000000 --- a/src/interactivity/win32/InputServices.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#include "precomp.h" - -#include "InputServices.hpp" - -#pragma hdrstop - -using namespace Microsoft::Console::Interactivity::Win32; - -BOOL InputServices::TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags) -{ - return ::TranslateCharsetInfo(lpSrc, lpCs, dwFlags); -} diff --git a/src/interactivity/win32/InputServices.hpp b/src/interactivity/win32/InputServices.hpp deleted file mode 100644 index 00d74b1cabb..00000000000 --- a/src/interactivity/win32/InputServices.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation -Licensed under the MIT license. - -Module Name: -- InputServices.hpp - -Abstract: -- Win32 implementation of the IInputServices interface. - -Author(s): -- Hernan Gatta (HeGatta) 29-Mar-2017 ---*/ - -#include "../inc/IInputServices.hpp" - -namespace Microsoft::Console::Interactivity::Win32 -{ - class InputServices final : public IInputServices - { - public: - // Inherited via IInputServices - ~InputServices() = default; - BOOL TranslateCharsetInfo(DWORD* lpSrc, LPCHARSETINFO lpCs, DWORD dwFlags); - }; -} diff --git a/src/interactivity/win32/lib/win32.LIB.vcxproj b/src/interactivity/win32/lib/win32.LIB.vcxproj index a29cec6458d..82a57c12398 100644 --- a/src/interactivity/win32/lib/win32.LIB.vcxproj +++ b/src/interactivity/win32/lib/win32.LIB.vcxproj @@ -22,7 +22,6 @@ - Create @@ -46,7 +45,6 @@ - diff --git a/src/interactivity/win32/lib/win32.LIB.vcxproj.filters b/src/interactivity/win32/lib/win32.LIB.vcxproj.filters index 4204622caea..52ecd14f5b7 100644 --- a/src/interactivity/win32/lib/win32.LIB.vcxproj.filters +++ b/src/interactivity/win32/lib/win32.LIB.vcxproj.filters @@ -63,9 +63,6 @@ Source Files - - Source Files - Source Files @@ -125,9 +122,6 @@ Header Files - - Header Files - Header Files @@ -141,4 +135,4 @@ - \ No newline at end of file + diff --git a/src/interactivity/win32/sources.inc b/src/interactivity/win32/sources.inc index 25d12cc0685..3580a5d6186 100644 --- a/src/interactivity/win32/sources.inc +++ b/src/interactivity/win32/sources.inc @@ -44,7 +44,6 @@ SOURCES = \ ..\consoleKeyInfo.cpp \ ..\find.cpp \ ..\icon.cpp \ - ..\InputServices.cpp \ ..\menu.cpp \ ..\screenInfoUiaProvider.cpp \ ..\SystemConfigurationProvider.cpp \ From 8ec87dff56a1e9866c1200dc351ec81372d00d40 Mon Sep 17 00:00:00 2001 From: Kayla Cinnamon Date: Thu, 24 Mar 2022 10:54:12 -0700 Subject: [PATCH 18/67] Change trimBlockSelection default to true (#12737) Changed the default value of `"trimBlockSelection"` to `true`. * [x] Closes #12536 ## Validation Steps Performed Without editing the setting, the toggle switch was enabled by default in the settings UI. --- doc/cascadia/profiles.schema.json | 2 +- src/cascadia/TerminalSettingsModel/MTSMSettings.h | 2 +- src/cascadia/TerminalSettingsModel/TerminalSettings.h | 2 +- src/cascadia/TerminalSettingsModel/defaults.json | 2 +- src/cascadia/inc/ControlProperties.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 3a401661150..ac7ab589514 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -1633,7 +1633,7 @@ "$ref": "#/$defs/CopyFormat" }, "trimBlockSelection": { - "default": false, + "default": true, "description": "When set to true, trailing white-spaces will be removed from text in rectangular (block) selection while copied to your clipboard. When set to false, the white-spaces will be preserved.", "type": "boolean" }, diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h index f2f95a562f5..5cba5156767 100644 --- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h +++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h @@ -27,7 +27,7 @@ Author(s): X(bool, ForceFullRepaintRendering, "experimental.rendering.forceFullRepaint", false) \ X(bool, SoftwareRendering, "experimental.rendering.software", false) \ X(bool, ForceVTInput, "experimental.input.forceVT", false) \ - X(bool, TrimBlockSelection, "trimBlockSelection", false) \ + X(bool, TrimBlockSelection, "trimBlockSelection", true) \ X(bool, DetectURLs, "experimental.detectURLs", true) \ X(bool, AlwaysShowTabs, "alwaysShowTabs", true) \ X(bool, ShowTitleInTitlebar, "showTerminalTitleInTitlebar", true) \ diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index 6409a2861fc..909ad8ab37a 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -89,7 +89,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::TerminalSettings, hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS); INHERITABLE_SETTING(Model::TerminalSettings, bool, CopyOnSelect, false); INHERITABLE_SETTING(Model::TerminalSettings, bool, FocusFollowMouse, false); - INHERITABLE_SETTING(Model::TerminalSettings, bool, TrimBlockSelection, false); + INHERITABLE_SETTING(Model::TerminalSettings, bool, TrimBlockSelection, true); INHERITABLE_SETTING(Model::TerminalSettings, bool, DetectURLs, true); INHERITABLE_SETTING(Model::TerminalSettings, Windows::Foundation::IReference, TabColor, nullptr); diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 89f78f630ff..7bff00a7f7b 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -11,7 +11,7 @@ // Selection "copyOnSelect": false, "copyFormatting": true, - "trimBlockSelection": false, + "trimBlockSelection": true, "trimPaste": true, "wordDelimiters": " /\\()\"'-.,:;<>~!@#$%^&*|+=[]{}~?\u2502", diff --git a/src/cascadia/inc/ControlProperties.h b/src/cascadia/inc/ControlProperties.h index 8243177ce11..171cbb7eb4b 100644 --- a/src/cascadia/inc/ControlProperties.h +++ b/src/cascadia/inc/ControlProperties.h @@ -41,7 +41,7 @@ X(bool, FocusFollowMouse, false) \ X(winrt::Windows::Foundation::IReference, TabColor, nullptr) \ X(winrt::Windows::Foundation::IReference, StartingTabColor, nullptr) \ - X(bool, TrimBlockSelection, false) \ + X(bool, TrimBlockSelection, true) \ X(bool, SuppressApplicationTitle) \ X(bool, ForceVTInput, false) \ X(winrt::hstring, StartingTitle) \ From 9fa4169d67f224bcf0577fdc551818ec7ad83b69 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 24 Mar 2022 18:56:11 +0100 Subject: [PATCH 19/67] Fix engine size not being changed on DPI changes (#12713) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we would only call `SetWindowSize` and `TriggerRedrawAll` if the viewport size in characters changed. This commit removes the limitation. Since the if-condition limiting full redraws is now gone, this commit moves the responsibility of limiting the calls up the call chain. With `_refreshSizeUnderLock` now being a heavier function call than before, some surrounding code was thus refactored. ## PR Checklist * [x] Closes #11317 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed Test relevant for #11317: * Print text, filling the entire window * Move the window from a 150% scale to a 300% scale monitor * The application works as expected ✅ Regression tests: * Text zoom with Ctrl+Plus/Minus/0 works as before ✅ * Resizing a window works as before ✅ * No deadlocks, etc. during settings updates ✅ --- src/cascadia/TerminalControl/ControlCore.cpp | 156 +++++++------------ src/cascadia/TerminalControl/ControlCore.h | 4 +- 2 files changed, 54 insertions(+), 106 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 21a71077389..f473a817439 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -620,19 +620,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _runtimeUseAcrylic = true; } - // Initialize our font information. - const auto fontFace = _settings->FontFace(); - const short fontHeight = ::base::saturated_cast(_settings->FontSize()); - const auto fontWeight = _settings->FontWeight(); - // The font width doesn't terribly matter, we'll only be using the - // height to look it up - // The other params here also largely don't matter. - // The family is only used to determine if the font is truetype or - // not, but DX doesn't use that info at all. - // The Codepage is additionally not actually used by the DX engine at all. - _actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontHeight }, CP_UTF8, false }; - _actualFontFaceName = { fontFace }; - _desiredFont = { _actualFont }; + const auto sizeChanged = _setFontSizeUnderLock(_settings->FontSize()); // Update the terminal core with its new Core settings _terminal->UpdateSettings(*_settings); @@ -651,11 +639,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _updateAntiAliasingMode(); - // Refresh our font with the renderer - const auto actualFontOldSize = _actualFont.GetSize(); - _updateFont(); - const auto actualFontNewSize = _actualFont.GetSize(); - if (actualFontNewSize != actualFontOldSize) + if (sizeChanged) { _refreshSizeUnderLock(); } @@ -768,30 +752,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - Set the font size of the terminal control. // Arguments: // - fontSize: The size of the font. - void ControlCore::_setFontSize(int fontSize) + // Return Value: + // - Returns true if you need to call _refreshSizeUnderLock(). + bool ControlCore::_setFontSizeUnderLock(int fontSize) { - try - { - // Make sure we have a non-zero font size - const auto newSize = std::max(gsl::narrow_cast(fontSize), 1); - const auto fontFace = _settings->FontFace(); - const auto fontWeight = _settings->FontWeight(); - _actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false }; - _actualFontFaceName = { fontFace }; - _desiredFont = { _actualFont }; - - auto lock = _terminal->LockForWriting(); - - // Refresh our font with the renderer - _updateFont(); - - // Resize the terminal's BUFFER to match the new font size. This does - // NOT change the size of the window, because that can lead to more - // problems (like what happens when you change the font size while the - // window is maximized?) - _refreshSizeUnderLock(); - } - CATCH_LOG(); + // Make sure we have a non-zero font size + const auto newSize = std::max(gsl::narrow_cast(fontSize), 1); + const auto fontFace = _settings->FontFace(); + const auto fontWeight = _settings->FontWeight(); + _actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false }; + _actualFontFaceName = { fontFace }; + _desiredFont = { _actualFont }; + + const auto before = _actualFont.GetSize(); + _updateFont(); + const auto after = _actualFont.GetSize(); + return before != after; } // Method Description: @@ -800,7 +776,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - none void ControlCore::ResetFontSize() { - _setFontSize(_settings->FontSize()); + const auto lock = _terminal->LockForWriting(); + + if (_setFontSizeUnderLock(_settings->FontSize())) + { + _refreshSizeUnderLock(); + } } // Method Description: @@ -809,69 +790,46 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - fontSizeDelta: The amount to increase or decrease the font size by. void ControlCore::AdjustFontSize(int fontSizeDelta) { - const auto newSize = _desiredFont.GetEngineSize().Y + fontSizeDelta; - _setFontSize(newSize); + const auto lock = _terminal->LockForWriting(); + + if (_setFontSizeUnderLock(_desiredFont.GetEngineSize().Y + fontSizeDelta)) + { + _refreshSizeUnderLock(); + } } // Method Description: - // - Perform a resize for the current size of the swapchainpanel. If the - // font size changed, we'll need to resize the buffer to fit the existing - // swapchain size. This helper will call _doResizeUnderLock with the - // current size of the swapchain, accounting for scaling due to DPI. + // - Process a resize event that was initiated by the user. This can either + // be due to the user resizing the window (causing the swapchain to + // resize) or due to the DPI changing (causing us to need to resize the + // buffer to match) // - Note that a DPI change will also trigger a font size change, and will // call into here. // - The write lock should be held when calling this method, we might be - // changing the buffer size in _doResizeUnderLock. + // changing the buffer size in _refreshSizeUnderLock. // Arguments: // - // Return Value: // - void ControlCore::_refreshSizeUnderLock() { - const auto widthInPixels = _panelWidth * _compositionScale; - const auto heightInPixels = _panelHeight * _compositionScale; - - _doResizeUnderLock(widthInPixels, heightInPixels); - } - - // Method Description: - // - Process a resize event that was initiated by the user. This can either - // be due to the user resizing the window (causing the swapchain to - // resize) or due to the DPI changing (causing us to need to resize the - // buffer to match) - // Arguments: - // - newWidth: the new width of the swapchain, in pixels. - // - newHeight: the new height of the swapchain, in pixels. - void ControlCore::_doResizeUnderLock(const double newWidth, - const double newHeight) - { - SIZE size; - size.cx = static_cast(newWidth); - size.cy = static_cast(newHeight); + auto cx = gsl::narrow_cast(_panelWidth * _compositionScale); + auto cy = gsl::narrow_cast(_panelHeight * _compositionScale); // Don't actually resize so small that a single character wouldn't fit // in either dimension. The buffer really doesn't like being size 0. - if (size.cx < _actualFont.GetSize().X || size.cy < _actualFont.GetSize().Y) - { - return; - } + cx = std::max(cx, _actualFont.GetSize().X); + cy = std::max(cy, _actualFont.GetSize().Y); // Convert our new dimensions to characters - const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, - { static_cast(size.cx), static_cast(size.cy) }); + const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, { cx, cy }); const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels); const auto currentVP = _terminal->GetViewport(); - // Don't actually resize if viewport dimensions didn't change - if (vp.Height() == currentVP.Height() && vp.Width() == currentVP.Width()) - { - return; - } - _terminal->ClearSelection(); // Tell the dx engine that our window is now the new size. - THROW_IF_FAILED(_renderEngine->SetWindowSize(size)); + THROW_IF_FAILED(_renderEngine->SetWindowSize({ cx, cy })); // Invalidate everything _renderer->TriggerRedrawAll(); @@ -888,15 +846,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ControlCore::SizeChanged(const double width, const double height) { + // _refreshSizeUnderLock redraws the entire terminal. + // Don't call it if we don't have to. + if (_panelWidth == width && _panelHeight == height) + { + return; + } + _panelWidth = width; _panelHeight = height; auto lock = _terminal->LockForWriting(); - const auto currentEngineScale = _renderEngine->GetScaling(); - - auto scaledWidth = width * currentEngineScale; - auto scaledHeight = height * currentEngineScale; - _doResizeUnderLock(scaledWidth, scaledHeight); + _refreshSizeUnderLock(); } void ControlCore::ScaleChanged(const double scale) @@ -906,30 +867,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } - const auto currentEngineScale = _renderEngine->GetScaling(); - // If we're getting a notification to change to the DPI we already - // have, then we're probably just beginning the DPI change. Since - // we'll get _another_ event with the real DPI, do nothing here for - // now. We'll also skip the next resize in _swapChainSizeChanged. - const bool dpiWasUnchanged = currentEngineScale == scale; - if (dpiWasUnchanged) + // _refreshSizeUnderLock redraws the entire terminal. + // Don't call it if we don't have to. + if (_compositionScale == scale) { return; } - const auto actualFontOldSize = _actualFont.GetSize(); - - auto lock = _terminal->LockForWriting(); _compositionScale = scale; + auto lock = _terminal->LockForWriting(); // _updateFont relies on the new _compositionScale set above _updateFont(); - - const auto actualFontNewSize = _actualFont.GetSize(); - if (actualFontNewSize != actualFontOldSize) - { - _refreshSizeUnderLock(); - } + _refreshSizeUnderLock(); } void ControlCore::SetSelectionAnchor(til::point const& position) diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 2a86c2585cd..a8cd204f1ef 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -242,11 +242,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::fire_and_forget _asyncCloseConnection(); - void _setFontSize(int fontSize); + bool _setFontSizeUnderLock(int fontSize); void _updateFont(const bool initialUpdate = false); void _refreshSizeUnderLock(); - void _doResizeUnderLock(const double newWidth, - const double newHeight); void _sendInputToConnection(std::wstring_view wstr); From f5882236dcb8693a0b14c70e4bbe73e6401d844d Mon Sep 17 00:00:00 2001 From: Dan Mezhiborsky Date: Thu, 24 Mar 2022 17:08:57 -0400 Subject: [PATCH 20/67] Fix transparency/opacity inconsistency in help text (#12592) (#12727) In two instances, the help text for the settings UI refers to _transparency_ when we're really talking about _opacity._ This PR changes those occurences to more accurately reflect the setting being described. ## PR Checklist * [x] Closes #12592 --- .../TerminalSettingsEditor/Resources/en-US/Resources.resw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw index 3a22ea0bcf4..fcafb0bcf4f 100644 --- a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw @@ -528,7 +528,7 @@ Header for a control to determine the level of opacity for the background of the control. The user can choose to make the background of the app more or less opaque. - Sets the transparency of the window. + Sets the opacity of the window. A description for what the "opacity" setting does. Presented near "Profile_Opacity.Header". @@ -648,7 +648,7 @@ Header for a control to choose the opacity of the image presented on the background of the app. - Sets the transparency of the background image. + Sets the opacity of the background image. A description for what the "background image opacity" setting does. Presented near "Profile_BackgroundImageOpacity". From 036cc284bd909a2a4ab836df3c662c5570a0c907 Mon Sep 17 00:00:00 2001 From: David Machaj <46852402+dmachaj@users.noreply.github.com> Date: Mon, 28 Mar 2022 11:31:36 -0700 Subject: [PATCH 21/67] Terminal would benefit from having a single canonical version number for each of its NuGet dependencies (#12707) These changes are purely a refactoring of the build files. There should be no difference to the compiled result or runtime behavior. Currently there are packages.config files in lots of directories, with those same projects referencing props/targets from packages/ with a version string in the path. This is frustrating because version changes or new dependencies require updating lots and lots of build files identically. There is also the possibility of error where locations are missed. With these changes there is a single canonical nuget configuration that takes effect for all of OpenConsole.sln. Updating version numbers should be limited to a single set of global files. The changes were done incrementally but the result is basically that dep\nuget\packages.config serves as the global NuGet dependency list. A pair of common build files (common.nugetversions.props and common.nugetversions.targets) were added to contain the various imports and error checks. There is also a special build target to ensure that the restore happens before builds even though a given directory doesn't have a packages.config for Visual Studio to observe. These new *.nugetversions.* files are imported in pretty much every vcxproj/csproj in the solution in the appropriate place to satisfy the need for packages. There are opt-in configuration values (e.g. `TerminalCppWinrt=true`) that must be set to opt into a given dependency. Adding a new dependency is just a matter of adding a new opt-in value. The ordering of include does matter, which was a difficult challenge to realize and address. There was also a preexisting issue in 3 test projects where cppwinrt.props was included but not cppwinrt.targets. By consolidating things globally that "error" was fixed, but broke the build in a way that was very confusing. Those projects don't need the cppwinrt targets so they were opted out of the cppwinrt build files entirely to fix the breaks and get back to previous behavior. There are two notable exceptions to this canonical versioning. The first is that there are dueling XAML 2.7 dependencies. I avoided that by leaving those as per-project package.config entries. The second is that any projects outside of the .sln (such as the Island samples) were not touched. ## Validation Steps Performed The primary validation is that the solution builds without errors. That is what I'm seeing (x64|Debug). I also ran `git clean -fdx` from the root of the repo to wipe it to clean and then opened the solution and was able to build successfully. The project F5 deploys and looks fine to me with just a cursory glance. The tests also largely pass (7418 pass, 188 fail, 14 other) which is as good or better than the baseline I established from a clean clone. Closes #12708 --- .github/actions/spelling/expect/expect.txt | 2 + OpenConsole.sln | 4 +- build/pipelines/release.yml | 8 ++ .../templates/build-console-audit-job.yml | 13 ++- .../build-console-compliance-job.yml | 8 ++ .../templates/build-console-steps.yml | 9 ++ dep/nuget/packages.config | 21 ++++ .../TextBuffer.Unit.Tests.vcxproj | 2 + .../SettingsModel.LocalTests.vcxproj | 5 +- .../FilteredCommandTests.cpp | 2 +- .../LocalTests_TerminalApp/TabTests.cpp | 2 +- .../TerminalApp.LocalTests.vcxproj | 8 +- .../TestHostApp/TestHostApp.vcxproj | 4 +- .../Microsoft.Terminal.RemotingLib.vcxproj | 8 +- .../dll/Microsoft.Terminal.Remoting.vcxproj | 7 ++ src/cascadia/Remoting/packages.config | 5 - .../WindowsTerminalShellExt.vcxproj | 6 +- src/cascadia/ShellExtension/packages.config | 4 - .../TerminalApp/TerminalAppLib.vcxproj | 12 ++- .../TerminalApp/dll/TerminalApp.vcxproj | 12 ++- src/cascadia/TerminalApp/packages.config | 3 - .../TerminalAzBridge/TerminalAzBridge.vcxproj | 9 +- src/cascadia/TerminalAzBridge/packages.config | 4 - .../TerminalConnection.vcxproj | 16 +-- .../TerminalConnection/packages.config | 6 -- .../TerminalControlLib.vcxproj | 10 +- .../dll/TerminalControl.vcxproj | 9 ++ src/cascadia/TerminalControl/packages.config | 5 - .../TerminalCore/lib/terminalcore-lib.vcxproj | 8 ++ src/cascadia/TerminalCore/packages.config | 4 - ...Microsoft.Terminal.Settings.Editor.vcxproj | 10 +- .../TerminalSettingsEditor/packages.config | 2 - ...crosoft.Terminal.Settings.ModelLib.vcxproj | 10 +- .../Microsoft.Terminal.Settings.Model.vcxproj | 7 ++ .../TerminalSettingsModel/packages.config | 6 -- .../Control.UnitTests.vcxproj | 7 ++ .../Remoting.UnitTests.vcxproj | 4 +- .../UnitTests_TerminalCore/UnitTests.vcxproj | 8 ++ src/cascadia/WinRTUtils/WinRTUtils.vcxproj | 9 +- src/cascadia/WinRTUtils/packages.config | 4 - .../WindowsTerminal/WindowsTerminal.vcxproj | 18 ++-- src/cascadia/WindowsTerminal/packages.config | 5 - .../WindowsTerminal.UIA.Tests.csproj | 33 +++---- .../WindowsTerminal_UIATests/packages.config | 9 -- .../ut_app/TerminalApp.UnitTests.vcxproj | 2 + src/common.build.post.props | 2 - src/common.build.pre.props | 1 - src/common.build.tests.props | 10 +- src/common.nugetversions.props | 42 ++++++++ src/common.nugetversions.targets | 97 +++++++++++++++++++ src/cppwinrt.build.post.props | 11 --- src/cppwinrt.build.pre.props | 2 - src/host/exe/packages.config | 4 - src/host/ft_host/Host.FeatureTests.vcxproj | 2 + src/host/ft_uia/Host.Tests.UIA.csproj | 31 +++--- src/host/ft_uia/packages.config | 9 -- src/host/ut_host/Host.UnitTests.vcxproj | 2 + src/host/ut_lib/host.unittest.vcxproj | 4 +- .../Interactivity.Win32.UnitTests.vcxproj | 2 + src/renderer/dx/ut_dx/Dx.Unit.Tests.vcxproj | 4 +- src/renderer/vt/ut_lib/vt.unittest.vcxproj | 2 + .../ut_adapter/Adapter.UnitTests.vcxproj | 2 + .../parser/ft_fuzzer/VTCommandFuzzer.vcxproj | 2 + .../parser/ft_fuzzwrapper/FuzzWrapper.vcxproj | 4 +- .../parser/ut_parser/Parser.UnitTests.vcxproj | 5 +- .../Parser.UnitTests.vcxproj.filters | 3 - src/terminal/parser/ut_parser/packages.config | 4 - src/til/ut_til/til.unit.tests.vcxproj | 2 + .../MonarchPeasantSample.vcxproj | 12 ++- .../MonarchPeasantSample/packages.config | 4 - src/types/ut_types/Types.Unit.Tests.vcxproj | 2 + .../ft_pty/winconpty.FeatureTests.vcxproj | 2 + tools/OpenConsole.psm1 | 1 + tools/razzle.cmd | 1 + 74 files changed, 423 insertions(+), 196 deletions(-) create mode 100644 dep/nuget/packages.config delete mode 100644 src/cascadia/Remoting/packages.config delete mode 100644 src/cascadia/ShellExtension/packages.config delete mode 100644 src/cascadia/TerminalAzBridge/packages.config delete mode 100644 src/cascadia/TerminalConnection/packages.config delete mode 100644 src/cascadia/TerminalControl/packages.config delete mode 100644 src/cascadia/TerminalCore/packages.config delete mode 100644 src/cascadia/TerminalSettingsModel/packages.config delete mode 100644 src/cascadia/WinRTUtils/packages.config delete mode 100644 src/cascadia/WindowsTerminal_UIATests/packages.config create mode 100644 src/common.nugetversions.props create mode 100644 src/common.nugetversions.targets delete mode 100644 src/host/exe/packages.config delete mode 100644 src/host/ft_uia/packages.config delete mode 100644 src/terminal/parser/ut_parser/packages.config delete mode 100644 src/tools/MonarchPeasantSample/packages.config diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 6b8bd612920..652be19189b 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -52,6 +52,7 @@ apimswincoresynchl apiset APPBARDATA appconsult +appcontainer APPICON appium applet @@ -1626,6 +1627,7 @@ NTVDM ntverp NTWIN nuget +nugetversions nullability nullness nullonfailure diff --git a/OpenConsole.sln b/OpenConsole.sln index 45613781537..f53e2cc56b3 100644 --- a/OpenConsole.sln +++ b/OpenConsole.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29001.49 @@ -290,9 +289,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Props", "Common Prop src\common.build.post.props = src\common.build.post.props src\common.build.pre.props = src\common.build.pre.props src\common.build.tests.props = src\common.build.tests.props + src\common.nugetversions.props = src\common.nugetversions.props + src\common.nugetversions.targets = src\common.nugetversions.targets common.openconsole.props = common.openconsole.props src\cppwinrt.build.post.props = src\cppwinrt.build.post.props src\cppwinrt.build.pre.props = src\cppwinrt.build.pre.props + dep\nuget\packages.config = dep\nuget\packages.config src\wap-common.build.post.props = src\wap-common.build.post.props src\wap-common.build.pre.props = src\wap-common.build.pre.props EndProjectSection diff --git a/build/pipelines/release.yml b/build/pipelines/release.yml index bbe1d0570b7..cd2cc038c1a 100644 --- a/build/pipelines/release.yml +++ b/build/pipelines/release.yml @@ -122,6 +122,14 @@ jobs: selectOrConfig: config nugetConfigPath: NuGet.Config arguments: restore OpenConsole.sln -SolutionDirectory $(Build.SourcesDirectory) + - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for global nuget + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: dep/nuget/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' # Pull the Windows SDK for the developer tools like the debuggers so we can index sources later - template: .\templates\install-winsdk-steps.yml - task: UniversalPackages@0 diff --git a/build/pipelines/templates/build-console-audit-job.yml b/build/pipelines/templates/build-console-audit-job.yml index f84c5bca520..591c2a7b12e 100644 --- a/build/pipelines/templates/build-console-audit-job.yml +++ b/build/pipelines/templates/build-console-audit-job.yml @@ -8,7 +8,7 @@ jobs: variables: BuildConfiguration: AuditMode BuildPlatform: ${{ parameters.platform }} - pool: + pool: ${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}: name: WinDevPoolOSS-L ${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}: @@ -48,6 +48,17 @@ jobs: restoreSolution: OpenConsole.sln restoreDirectory: '$(Build.SourcesDirectory)\packages' + # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. + # This should be `task: NuGetCommand@2` + - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for global nuget + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: dep/nuget/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' + - task: VSBuild@1 displayName: 'Build solution **\OpenConsole.sln' inputs: diff --git a/build/pipelines/templates/build-console-compliance-job.yml b/build/pipelines/templates/build-console-compliance-job.yml index eafaf6b8062..3ae3fb197ee 100644 --- a/build/pipelines/templates/build-console-compliance-job.yml +++ b/build/pipelines/templates/build-console-compliance-job.yml @@ -52,6 +52,14 @@ jobs: selectOrConfig: config nugetConfigPath: NuGet.Config arguments: restore OpenConsole.sln -SolutionDirectory $(Build.SourcesDirectory) + - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for global nuget + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: dep/nuget/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' - task: UniversalPackages@0 displayName: Download terminal-internal Universal Package inputs: diff --git a/build/pipelines/templates/build-console-steps.yml b/build/pipelines/templates/build-console-steps.yml index dd609988604..65e1d146aa3 100644 --- a/build/pipelines/templates/build-console-steps.yml +++ b/build/pipelines/templates/build-console-steps.yml @@ -34,6 +34,15 @@ steps: restoreSolution: OpenConsole.sln restoreDirectory: '$(Build.SourcesDirectory)\packages' +- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for global nuget + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: dep/nuget/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' + # The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves. - script: | "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt diff --git a/dep/nuget/packages.config b/dep/nuget/packages.config new file mode 100644 index 00000000000..fb81204984e --- /dev/null +++ b/dep/nuget/packages.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj b/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj index dab7c2bf390..ca276b2b13f 100644 --- a/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj +++ b/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -40,4 +41,5 @@ + diff --git a/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj b/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj index 2ad3e5508e3..47214270725 100644 --- a/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj +++ b/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj @@ -19,9 +19,11 @@ SettingsModel.LocalTests DynamicLibrary true + + @@ -94,6 +96,7 @@ + @@ -102,7 +105,7 @@ <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\runtimes\win10-$(Native-Platform)\native\" - + diff --git a/src/cascadia/LocalTests_TerminalApp/FilteredCommandTests.cpp b/src/cascadia/LocalTests_TerminalApp/FilteredCommandTests.cpp index 4d0f6603103..7a92e2c023c 100644 --- a/src/cascadia/LocalTests_TerminalApp/FilteredCommandTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/FilteredCommandTests.cpp @@ -4,7 +4,7 @@ #include "pch.h" #include "../TerminalApp/CommandLinePaletteItem.h" #include "../TerminalApp/CommandPalette.h" -#include "../CppWinrtTailored.h" +#include "CppWinrtTailored.h" using namespace Microsoft::Console; using namespace WEX::Logging; diff --git a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp index 424f0ddcdc0..fcb8f214de0 100644 --- a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp @@ -9,7 +9,7 @@ #include "../TerminalApp/ShortcutActionDispatch.h" #include "../TerminalApp/TerminalTab.h" #include "../TerminalApp/CommandPalette.h" -#include "../CppWinrtTailored.h" +#include "CppWinrtTailored.h" using namespace Microsoft::Console; using namespace TerminalApp; diff --git a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj index d44431a5f89..b57c9beb56a 100644 --- a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj @@ -21,7 +21,13 @@ true + + + true + + + @@ -87,6 +93,7 @@ + @@ -97,6 +104,5 @@ - diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj index 896547f5ffd..81a175840f5 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj @@ -29,6 +29,7 @@ + @@ -127,6 +128,7 @@ + diff --git a/src/cascadia/Remoting/Microsoft.Terminal.RemotingLib.vcxproj b/src/cascadia/Remoting/Microsoft.Terminal.RemotingLib.vcxproj index 517c2f56fcb..638229df0d4 100644 --- a/src/cascadia/Remoting/Microsoft.Terminal.RemotingLib.vcxproj +++ b/src/cascadia/Remoting/Microsoft.Terminal.RemotingLib.vcxproj @@ -9,8 +9,10 @@ StaticLibrary Console true + true + @@ -107,7 +109,6 @@ - @@ -139,5 +140,8 @@ + + + - \ No newline at end of file + diff --git a/src/cascadia/Remoting/dll/Microsoft.Terminal.Remoting.vcxproj b/src/cascadia/Remoting/dll/Microsoft.Terminal.Remoting.vcxproj index a2eaba668e4..d0b9179f433 100644 --- a/src/cascadia/Remoting/dll/Microsoft.Terminal.Remoting.vcxproj +++ b/src/cascadia/Remoting/dll/Microsoft.Terminal.Remoting.vcxproj @@ -12,7 +12,11 @@ true true + + true + + @@ -71,4 +75,7 @@ + + + diff --git a/src/cascadia/Remoting/packages.config b/src/cascadia/Remoting/packages.config deleted file mode 100644 index 64e09e4c8e5..00000000000 --- a/src/cascadia/Remoting/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj b/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj index ad10da07a77..2f6fce0cb92 100644 --- a/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj +++ b/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj @@ -11,7 +11,11 @@ false + + true + + @@ -30,7 +34,6 @@ - @@ -50,6 +53,7 @@ + + + + - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - @@ -88,15 +92,12 @@ - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - @@ -111,4 +112,7 @@ + + + diff --git a/src/cascadia/TerminalApp/packages.config b/src/cascadia/TerminalApp/packages.config index e039fa4ae47..e91b14a32bf 100644 --- a/src/cascadia/TerminalApp/packages.config +++ b/src/cascadia/TerminalApp/packages.config @@ -1,7 +1,4 @@ - - - diff --git a/src/cascadia/TerminalAzBridge/TerminalAzBridge.vcxproj b/src/cascadia/TerminalAzBridge/TerminalAzBridge.vcxproj index cf465a2a340..0fddd2db19a 100644 --- a/src/cascadia/TerminalAzBridge/TerminalAzBridge.vcxproj +++ b/src/cascadia/TerminalAzBridge/TerminalAzBridge.vcxproj @@ -13,7 +13,12 @@ Windows + + true + + + @@ -33,9 +38,6 @@ - - - @@ -57,6 +59,7 @@ + diff --git a/src/cascadia/TerminalAzBridge/packages.config b/src/cascadia/TerminalAzBridge/packages.config deleted file mode 100644 index 6ec12ca23d1..00000000000 --- a/src/cascadia/TerminalAzBridge/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/cascadia/TerminalConnection/TerminalConnection.vcxproj b/src/cascadia/TerminalConnection/TerminalConnection.vcxproj index f9ab61577f7..0fed7d60aa1 100644 --- a/src/cascadia/TerminalConnection/TerminalConnection.vcxproj +++ b/src/cascadia/TerminalConnection/TerminalConnection.vcxproj @@ -9,7 +9,12 @@ true true + + true + true + + @@ -60,7 +65,6 @@ Designer - @@ -81,13 +85,6 @@ - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - $(IntDir)..\OpenConsoleProxy;%(AdditionalIncludeDirectories) @@ -98,6 +95,9 @@ + + + @@ -140,7 +146,6 @@ - @@ -175,5 +180,8 @@ + + + diff --git a/src/cascadia/TerminalControl/dll/TerminalControl.vcxproj b/src/cascadia/TerminalControl/dll/TerminalControl.vcxproj index 061b74c23f2..7783493136c 100644 --- a/src/cascadia/TerminalControl/dll/TerminalControl.vcxproj +++ b/src/cascadia/TerminalControl/dll/TerminalControl.vcxproj @@ -22,7 +22,13 @@ --> 3 + + + true + + + @@ -98,4 +104,7 @@ + + + diff --git a/src/cascadia/TerminalControl/packages.config b/src/cascadia/TerminalControl/packages.config deleted file mode 100644 index 64e09e4c8e5..00000000000 --- a/src/cascadia/TerminalControl/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj index 2f750978bba..7488acf941f 100644 --- a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj +++ b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj @@ -12,12 +12,17 @@ true + + true + + "$(SolutionDir)\src\cascadia\TerminalCore\Generated Files\winrt";$(SolutionDir)src\cascadia\TerminalCore;$(CAExcludePath) + @@ -65,4 +70,7 @@ + + + diff --git a/src/cascadia/TerminalCore/packages.config b/src/cascadia/TerminalCore/packages.config deleted file mode 100644 index 6ec12ca23d1..00000000000 --- a/src/cascadia/TerminalCore/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj b/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj index 7c5f17695a9..8953d1e9b2a 100644 --- a/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj +++ b/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj @@ -32,7 +32,11 @@ 4 nested + + true + + @@ -345,6 +349,10 @@ + + + + @@ -353,4 +361,4 @@ - \ No newline at end of file + diff --git a/src/cascadia/TerminalSettingsEditor/packages.config b/src/cascadia/TerminalSettingsEditor/packages.config index 9b938bd8686..03d6e483c32 100644 --- a/src/cascadia/TerminalSettingsEditor/packages.config +++ b/src/cascadia/TerminalSettingsEditor/packages.config @@ -1,6 +1,4 @@ - - diff --git a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj index bf0e68e2662..c37026831c5 100644 --- a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj +++ b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj @@ -10,7 +10,12 @@ Console true + + true + true + + @@ -184,7 +189,6 @@ - @@ -268,13 +272,14 @@ + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - @@ -125,4 +129,7 @@ + + + diff --git a/src/cascadia/TerminalSettingsModel/packages.config b/src/cascadia/TerminalSettingsModel/packages.config deleted file mode 100644 index 2ecd2492264..00000000000 --- a/src/cascadia/TerminalSettingsModel/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/cascadia/UnitTests_Control/Control.UnitTests.vcxproj b/src/cascadia/UnitTests_Control/Control.UnitTests.vcxproj index 08cc065238c..b553e3f9ccc 100644 --- a/src/cascadia/UnitTests_Control/Control.UnitTests.vcxproj +++ b/src/cascadia/UnitTests_Control/Control.UnitTests.vcxproj @@ -10,7 +10,12 @@ true + + true + + + @@ -85,5 +90,7 @@ + + diff --git a/src/cascadia/UnitTests_Remoting/Remoting.UnitTests.vcxproj b/src/cascadia/UnitTests_Remoting/Remoting.UnitTests.vcxproj index 424e6f9b4b7..171b3eed2d5 100644 --- a/src/cascadia/UnitTests_Remoting/Remoting.UnitTests.vcxproj +++ b/src/cascadia/UnitTests_Remoting/Remoting.UnitTests.vcxproj @@ -19,9 +19,11 @@ Remoting.Unit.Tests DynamicLibrary true + + @@ -71,6 +73,6 @@ - + diff --git a/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj b/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj index 0bcdc582a67..42893d18fa4 100644 --- a/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj +++ b/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj @@ -9,7 +9,11 @@ DynamicLibrary false + + true + + @@ -98,4 +102,8 @@ + + + + diff --git a/src/cascadia/WinRTUtils/WinRTUtils.vcxproj b/src/cascadia/WinRTUtils/WinRTUtils.vcxproj index 0c6d74a8ac8..ac766d765fe 100644 --- a/src/cascadia/WinRTUtils/WinRTUtils.vcxproj +++ b/src/cascadia/WinRTUtils/WinRTUtils.vcxproj @@ -10,7 +10,11 @@ Console true + + true + + @@ -33,10 +37,6 @@ - - - - @@ -50,4 +50,5 @@ + diff --git a/src/cascadia/WinRTUtils/packages.config b/src/cascadia/WinRTUtils/packages.config deleted file mode 100644 index 6ec12ca23d1..00000000000 --- a/src/cascadia/WinRTUtils/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 47655445e79..e4e6186e799 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -1,6 +1,5 @@ - {CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B} @@ -17,7 +16,15 @@ true + + true + true + true + true + + + @@ -135,17 +142,11 @@ - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + diff --git a/src/common.build.post.props b/src/common.build.post.props index 399cec3bf1e..4e2a1f7d086 100644 --- a/src/common.build.post.props +++ b/src/common.build.post.props @@ -33,8 +33,6 @@ - - diff --git a/src/common.build.pre.props b/src/common.build.pre.props index 4d494f911ab..b8178508228 100644 --- a/src/common.build.pre.props +++ b/src/common.build.pre.props @@ -181,7 +181,6 @@ - diff --git a/src/common.build.tests.props b/src/common.build.tests.props index 3e43e16fe81..0c93e53ed75 100644 --- a/src/common.build.tests.props +++ b/src/common.build.tests.props @@ -5,11 +5,7 @@ INLINE_TEST_METHOD_MARKUP;UNIT_TESTING;%(PreprocessorDefinitions) - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - + + true + diff --git a/src/common.nugetversions.props b/src/common.nugetversions.props new file mode 100644 index 00000000000..170b9062dcb --- /dev/null +++ b/src/common.nugetversions.props @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + $(MSBuildThisFileDirectory)..\packages\Microsoft.Taef.10.60.210621002 + + + + + $(MSBuildThisFileDirectory)..\packages\Appium.WebDriver.3.0.0.2 + + + + + $(MSBuildThisFileDirectory)..\packages\Castle.Core.4.1.1 + + + + + $(MSBuildThisFileDirectory)..\packages\Newtonsoft.Json.12.0.3 + + + + + $(MSBuildThisFileDirectory)..\packages\Selenium.WebDriver.3.5.0 + + + + + $(MSBuildThisFileDirectory)..\packages\Selenium.Support.3.5.0 + + + diff --git a/src/common.nugetversions.targets b/src/common.nugetversions.targets new file mode 100644 index 00000000000..025d7418948 --- /dev/null +++ b/src/common.nugetversions.targets @@ -0,0 +1,97 @@ + + + + + + + + + $(SolutionDir)dep\nuget\nuget.exe + $(SolutionDir)dep\nuget\packages.config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cppwinrt.build.post.props b/src/cppwinrt.build.post.props index 72d925f0b13..68fc7ec2616 100644 --- a/src/cppwinrt.build.post.props +++ b/src/cppwinrt.build.post.props @@ -1,15 +1,4 @@ - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - diff --git a/src/cppwinrt.build.pre.props b/src/cppwinrt.build.pre.props index 263da4fd9bf..30a659e33c4 100644 --- a/src/cppwinrt.build.pre.props +++ b/src/cppwinrt.build.pre.props @@ -8,8 +8,6 @@ - - AnyValueHereWillDisableTheOptOut true diff --git a/src/host/exe/packages.config b/src/host/exe/packages.config deleted file mode 100644 index 9e477b65215..00000000000 --- a/src/host/exe/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/host/ft_host/Host.FeatureTests.vcxproj b/src/host/ft_host/Host.FeatureTests.vcxproj index 1538e9b5455..6f782a5404e 100644 --- a/src/host/ft_host/Host.FeatureTests.vcxproj +++ b/src/host/ft_host/Host.FeatureTests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -60,4 +61,5 @@ + diff --git a/src/host/ft_uia/Host.Tests.UIA.csproj b/src/host/ft_uia/Host.Tests.UIA.csproj index 1f71e6a4919..675ddd7086a 100644 --- a/src/host/ft_uia/Host.Tests.UIA.csproj +++ b/src/host/ft_uia/Host.Tests.UIA.csproj @@ -21,6 +21,10 @@ + + true + + ARM64 @@ -43,35 +47,35 @@ - ..\..\..\packages\Appium.WebDriver.3.0.0.2\lib\net45\appium-dotnet-driver.dll + $(AppiumWebDriverPathRoot)\lib\net45\appium-dotnet-driver.dll - ..\..\..\packages\Castle.Core.4.1.1\lib\net45\Castle.Core.dll + $(CastleCorePathRoot)\lib\net45\Castle.Core.dll - ..\..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + $(NewtonsoftJSONPathRoot)\lib\net45\Newtonsoft.Json.dll - ..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\TE.Managed.dll + $(TAEFPackagePathRoot)\lib\net45\TE.Managed.dll - ..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\TE.Model.Managed.dll + $(TAEFPackagePathRoot)\lib\net45\TE.Model.Managed.dll - ..\..\..\packages\Selenium.WebDriver.3.5.0\lib\net40\WebDriver.dll + $(SeleniumWebDriverPathRoot)\lib\net40\WebDriver.dll - ..\..\..\packages\Selenium.Support.3.5.0\lib\net40\WebDriver.Support.dll + $(SeleniumSupportPathRoot)\lib\net40\WebDriver.Support.dll - ..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\Wex.Common.Managed.dll + $(TAEFPackagePathRoot)\lib\net45\Wex.Common.Managed.dll - ..\..\..\packages\Microsoft.Taef.10.60.210621002\lib\net45\Wex.Logger.Interop.dll + $(TAEFPackagePathRoot)\lib\net45\Wex.Logger.Interop.dll @@ -121,7 +125,6 @@ - @@ -148,11 +151,5 @@ copy "$(SolutionDir)\dep\WinAppDriver\*" "$(OutDir)\" - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - + diff --git a/src/host/ft_uia/packages.config b/src/host/ft_uia/packages.config deleted file mode 100644 index 0579ab06c6a..00000000000 --- a/src/host/ft_uia/packages.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/host/ut_host/Host.UnitTests.vcxproj b/src/host/ut_host/Host.UnitTests.vcxproj index 6b5bedf1b11..633c990e6fa 100644 --- a/src/host/ut_host/Host.UnitTests.vcxproj +++ b/src/host/ut_host/Host.UnitTests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -112,4 +113,5 @@ + diff --git a/src/host/ut_lib/host.unittest.vcxproj b/src/host/ut_lib/host.unittest.vcxproj index 75821ebc8a8..3faad5afefe 100644 --- a/src/host/ut_lib/host.unittest.vcxproj +++ b/src/host/ut_lib/host.unittest.vcxproj @@ -6,9 +6,10 @@ hostlib.unittest Host.unittest ConhostV2Lib.unittest - StaticLibrary + StaticLibrary + @@ -19,4 +20,5 @@ + diff --git a/src/interactivity/win32/ut_interactivity_win32/Interactivity.Win32.UnitTests.vcxproj b/src/interactivity/win32/ut_interactivity_win32/Interactivity.Win32.UnitTests.vcxproj index fa2fa30b086..5a03a6df2d3 100644 --- a/src/interactivity/win32/ut_interactivity_win32/Interactivity.Win32.UnitTests.vcxproj +++ b/src/interactivity/win32/ut_interactivity_win32/Interactivity.Win32.UnitTests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -79,4 +80,5 @@ + diff --git a/src/renderer/dx/ut_dx/Dx.Unit.Tests.vcxproj b/src/renderer/dx/ut_dx/Dx.Unit.Tests.vcxproj index 78b8de06872..4c6abb8075e 100644 --- a/src/renderer/dx/ut_dx/Dx.Unit.Tests.vcxproj +++ b/src/renderer/dx/ut_dx/Dx.Unit.Tests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -37,4 +38,5 @@ - \ No newline at end of file + + diff --git a/src/renderer/vt/ut_lib/vt.unittest.vcxproj b/src/renderer/vt/ut_lib/vt.unittest.vcxproj index 2c146516195..9f33a67e60d 100644 --- a/src/renderer/vt/ut_lib/vt.unittest.vcxproj +++ b/src/renderer/vt/ut_lib/vt.unittest.vcxproj @@ -9,9 +9,11 @@ StaticLibrary + + diff --git a/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj b/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj index b1ce6a9d73e..8ee87c5ba50 100644 --- a/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj +++ b/src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -45,4 +46,5 @@ + diff --git a/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.vcxproj b/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.vcxproj index 906822e1e2d..587d6ed1d1e 100644 --- a/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.vcxproj +++ b/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.vcxproj @@ -9,6 +9,7 @@ Application + Create @@ -34,4 +35,5 @@ + diff --git a/src/terminal/parser/ft_fuzzwrapper/FuzzWrapper.vcxproj b/src/terminal/parser/ft_fuzzwrapper/FuzzWrapper.vcxproj index f9b51f59f2f..98b4a98515b 100644 --- a/src/terminal/parser/ft_fuzzwrapper/FuzzWrapper.vcxproj +++ b/src/terminal/parser/ft_fuzzwrapper/FuzzWrapper.vcxproj @@ -9,6 +9,7 @@ Application + Create @@ -39,4 +40,5 @@ - \ No newline at end of file + + diff --git a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj index 549eb4170ff..6ddbcdd116b 100644 --- a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj +++ b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -42,10 +43,8 @@ {06ec74cb-9a12-429c-b551-8562ec964846} - - - + diff --git a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters index 888240512c2..61ed48e9af8 100644 --- a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters +++ b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters @@ -39,7 +39,4 @@ - - - \ No newline at end of file diff --git a/src/terminal/parser/ut_parser/packages.config b/src/terminal/parser/ut_parser/packages.config deleted file mode 100644 index bd5fb454237..00000000000 --- a/src/terminal/parser/ut_parser/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/til/ut_til/til.unit.tests.vcxproj b/src/til/ut_til/til.unit.tests.vcxproj index 48f9a8d3dea..ac5fa9bebb4 100644 --- a/src/til/ut_til/til.unit.tests.vcxproj +++ b/src/til/ut_til/til.unit.tests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + Create @@ -44,4 +45,5 @@ + diff --git a/src/tools/MonarchPeasantSample/MonarchPeasantSample.vcxproj b/src/tools/MonarchPeasantSample/MonarchPeasantSample.vcxproj index 0daaf4a3d0e..1e4815a9cfe 100644 --- a/src/tools/MonarchPeasantSample/MonarchPeasantSample.vcxproj +++ b/src/tools/MonarchPeasantSample/MonarchPeasantSample.vcxproj @@ -13,7 +13,12 @@ Windows + + true + + + @@ -54,10 +59,6 @@ - - - - @@ -87,5 +88,8 @@ + + + diff --git a/src/tools/MonarchPeasantSample/packages.config b/src/tools/MonarchPeasantSample/packages.config deleted file mode 100644 index 21e62883af7..00000000000 --- a/src/tools/MonarchPeasantSample/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/types/ut_types/Types.Unit.Tests.vcxproj b/src/types/ut_types/Types.Unit.Tests.vcxproj index 3f5087de763..dfd180e294e 100644 --- a/src/types/ut_types/Types.Unit.Tests.vcxproj +++ b/src/types/ut_types/Types.Unit.Tests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -32,4 +33,5 @@ + diff --git a/src/winconpty/ft_pty/winconpty.FeatureTests.vcxproj b/src/winconpty/ft_pty/winconpty.FeatureTests.vcxproj index 438f6014dae..503ff27408b 100644 --- a/src/winconpty/ft_pty/winconpty.FeatureTests.vcxproj +++ b/src/winconpty/ft_pty/winconpty.FeatureTests.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -31,6 +32,7 @@ + $(OutDir)\conptylib.lib;%(AdditionalDependencies) diff --git a/tools/OpenConsole.psm1 b/tools/OpenConsole.psm1 index bad0afb0d95..fd0ededc112 100644 --- a/tools/OpenConsole.psm1 +++ b/tools/OpenConsole.psm1 @@ -261,6 +261,7 @@ function Invoke-OpenConsoleBuild() { $root = Find-OpenConsoleRoot & "$root\dep\nuget\nuget.exe" restore "$root\OpenConsole.sln" + & "$root\dep\nuget\nuget.exe" restore "$root\dep\nuget\packages.config" msbuild.exe "$root\OpenConsole.sln" @args } diff --git a/tools/razzle.cmd b/tools/razzle.cmd index 456e271d1b2..f5b567d77f0 100644 --- a/tools/razzle.cmd +++ b/tools/razzle.cmd @@ -22,6 +22,7 @@ set PATH=%PATH%%OPENCON%\dep\nuget; rem Run nuget restore so you can use vswhere nuget restore %OPENCON%\OpenConsole.sln -Verbosity quiet +nuget restore %OPENCON%\dep\nuget\packages.config -Verbosity quiet :FIND_MSBUILD set MSBUILD= From 90c92850ea8257c4bfb0ff5689d6cb0e2e12037e Mon Sep 17 00:00:00 2001 From: David Machaj <46852402+dmachaj@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:28:15 -0700 Subject: [PATCH 22/67] Convert WIL submodule to global NuGet. Update to latest. Replace winrt::resume_foreground with wil::resume_foreground (#12778) ## Summary of the Pull Request This builds on top of #12707. As I understand it the primary motivation for using a git submodule instead of NuGet is just that it is too annoying to have to manage dozens of packages.config files and their corresponding import statements. Now that there is a single global nuget definition that is a nonissue and we can switch over. This also updates to the latest version of WIL. Now that the latest version of WIL is available it uses it to replace `winrt::resume_foreground` with `wil::resume_foreground`. See [https://github.com/microsoft/wil/commit/492c01bb535daadf719d4445d6107aadf1e60812](https://github.com/microsoft/wil/commit/492c01bb535daadf719d4445d6107aadf1e60812) for a detailed explanation of the problems with `winrt::resume_foreground` and how WIL addresses them. ## References ## PR Checklist * [ ] Closes #12776, Closes #12777 * [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [ ] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed Ran `git clean -fdx` to wipe my clone to be completely clean. Opened the solution in Visual Studio 2022 and build it. Used `razzle.cmd`, `b`, and `runut.cmd` to run the tests. --- dep/nuget/packages.config | 1 + dep/wil | 1 - doc/building.md | 11 +++++++++- src/buffer/out/lib/bufferout.vcxproj | 2 ++ src/cascadia/ElevateShim/elevate-shim.vcxproj | 2 ++ .../PublicTerminalCore.vcxproj | 2 ++ src/cascadia/TerminalApp/Pane.cpp | 4 ++-- src/cascadia/TerminalApp/SettingsTab.cpp | 2 +- src/cascadia/TerminalApp/TabBase.cpp | 2 +- src/cascadia/TerminalApp/TabManagement.cpp | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 20 +++++++++---------- src/cascadia/TerminalApp/TerminalTab.cpp | 20 +++++++++---------- src/cascadia/TerminalApp/pch.h | 1 + src/cascadia/TerminalControl/TermControl.cpp | 16 +++++++-------- src/cascadia/TerminalControl/pch.h | 1 + src/cascadia/TerminalSettingsModel/pch.h | 1 + src/cascadia/WindowsTerminal/AppHost.cpp | 6 +++--- src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 +- src/cascadia/WindowsTerminal/pch.h | 1 + src/cascadia/wt/wt.vcxproj | 2 ++ src/common.build.pre.props | 4 ++-- src/common.nugetversions.targets | 6 ++++++ src/host/exe/Host.EXE.vcxproj | 2 ++ src/host/lib/hostlib.vcxproj | 2 ++ .../base/lib/InteractivityBase.vcxproj | 2 ++ src/interactivity/win32/lib/win32.LIB.vcxproj | 2 ++ src/internal/internal.vcxproj | 2 ++ src/propsheet/propsheet.vcxproj | 2 ++ src/propslib/propslib.vcxproj | 2 ++ src/renderer/atlas/atlas.vcxproj | 4 +++- src/renderer/base/lib/base.vcxproj | 2 ++ src/renderer/dx/lib/dx.vcxproj | 2 ++ src/renderer/gdi/lib/gdi.vcxproj | 2 ++ src/renderer/uia/lib/uia.vcxproj | 2 ++ src/renderer/vt/lib/vt.vcxproj | 2 ++ src/server/lib/server.vcxproj | 2 ++ src/terminal/adapter/lib/adapter.vcxproj | 4 +++- src/terminal/input/lib/terminalinput.vcxproj | 4 +++- src/terminal/parser/lib/parser.vcxproj | 2 ++ src/tools/buffersize/buffersize.vcxproj | 2 ++ src/tools/echokey/ConEchoKey.vcxproj | 2 ++ src/tools/fontlist/FontList.vcxproj | 2 ++ src/tools/vtpipeterm/VtPipeTerm.vcxproj | 2 ++ src/tsf/tsf.vcxproj | 2 ++ src/types/lib/types.vcxproj | 2 ++ src/winconpty/dll/winconptydll.vcxproj | 2 ++ src/winconpty/lib/winconptylib.vcxproj | 4 +++- 47 files changed, 122 insertions(+), 45 deletions(-) delete mode 160000 dep/wil diff --git a/dep/nuget/packages.config b/dep/nuget/packages.config index fb81204984e..5d0f1f2e637 100644 --- a/dep/nuget/packages.config +++ b/dep/nuget/packages.config @@ -11,6 +11,7 @@ + diff --git a/dep/wil b/dep/wil deleted file mode 160000 index 2e225973d6c..00000000000 --- a/dep/wil +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2e225973d6c2ecf17fb4d376ddbeedb6db7dd82f diff --git a/doc/building.md b/doc/building.md index df13e5d6933..ca88a52bcb0 100644 --- a/doc/building.md +++ b/doc/building.md @@ -64,7 +64,16 @@ Openconsole has three configuration types: AuditMode is an experimental mode that enables some additional static analysis from CppCoreCheck. -## Updating Nuget package references +## Updating Nuget package references - Globally versioned +Most Nuget package references in this project are centralized in a single configuration so that there is a single canonical version for everything. This canonical version is restored before builds by the build pipeline, environment initialization scripts, or Visual Studio (as appropriate). + +The canonical version numbers are defined in dep/nuget/packages.config. That defines what will be downloaded by nuget.exe. Most Nuget packages also have a .props and/or .targets file that must be imported by every project that consumes it. Those import statements are consolidated in: +- src/common.nugetversions.props +- src/common.nugetversions.targets + +When a globally managed version changes all three of those files must be changed in unison. + +## Updating Nuget package references - Locally versioned Certain Nuget package references in this project, like `Microsoft.UI.Xaml`, must be updated outside of the Visual Studio NuGet package manager. This can be done using the snippet below. > Note that to run this snippet, you need to use WSL as the command uses `sed`. To update the version of a given package, use the following snippet diff --git a/src/buffer/out/lib/bufferout.vcxproj b/src/buffer/out/lib/bufferout.vcxproj index cfe899c732f..7f48bb3fee3 100644 --- a/src/buffer/out/lib/bufferout.vcxproj +++ b/src/buffer/out/lib/bufferout.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -56,4 +57,5 @@ + diff --git a/src/cascadia/ElevateShim/elevate-shim.vcxproj b/src/cascadia/ElevateShim/elevate-shim.vcxproj index f81353ad368..ba12ddf62f2 100644 --- a/src/cascadia/ElevateShim/elevate-shim.vcxproj +++ b/src/cascadia/ElevateShim/elevate-shim.vcxproj @@ -11,6 +11,7 @@ + @@ -24,6 +25,7 @@ + diff --git a/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj b/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj index a7063bb9b28..342dac89acd 100644 --- a/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj +++ b/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + Create @@ -48,6 +49,7 @@ + diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index 2bef061af7a..9130aec77da 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -1032,7 +1032,7 @@ winrt::fire_and_forget Pane::_playBellSound(winrt::Windows::Foundation::Uri uri) { auto weakThis{ weak_from_this() }; - co_await winrt::resume_foreground(_root.Dispatcher()); + co_await wil::resume_foreground(_root.Dispatcher()); if (auto pane{ weakThis.lock() }) { // BODGY @@ -1761,7 +1761,7 @@ winrt::fire_and_forget Pane::_CloseChildRoutine(const bool closeFirst) { auto weakThis{ shared_from_this() }; - co_await winrt::resume_foreground(_root.Dispatcher()); + co_await wil::resume_foreground(_root.Dispatcher()); if (auto pane{ weakThis.get() }) { diff --git a/src/cascadia/TerminalApp/SettingsTab.cpp b/src/cascadia/TerminalApp/SettingsTab.cpp index 4eb0457d1b1..54e48ed1e0d 100644 --- a/src/cascadia/TerminalApp/SettingsTab.cpp +++ b/src/cascadia/TerminalApp/SettingsTab.cpp @@ -94,7 +94,7 @@ namespace winrt::TerminalApp::implementation { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { diff --git a/src/cascadia/TerminalApp/TabBase.cpp b/src/cascadia/TerminalApp/TabBase.cpp index 6667f760ea7..167b5008066 100644 --- a/src/cascadia/TerminalApp/TabBase.cpp +++ b/src/cascadia/TerminalApp/TabBase.cpp @@ -183,7 +183,7 @@ namespace winrt::TerminalApp::implementation auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp index 2989e847a3c..bf3fc392212 100644 --- a/src/cascadia/TerminalApp/TabManagement.cpp +++ b/src/cascadia/TerminalApp/TabManagement.cpp @@ -716,7 +716,7 @@ namespace winrt::TerminalApp::implementation // sometimes set focus to an incorrect tab after removing some tabs auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(_tabView.Dispatcher()); + co_await wil::resume_foreground(_tabView.Dispatcher()); if (auto page{ weakThis.get() }) { diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 8f79e9b8090..91694653088 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -591,7 +591,7 @@ namespace winrt::TerminalApp::implementation auto weakThis{ get_weak() }; // Handle it on a subsequent pass of the UI thread. - co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal); + co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal); // If the caller provided a CWD, switch to that directory, then switch // back once we're done. This looks weird though, because we have to set @@ -1040,7 +1040,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget TerminalPage::_RemoveOnCloseRoutine(Microsoft::UI::Xaml::Controls::TabViewItem tabViewItem, winrt::com_ptr page) { - co_await winrt::resume_foreground(page->_tabView.Dispatcher()); + co_await wil::resume_foreground(page->_tabView.Dispatcher()); if (auto tab{ _GetTabByTabViewItem(tabViewItem) }) { @@ -2040,7 +2040,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget TerminalPage::_CopyToClipboardHandler(const IInspectable /*sender*/, const CopyToClipboardEventArgs copiedData) { - co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::High); + co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::High); DataPackage dataPack = DataPackage(); dataPack.RequestedOperation(DataPackageOperation::Copy); @@ -2154,7 +2154,7 @@ namespace winrt::TerminalApp::implementation if (warnMultiLine || warnLargeText) { - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); // We have to initialize the dialog here to be able to change the text of the text block within it FindName(L"MultiLinePasteDialog").try_as(); @@ -2267,7 +2267,7 @@ namespace winrt::TerminalApp::implementation const Microsoft::Terminal::Control::NoticeEventArgs eventArgs) { auto weakThis = get_weak(); - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto page = weakThis.get()) { winrt::hstring message = eventArgs.Message(); @@ -2334,7 +2334,7 @@ namespace winrt::TerminalApp::implementation // - eventArgs: the arguments specifying how to set the progress indicator winrt::fire_and_forget TerminalPage::_SetTaskbarProgressHandler(const IInspectable /*sender*/, const IInspectable /*eventArgs*/) { - co_await resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); _SetTaskbarProgressHandlers(*this, nullptr); } @@ -3415,7 +3415,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget TerminalPage::IdentifyWindow() { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto page{ weakThis.get() }) { // If we haven't ever loaded the TeachingTip, then do so now and @@ -3458,7 +3458,7 @@ namespace winrt::TerminalApp::implementation auto weakThis{ get_weak() }; // On the foreground thread, raise property changed notifications, and // display the success toast. - co_await resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto page{ weakThis.get() }) { if (changed) @@ -3550,7 +3550,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget TerminalPage::RenameFailed() { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto page{ weakThis.get() }) { // If we haven't ever loaded the TeachingTip, then do so now and @@ -3757,7 +3757,7 @@ namespace winrt::TerminalApp::implementation const auto newConnectionState = coreState.ConnectionState(); if (newConnectionState == ConnectionState::Failed && !_IsMessageDismissed(InfoBarMessage::CloseOnExitInfo)) { - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (const auto infoBar = FindName(L"CloseOnExitInfoBar").try_as()) { infoBar.IsOpen(true); diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 5dc52596177..96ecad9d8b9 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -146,7 +146,7 @@ namespace winrt::TerminalApp::implementation { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { @@ -288,7 +288,7 @@ namespace winrt::TerminalApp::implementation auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { @@ -307,7 +307,7 @@ namespace winrt::TerminalApp::implementation { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { @@ -336,7 +336,7 @@ namespace winrt::TerminalApp::implementation { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { @@ -351,7 +351,7 @@ namespace winrt::TerminalApp::implementation { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { @@ -398,7 +398,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget TerminalTab::UpdateTitle() { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(TabViewItem().Dispatcher()); + co_await wil::resume_foreground(TabViewItem().Dispatcher()); if (auto tab{ weakThis.get() }) { const auto activeTitle = _GetActiveTitle(); @@ -424,7 +424,7 @@ namespace winrt::TerminalApp::implementation { auto control = GetActiveTerminalControl(); - co_await winrt::resume_foreground(control.Dispatcher()); + co_await wil::resume_foreground(control.Dispatcher()); const auto currentOffset = control.ScrollOffset(); control.ScrollViewport(::base::ClampAdd(currentOffset, delta)); @@ -865,7 +865,7 @@ namespace winrt::TerminalApp::implementation }); events.taskbarToken = control.SetTaskbarProgress([dispatcher, weakThis](auto&&, auto &&) -> winrt::fire_and_forget { - co_await winrt::resume_foreground(dispatcher); + co_await wil::resume_foreground(dispatcher); // Check if Tab's lifetime has expired if (auto tab{ weakThis.get() }) { @@ -1074,7 +1074,7 @@ namespace winrt::TerminalApp::implementation { if (tab->_zoomedPane) { - co_await winrt::resume_foreground(tab->Content().Dispatcher()); + co_await wil::resume_foreground(tab->Content().Dispatcher()); tab->Content(tab->_rootPane->GetRootElement()); tab->ExitZoom(); @@ -1088,7 +1088,7 @@ namespace winrt::TerminalApp::implementation // did not actually change. Triggering if (pane != tab->_activePane && !tab->_activePane->_IsLeaf()) { - co_await winrt::resume_foreground(tab->Content().Dispatcher()); + co_await wil::resume_foreground(tab->Content().Dispatcher()); tab->_UpdateActivePane(tab->_activePane); } diff --git a/src/cascadia/TerminalApp/pch.h b/src/cascadia/TerminalApp/pch.h index 92e8003e4ef..0ba3fd6fbfe 100644 --- a/src/cascadia/TerminalApp/pch.h +++ b/src/cascadia/TerminalApp/pch.h @@ -82,3 +82,4 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalAppProvider); #include "til.h" #include +#include // must go after the CoreDispatcher type is defined diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 2410f585b7d..d09c1c06884 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -244,7 +244,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Dispatch a call to the UI thread to apply the new settings to the // terminal. - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); _core.UpdateSettings(settings, unfocusedAppearance); @@ -260,7 +260,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::fire_and_forget TermControl::UpdateAppearance(IControlAppearance newAppearance) { // Dispatch a call to the UI thread - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); _UpdateAppearanceFromUIThread(newAppearance); } @@ -504,7 +504,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const IInspectable& /*args*/) { auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto control{ weakThis.get() }) { til::color newBgColor{ _core.BackgroundColor() }; @@ -626,7 +626,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // We also don't lock for things that come back from the renderer. auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto control{ weakThis.get() }) { @@ -651,7 +651,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto hr = static_cast(args.Result()); auto weakThis{ get_weak() }; - co_await winrt::resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto control{ weakThis.get() }) { @@ -1376,7 +1376,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::fire_and_forget TermControl::_coreTransparencyChanged(IInspectable /*sender*/, Control::TransparencyChangedEventArgs /*args*/) { - co_await resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); try { _changeBackgroundOpacity(); @@ -1771,7 +1771,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // just go ahead and do it. // This can come in off the COM thread - hop back to the UI thread. auto weakThis{ get_weak() }; - co_await resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto control{ weakThis.get() }; !control->_IsClosing()) { control->TSFInputControl().TryRedrawCanvas(); @@ -2618,7 +2618,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation IInspectable args) { auto weakThis{ get_weak() }; - co_await resume_foreground(Dispatcher()); + co_await wil::resume_foreground(Dispatcher()); if (auto self{ weakThis.get() }) { auto lastHoveredCell = _core.HoveredCell(); diff --git a/src/cascadia/TerminalControl/pch.h b/src/cascadia/TerminalControl/pch.h index 018137572fa..7d710c5b5c7 100644 --- a/src/cascadia/TerminalControl/pch.h +++ b/src/cascadia/TerminalControl/pch.h @@ -65,3 +65,4 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider); #include "ThrottledFunc.h" #include +#include // must go after the CoreDispatcher type is defined diff --git a/src/cascadia/TerminalSettingsModel/pch.h b/src/cascadia/TerminalSettingsModel/pch.h index b922b9efea9..3f0220ef1a4 100644 --- a/src/cascadia/TerminalSettingsModel/pch.h +++ b/src/cascadia/TerminalSettingsModel/pch.h @@ -58,3 +58,4 @@ TRACELOGGING_DECLARE_PROVIDER(g_hSettingsModelProvider); #include #include +#include // must go after the CoreDispatcher type is defined diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 3ebfd52593a..a12f1f1ca6a 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -841,7 +841,7 @@ winrt::Windows::Foundation::IAsyncOperation AppHost::_GetWindowL winrt::hstring layoutJson = L""; // Use the main thread since we are accessing controls. - co_await winrt::resume_foreground(_logic.GetRoot().Dispatcher()); + co_await wil::resume_foreground(_logic.GetRoot().Dispatcher()); try { const auto pos = _GetWindowLaunchPosition(); @@ -1017,7 +1017,7 @@ void AppHost::_listenForInboundConnections() winrt::fire_and_forget AppHost::_setupGlobalHotkeys() { // The hotkey MUST be registered on the main thread. It will fail otherwise! - co_await winrt::resume_foreground(_logic.GetRoot().Dispatcher()); + co_await wil::resume_foreground(_logic.GetRoot().Dispatcher()); if (!_window) { @@ -1354,7 +1354,7 @@ winrt::fire_and_forget AppHost::_QuitRequested(const winrt::Windows::Foundation: const winrt::Windows::Foundation::IInspectable&) { // Need to be on the main thread to close out all of the tabs. - co_await winrt::resume_foreground(_logic.GetRoot().Dispatcher()); + co_await wil::resume_foreground(_logic.GetRoot().Dispatcher()); _logic.Quit(); } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index bacf5c35b5d..b336c60a7f9 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -1207,7 +1207,7 @@ bool IslandWindow::RegisterHotKey(const int index, const winrt::Microsoft::Termi winrt::fire_and_forget IslandWindow::SummonWindow(Remoting::SummonWindowBehavior args) { // On the foreground thread: - co_await winrt::resume_foreground(_rootGrid.Dispatcher()); + co_await wil::resume_foreground(_rootGrid.Dispatcher()); _summonWindowRoutineBody(args); } diff --git a/src/cascadia/WindowsTerminal/pch.h b/src/cascadia/WindowsTerminal/pch.h index 66664b2a07e..19bfcdb27ff 100644 --- a/src/cascadia/WindowsTerminal/pch.h +++ b/src/cascadia/WindowsTerminal/pch.h @@ -91,3 +91,4 @@ TRACELOGGING_DECLARE_PROVIDER(g_hWindowsTerminalProvider); #include "til.h" #include +#include // must go after the CoreDispatcher type is defined diff --git a/src/cascadia/wt/wt.vcxproj b/src/cascadia/wt/wt.vcxproj index e1e47c17090..ab3bc16ae5b 100644 --- a/src/cascadia/wt/wt.vcxproj +++ b/src/cascadia/wt/wt.vcxproj @@ -11,6 +11,7 @@ + @@ -24,6 +25,7 @@ + diff --git a/src/common.build.pre.props b/src/common.build.pre.props index b8178508228..80ed4fd94e3 100644 --- a/src/common.build.pre.props +++ b/src/common.build.pre.props @@ -112,7 +112,7 @@ true precomp.h ProgramDatabase - $(SolutionDir)\src\inc;$(SolutionDir)\dep;$(SolutionDir)\dep\Console;$(SolutionDir)\dep\gsl\include;$(SolutionDir)\dep\wil\include;$(SolutionDir)\dep\Win32K;$(SolutionDir)\oss\boost\boost_1_73_0;$(SolutionDir)\oss\chromium;$(SolutionDir)\oss\dynamic_bitset;$(SolutionDir)\oss\fmt\include;$(SolutionDir)\oss\interval_tree;$(SolutionDir)\oss\libpopcnt;$(SolutionDir)\oss\pcg\include;%(AdditionalIncludeDirectories); + $(SolutionDir)\src\inc;$(SolutionDir)\dep;$(SolutionDir)\dep\Console;$(SolutionDir)\dep\gsl\include;$(SolutionDir)\dep\Win32K;$(SolutionDir)\oss\boost\boost_1_73_0;$(SolutionDir)\oss\chromium;$(SolutionDir)\oss\dynamic_bitset;$(SolutionDir)\oss\fmt\include;$(SolutionDir)\oss\interval_tree;$(SolutionDir)\oss\libpopcnt;$(SolutionDir)\oss\pcg\include;%(AdditionalIncludeDirectories); true false false @@ -227,7 +227,7 @@ This project references git submodule(s) that are missing on this computer. Use `git submodule update --init --recursive` to download them. For more information, see https://github.com/microsoft/terminal#building-the-code. - + diff --git a/src/common.nugetversions.targets b/src/common.nugetversions.targets index 025d7418948..70621262600 100644 --- a/src/common.nugetversions.targets +++ b/src/common.nugetversions.targets @@ -58,6 +58,9 @@ + + + @@ -92,6 +95,9 @@ + + + diff --git a/src/host/exe/Host.EXE.vcxproj b/src/host/exe/Host.EXE.vcxproj index c21bb27c8a2..40d3007b2b5 100644 --- a/src/host/exe/Host.EXE.vcxproj +++ b/src/host/exe/Host.EXE.vcxproj @@ -11,6 +11,7 @@ + @@ -96,4 +97,5 @@ + diff --git a/src/host/lib/hostlib.vcxproj b/src/host/lib/hostlib.vcxproj index fb83977af9c..cf35a1301e1 100644 --- a/src/host/lib/hostlib.vcxproj +++ b/src/host/lib/hostlib.vcxproj @@ -9,8 +9,10 @@ StaticLibrary + + diff --git a/src/interactivity/base/lib/InteractivityBase.vcxproj b/src/interactivity/base/lib/InteractivityBase.vcxproj index 0161b56daa4..0af5193c7e2 100644 --- a/src/interactivity/base/lib/InteractivityBase.vcxproj +++ b/src/interactivity/base/lib/InteractivityBase.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -50,4 +51,5 @@ + diff --git a/src/interactivity/win32/lib/win32.LIB.vcxproj b/src/interactivity/win32/lib/win32.LIB.vcxproj index 82a57c12398..6ce9bc9ebab 100644 --- a/src/interactivity/win32/lib/win32.LIB.vcxproj +++ b/src/interactivity/win32/lib/win32.LIB.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + _WINDLL;%(PreprocessorDefinitions) @@ -73,4 +74,5 @@ + diff --git a/src/internal/internal.vcxproj b/src/internal/internal.vcxproj index 332586eb195..f9be0aa8aae 100644 --- a/src/internal/internal.vcxproj +++ b/src/internal/internal.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -21,4 +22,5 @@ + diff --git a/src/propsheet/propsheet.vcxproj b/src/propsheet/propsheet.vcxproj index 01f16cf1b2e..55b315a0fc7 100644 --- a/src/propsheet/propsheet.vcxproj +++ b/src/propsheet/propsheet.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + @@ -85,4 +86,5 @@ + diff --git a/src/propslib/propslib.vcxproj b/src/propslib/propslib.vcxproj index bf1fa6d63e8..20b38f341f7 100644 --- a/src/propslib/propslib.vcxproj +++ b/src/propslib/propslib.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -28,4 +29,5 @@ + diff --git a/src/renderer/atlas/atlas.vcxproj b/src/renderer/atlas/atlas.vcxproj index 5b257695e0e..662865002dc 100644 --- a/src/renderer/atlas/atlas.vcxproj +++ b/src/renderer/atlas/atlas.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -51,10 +52,11 @@ + pch.h $(OutDir)$(ProjectName)\;%(AdditionalIncludeDirectories) - \ No newline at end of file + diff --git a/src/renderer/base/lib/base.vcxproj b/src/renderer/base/lib/base.vcxproj index ceed166fd27..99ec05c9400 100644 --- a/src/renderer/base/lib/base.vcxproj +++ b/src/renderer/base/lib/base.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -40,4 +41,5 @@ + diff --git a/src/renderer/dx/lib/dx.vcxproj b/src/renderer/dx/lib/dx.vcxproj index d26c951f43a..d54407c5b84 100644 --- a/src/renderer/dx/lib/dx.vcxproj +++ b/src/renderer/dx/lib/dx.vcxproj @@ -14,6 +14,7 @@ + @@ -41,4 +42,5 @@ + diff --git a/src/renderer/gdi/lib/gdi.vcxproj b/src/renderer/gdi/lib/gdi.vcxproj index bf1fe0758f9..95922dc322e 100644 --- a/src/renderer/gdi/lib/gdi.vcxproj +++ b/src/renderer/gdi/lib/gdi.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -29,4 +30,5 @@ + diff --git a/src/renderer/uia/lib/uia.vcxproj b/src/renderer/uia/lib/uia.vcxproj index d67ddc1406e..70b4c245b40 100644 --- a/src/renderer/uia/lib/uia.vcxproj +++ b/src/renderer/uia/lib/uia.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + Create @@ -21,4 +22,5 @@ + diff --git a/src/renderer/vt/lib/vt.vcxproj b/src/renderer/vt/lib/vt.vcxproj index eac03be76a7..ff5095a3a3c 100644 --- a/src/renderer/vt/lib/vt.vcxproj +++ b/src/renderer/vt/lib/vt.vcxproj @@ -9,8 +9,10 @@ StaticLibrary + + diff --git a/src/server/lib/server.vcxproj b/src/server/lib/server.vcxproj index d7f05cf139d..cadd74b0b8e 100644 --- a/src/server/lib/server.vcxproj +++ b/src/server/lib/server.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -69,4 +70,5 @@ + diff --git a/src/terminal/adapter/lib/adapter.vcxproj b/src/terminal/adapter/lib/adapter.vcxproj index 6ec11be72ad..0a6b1205790 100644 --- a/src/terminal/adapter/lib/adapter.vcxproj +++ b/src/terminal/adapter/lib/adapter.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -46,4 +47,5 @@ - \ No newline at end of file + + diff --git a/src/terminal/input/lib/terminalinput.vcxproj b/src/terminal/input/lib/terminalinput.vcxproj index 0dd6aead6ff..16f495dcd26 100644 --- a/src/terminal/input/lib/terminalinput.vcxproj +++ b/src/terminal/input/lib/terminalinput.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -28,4 +29,5 @@ - \ No newline at end of file + + diff --git a/src/terminal/parser/lib/parser.vcxproj b/src/terminal/parser/lib/parser.vcxproj index 35cd5abdd29..31a950e33d4 100644 --- a/src/terminal/parser/lib/parser.vcxproj +++ b/src/terminal/parser/lib/parser.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -19,4 +20,5 @@ + diff --git a/src/tools/buffersize/buffersize.vcxproj b/src/tools/buffersize/buffersize.vcxproj index c599bdf8e31..998c2ee7454 100644 --- a/src/tools/buffersize/buffersize.vcxproj +++ b/src/tools/buffersize/buffersize.vcxproj @@ -9,6 +9,7 @@ Application + @@ -24,4 +25,5 @@ + diff --git a/src/tools/echokey/ConEchoKey.vcxproj b/src/tools/echokey/ConEchoKey.vcxproj index 9d91d6ccbbd..7a9fe839d68 100644 --- a/src/tools/echokey/ConEchoKey.vcxproj +++ b/src/tools/echokey/ConEchoKey.vcxproj @@ -9,6 +9,7 @@ Application + @@ -24,4 +25,5 @@ + diff --git a/src/tools/fontlist/FontList.vcxproj b/src/tools/fontlist/FontList.vcxproj index e3974b647e4..040497286d0 100644 --- a/src/tools/fontlist/FontList.vcxproj +++ b/src/tools/fontlist/FontList.vcxproj @@ -9,6 +9,7 @@ Application + @@ -24,4 +25,5 @@ + diff --git a/src/tools/vtpipeterm/VtPipeTerm.vcxproj b/src/tools/vtpipeterm/VtPipeTerm.vcxproj index a292ee1e0ac..9b2fcb372b8 100644 --- a/src/tools/vtpipeterm/VtPipeTerm.vcxproj +++ b/src/tools/vtpipeterm/VtPipeTerm.vcxproj @@ -9,6 +9,7 @@ Application + @@ -28,4 +29,5 @@ + diff --git a/src/tsf/tsf.vcxproj b/src/tsf/tsf.vcxproj index ac41260c6da..1e5a3f0cdf3 100644 --- a/src/tsf/tsf.vcxproj +++ b/src/tsf/tsf.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -34,4 +35,5 @@ + diff --git a/src/types/lib/types.vcxproj b/src/types/lib/types.vcxproj index bebe7059a3d..24372906d78 100644 --- a/src/types/lib/types.vcxproj +++ b/src/types/lib/types.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -70,4 +71,5 @@ + diff --git a/src/winconpty/dll/winconptydll.vcxproj b/src/winconpty/dll/winconptydll.vcxproj index 8c9d17ee6d5..a9467f61ab1 100644 --- a/src/winconpty/dll/winconptydll.vcxproj +++ b/src/winconpty/dll/winconptydll.vcxproj @@ -9,6 +9,7 @@ DynamicLibrary + Create @@ -22,6 +23,7 @@ + winconpty.def diff --git a/src/winconpty/lib/winconptylib.vcxproj b/src/winconpty/lib/winconptylib.vcxproj index ea4b63f8355..ce30460c595 100644 --- a/src/winconpty/lib/winconptylib.vcxproj +++ b/src/winconpty/lib/winconptylib.vcxproj @@ -9,6 +9,7 @@ StaticLibrary + @@ -24,7 +25,8 @@ - From 0bc66abd3b9777200178ca2f4760eaee7ab72812 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 28 Mar 2022 17:28:16 -0500 Subject: [PATCH 23/67] Add mp:PhoneIdentity to stop Store from rewriting our packages (#12779) If we do not include mp:PhoneIdentity in our AppxManifest, the store will edit our package and re-sign it for distribution. When that happens, it creates a divergence: there are now two versions of our package with the same name and version number, but different contents. This breaks everything. **THIS IS LOAD BEARING** --- src/cascadia/CascadiaPackage/Package-Pre.appxmanifest | 5 +++++ src/cascadia/CascadiaPackage/Package.appxmanifest | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest b/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest index a55af61e2a0..06f3ec52d8f 100644 --- a/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest +++ b/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest @@ -235,4 +235,9 @@ + + + diff --git a/src/cascadia/CascadiaPackage/Package.appxmanifest b/src/cascadia/CascadiaPackage/Package.appxmanifest index cb99c9a07ea..43e65c64220 100644 --- a/src/cascadia/CascadiaPackage/Package.appxmanifest +++ b/src/cascadia/CascadiaPackage/Package.appxmanifest @@ -235,4 +235,9 @@ + + + From 0651d92dba09aaf13a807f1502a10bef159e4f5d Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 29 Mar 2022 14:07:57 -0500 Subject: [PATCH 24/67] Build PublicTerminalCore for ARM64, and package it with WPF (#12787) I also took the opportunity to clean up the WPF stage's artifact rules. Closes #12786 --- OpenConsole.sln | 2 ++ build/pipelines/release.yml | 30 +++++++------------ .../WpfTerminalControl.csproj | 8 +++++ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/OpenConsole.sln b/OpenConsole.sln index f53e2cc56b3..5fb7202976b 100644 --- a/OpenConsole.sln +++ b/OpenConsole.sln @@ -2117,6 +2117,7 @@ Global {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|Any CPU.ActiveCfg = Debug|Win32 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|ARM.ActiveCfg = Debug|Win32 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|ARM64.Build.0 = Debug|ARM64 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|DotNet_x64Test.ActiveCfg = Debug|x64 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|DotNet_x64Test.Build.0 = Debug|x64 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32 @@ -2135,6 +2136,7 @@ Global {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|Any CPU.ActiveCfg = Release|Win32 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|ARM.ActiveCfg = Release|Win32 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|ARM64.ActiveCfg = Release|ARM64 + {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|ARM64.Build.0 = Release|ARM64 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|DotNet_x64Test.ActiveCfg = Release|x64 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|DotNet_x64Test.Build.0 = Release|x64 {84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|DotNet_x86Test.ActiveCfg = Release|Win32 diff --git a/build/pipelines/release.yml b/build/pipelines/release.yml index cd2cc038c1a..301e8709b6f 100644 --- a/build/pipelines/release.yml +++ b/build/pipelines/release.yml @@ -216,7 +216,6 @@ jobs: - ${{ if eq(parameters.buildWPF, true) }}: - task: VSBuild@1 displayName: Build solution **\OpenConsole.sln for PublicTerminalCore - condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64')) inputs: solution: '**\OpenConsole.sln' vsVersion: 16.0 @@ -270,7 +269,6 @@ jobs: - ${{ if eq(parameters.buildWPF, true) }}: - task: CopyFiles@2 displayName: Copy PublicTerminalCore.dll to Artifacts - condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64')) inputs: Contents: >- **/PublicTerminalCore.dll @@ -281,7 +279,6 @@ jobs: flattenFolders: true - task: PublishBuildArtifacts@1 displayName: Publish Artifact (PublicTerminalCore) - condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64')) inputs: PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion) @@ -389,31 +386,26 @@ jobs: displayName: Package ES - Setup Build inputs: disableOutputRedirect: true - - task: DownloadBuildArtifacts@0 - displayName: Download x86 PublicTerminalCore - inputs: - artifactName: wpf-dll-x86-$(BuildConfiguration)-Win10 - itemPattern: '**/*.dll' - downloadPath: bin\Win32\$(BuildConfiguration)\ - extractTars: false - - task: DownloadBuildArtifacts@0 - displayName: Download x64 PublicTerminalCore - inputs: - artifactName: wpf-dll-x64-$(BuildConfiguration)-Win10 - itemPattern: '**/*.dll' - downloadPath: bin\x64\$(BuildConfiguration)\ - extractTars: false + - ${{ each platform in parameters.buildPlatforms }}: + - task: DownloadBuildArtifacts@0 + displayName: Download ${{ platform }} PublicTerminalCore + inputs: + artifactName: wpf-dll-${{ platform }}-$(BuildConfiguration)-Win10 + itemPattern: '**/*.dll' + downloadPath: bin\${{ platform }}\$(BuildConfiguration)\ + extractTars: false - task: PowerShell@2 - displayName: Move downloaded artifacts up a level + displayName: Move downloaded artifacts around inputs: targetType: inline # Find all artifact files and move them up a directory. Ugh. - script: >- + script: |- Get-ChildItem bin -Recurse -Directory -Filter wpf-dll-* | % { $_ | Get-ChildItem -Recurse -File | % { Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName } } + Move-Item bin\x86 bin\Win32 - task: NuGetToolInstaller@1 displayName: Use NuGet 5.10.0 inputs: diff --git a/src/cascadia/WpfTerminalControl/WpfTerminalControl.csproj b/src/cascadia/WpfTerminalControl/WpfTerminalControl.csproj index 7b074d86889..e47e5224865 100644 --- a/src/cascadia/WpfTerminalControl/WpfTerminalControl.csproj +++ b/src/cascadia/WpfTerminalControl/WpfTerminalControl.csproj @@ -50,6 +50,14 @@ true runtimes\win-x64\native\ + + true + runtimes\win-arm64\native\ + + + true + runtimes\win-arm64\native\ + From 4e61be9cd72a578cecd24b2c2d0c17fe7dd9635a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 29 Mar 2022 17:16:57 -0500 Subject: [PATCH 25/67] Fix the OS build (#12790) The `cascadia/` directory straight up isn't checked into the OS. So adding a test dependency on code in there was a BAD IDEA. --- src/cascadia/UnitTests_Control/ControlCoreTests.cpp | 2 +- src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp | 2 +- src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp | 2 +- src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp | 2 +- src/host/ut_host/ScreenBufferTests.cpp | 2 +- src/{cascadia/UnitTests_TerminalCore => inc}/TestUtils.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/{cascadia/UnitTests_TerminalCore => inc}/TestUtils.h (97%) diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index a936d046eba..105cba0409b 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -6,7 +6,7 @@ #include "../TerminalControl/ControlCore.h" #include "MockControlSettings.h" #include "MockConnection.h" -#include "../UnitTests_TerminalCore/TestUtils.h" +#include "../../inc/TestUtils.h" using namespace Microsoft::Console; using namespace WEX::Logging; diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index 35a6f8a6665..17c35ef3e4b 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -26,7 +26,7 @@ #include "../cascadia/TerminalCore/Terminal.hpp" -#include "TestUtils.h" +#include "../../inc/TestUtils.h" using namespace WEX::Common; using namespace WEX::Logging; diff --git a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp index 2c94a43ca57..38b89d69bdc 100644 --- a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp @@ -13,7 +13,7 @@ #include "../cascadia/TerminalCore/Terminal.hpp" #include "MockTermSettings.h" #include "consoletaeftemplates.hpp" -#include "TestUtils.h" +#include "../../inc/TestUtils.h" using namespace winrt::Microsoft::Terminal::Core; using namespace Microsoft::Terminal::Core; diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp index e9378f50d20..1684fa244b0 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp @@ -8,7 +8,7 @@ #include "../cascadia/TerminalCore/Terminal.hpp" #include "MockTermSettings.h" #include "consoletaeftemplates.hpp" -#include "TestUtils.h" +#include "../../inc/TestUtils.h" using namespace winrt::Microsoft::Terminal::Core; using namespace Microsoft::Terminal::Core; diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 5315687810c..a61839d17c5 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -17,7 +17,7 @@ #include "../../inc/conattrs.hpp" #include "../../types/inc/Viewport.hpp" -#include "../../cascadia/UnitTests_TerminalCore/TestUtils.h" +#include "../../inc/TestUtils.h" #include diff --git a/src/cascadia/UnitTests_TerminalCore/TestUtils.h b/src/inc/TestUtils.h similarity index 97% rename from src/cascadia/UnitTests_TerminalCore/TestUtils.h rename to src/inc/TestUtils.h index 3f437303938..922a8d24de0 100644 --- a/src/cascadia/UnitTests_TerminalCore/TestUtils.h +++ b/src/inc/TestUtils.h @@ -12,7 +12,7 @@ Author(s): Mike Griese (migrie) January-2020 --*/ -#include "../../buffer/out/textBuffer.hpp" +#include "../buffer/out/textBuffer.hpp" namespace TerminalCoreUnitTests { From a24d419b7bbe27178f709146fcaf464f3e882e24 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Wed, 30 Mar 2022 17:12:00 -0500 Subject: [PATCH 26/67] Add ServicingPipeline.ps1, a script I use to service Terminal (#12789) This script takes pull requests from a project board, cherry-picks them, and updates the project board. It also yells at you if there are conflicts to resolve, and generally tries to keep track of everything. It is quite cool. --- .github/actions/spelling/excludes.txt | 1 + .../ReleaseEngineering/ServicingPipeline.ps1 | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 tools/ReleaseEngineering/ServicingPipeline.ps1 diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 7d64932c95a..ec940e1dbfc 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -76,6 +76,7 @@ SUMS$ ^src/tools/texttests/fira\.txt$ ^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$ ^src/types/ut_types/UtilsTests.cpp$ +^tools/ReleaseEngineering/ServicingPipeline.ps1$ ^\.github/actions/spelling/ ^\.gitignore$ ^\XamlStyler.json$ diff --git a/tools/ReleaseEngineering/ServicingPipeline.ps1 b/tools/ReleaseEngineering/ServicingPipeline.ps1 new file mode 100644 index 00000000000..8c7f9a84f23 --- /dev/null +++ b/tools/ReleaseEngineering/ServicingPipeline.ps1 @@ -0,0 +1,127 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +#Requires -Version 7 +#Requires -Modules PSGitHub + +[CmdletBinding()] +Param( + [string]$Version, + [string]$SourceBranch = "origin/main", + [switch]$GpgSign = $False +) + +Function Prompt() { + "PSCR {0}> " -f $PWD.Path +} + +Function Enter-ConflictResolutionShell($entry) { + $Global:Abort = $False + $Global:Skip = $False + $Global:Reject = $False + Push-Location -StackName:"ServicingStack" -Path:$PWD > $Null + Write-Host (@" +`e[31;1;7mCONFLICT RESOLUTION REQUIRED`e[m +`e[1mCommit `e[m: `e[1;93m{0}`e[m +`e[1mSubject`e[m: `e[1;93m{1}`e[m + +"@ -f ($_.CommitID, $_.Subject)) + + & git status --short + + Write-Host (@" + +`e[1mCommands`e[m +`e[1;96mdone `e[m Complete conflict resolution and commit +`e[1;96mskip `e[m Skip this commit +`e[1;96mabort `e[m Stop everything +`e[1;96mreject`e[m Skip and `e[31mremove this commit from servicing consideration`e[m +"@) + $Host.EnterNestedPrompt() + Pop-Location -StackName:"ServicingStack" > $Null +} + +Function Done() { + $Host.ExitNestedPrompt() +} + +Function Abort() { + $Global:Abort = $True + $Host.ExitNestedPrompt() +} + +Function Skip() { + $Global:Skip = $True + $Host.ExitNestedPrompt() +} + +Function Reject() { + $Global:Skip = $True + $Global:Reject = $True + $Host.ExitNestedPrompt() +} + +$Script:TodoColumnName = "To Cherry Pick" +$Script:DoneColumnName = "Cherry Picked" +$Script:RejectColumnName = "Rejected" + +# Propagate default values into all PSGitHub cmdlets +$PSDefaultParameterValues['*GitHub*:Owner'] = "microsoft" +$PSDefaultParameterValues['*GitHub*:RepositoryName'] = "terminal" + +$Project = Get-GithubProject -Name "$Version Servicing Pipeline" +$AllColumns = Get-GithubProjectColumn -ProjectId $Project.id +$ToPickColumn = $AllColumns | ? Name -Eq $script:TodoColumnName +$DoneColumn = $AllColumns | ? Name -Eq $script:DoneColumnName +$RejectColumn = $AllColumns | ? Name -Eq $script:RejectColumnName +$Cards = Get-GithubProjectCard -ColumnId $ToPickColumn.id + +& git fetch --all 2>&1 | Out-Null + +$Entries = @(& git log $SourceBranch --grep "(#\($($Cards.Number -Join "\|")\))" "--pretty=format:%H%x1C%s" | + ConvertFrom-CSV -Delimiter "`u{001C}" -Header CommitID,Subject) + +[Array]::Reverse($Entries) + +$PickArgs = @() +If ($GpgSign) { + $PickArgs += , "-S" +} + +$CommitPRRegex = [Regex]"\(#(\d+)\)$" +$Entries | ForEach-Object { + Write-Host "`e[96m`e[1;7mPICK`e[22;27m $($_.CommitID): $($_.Subject)`e[m" + $PR = $CommitPRRegex.Match($_.Subject).Groups[1].Value + $Card = $Cards | ? Number -Eq $PR + $null = & git cherry-pick -x $_.CommitID 2>&1 + $Err = "" + While ($True) { + If ($LASTEXITCODE -ne 0) { + $Err + Enter-ConflictResolutionShell $_ + + If ($Global:Abort) { + & git cherry-pick --abort + Write-Host -ForegroundColor "Red" "YOU'RE ON YOUR OWN" + Exit + } + + If ($Global:Reject) { + Move-GithubProjectCard -CardId $Card.id -ColumnId $RejectColumn.id + # Fall through to Skip + } + + If ($Global:Skip) { + & git cherry-pick --skip + Break + } + + $Err = & git cherry-pick --continue --no-edit + } Else { + & git commit @PickArgs --amend --no-edit --trailer "Service-Card-Id:$($Card.Id)" --trailer "Service-Version:$Version" | Out-Null + Write-Host "`e[92;1;7m OK `e[m" + Move-GithubProjectCard -CardId $Card.id -ColumnId $DoneColumn.id + Break + } + } +} From 2c2f4f9be230e0be015f9bf799f58ef4bea807eb Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Wed, 30 Mar 2022 16:22:42 -0700 Subject: [PATCH 27/67] [FHL] Make VTApiRoutines, which does VT translation for output (#11264) Make a VTApiRoutines servicer that does minimal translations instead of environmental simulation for some output methods. Remaining methods are backed on the existing console host infrastructure (primarily input related methods). ## PR Checklist * [x] I work here * [x] It's Fix-Hack-Learn quality so it's behind a feature gate so we can keep refining it. But it's a start! To turn this on, you will have to be in the Dev or Preview rings (feature staged). Then add `experimental.connection.passthroughMode: true` to a profile and on the next launch, the flags will propagate down through the `ConptyConnection` into the underlying `Openconsole.exe` startup and tell it to use the passthrough mode instead of the full simulation mode. ## Validation Steps Performed - Played with it manually in CMD.exe, it seems to work mostly. - Played with it manually in Ubuntu WSL, it seems to work. - Played with it manually in Powershell and it's mostly sad. It'll get there. Starts #1173 --- .github/actions/spelling/allow/apis.txt | 3 +- .github/actions/spelling/expect/expect.txt | 2 + .vscode/settings.json | 6 +- doc/cascadia/profiles.schema.json | 4 + .../PublicTerminalCore/HwndTerminal.cpp | 4 +- .../PublicTerminalCore/HwndTerminal.hpp | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 39 +- .../TerminalConnection/ConptyConnection.cpp | 16 +- .../TerminalConnection/ConptyConnection.h | 1 + src/cascadia/TerminalControl/ControlCore.cpp | 2 +- src/cascadia/TerminalCore/ICoreSettings.idl | 1 + src/cascadia/TerminalCore/ITerminalApi.hpp | 2 + src/cascadia/TerminalCore/Terminal.cpp | 2 +- src/cascadia/TerminalCore/Terminal.hpp | 9 +- src/cascadia/TerminalCore/TerminalApi.cpp | 10 + .../TerminalCore/TerminalDispatch.cpp | 64 ++ .../TerminalCore/TerminalDispatch.hpp | 6 + .../ProfileViewModel.cpp | 5 + .../TerminalSettingsEditor/ProfileViewModel.h | 2 + .../ProfileViewModel.idl | 2 + .../Profiles_Advanced.xaml | 10 + .../Resources/en-US/Resources.resw | 4 + .../TerminalSettingsModel/MTSMSettings.h | 3 +- .../TerminalSettingsModel/Profile.idl | 1 + .../TerminalSettings.cpp | 1 + .../TerminalSettingsModel/TerminalSettings.h | 1 + .../UnitTests_TerminalCore/InputTest.cpp | 2 +- src/cascadia/inc/ControlProperties.h | 3 +- src/features.xml | 11 + src/host/CommandListPopup.cpp | 18 +- src/host/ConsoleArguments.cpp | 12 + src/host/ConsoleArguments.hpp | 21 +- src/host/VtApiRoutines.cpp | 863 ++++++++++++++++++ src/host/VtApiRoutines.h | 392 ++++++++ src/host/VtInputThread.cpp | 14 +- src/host/VtInputThread.hpp | 3 + src/host/VtIo.cpp | 48 +- src/host/VtIo.hpp | 1 + src/host/directio.cpp | 6 +- src/host/globals.cpp | 5 + src/host/globals.h | 5 +- src/host/host-common.vcxitems | 2 + src/host/lib/hostlib.vcxproj.filters | 8 +- src/host/outputStream.cpp | 8 +- src/host/popup.cpp | 8 +- src/host/sources.inc | 1 + src/host/srvinit.cpp | 6 +- src/host/ut_host/ConsoleArgumentsTests.cpp | 156 ++-- src/host/ut_host/ScreenBufferTests.cpp | 18 +- src/inc/conpty-static.h | 1 + src/interactivity/win32/windowio.cpp | 4 +- src/renderer/vt/Xterm256Engine.cpp | 4 +- src/renderer/vt/Xterm256Engine.hpp | 4 + src/renderer/vt/XtermEngine.cpp | 10 + src/renderer/vt/state.cpp | 76 +- src/renderer/vt/tracing.cpp | 17 + src/renderer/vt/tracing.hpp | 1 + src/renderer/vt/vtrenderer.hpp | 8 + src/server/IApiRoutines.h | 2 + .../parser/InputStateMachineEngine.cpp | 5 + .../parser/InputStateMachineEngine.hpp | 2 + src/tools/closetest/closetest.cpp | 5 +- src/winconpty/winconpty.cpp | 4 +- src/winconpty/winconpty.h | 1 + 64 files changed, 1826 insertions(+), 131 deletions(-) create mode 100644 src/host/VtApiRoutines.cpp create mode 100644 src/host/VtApiRoutines.h diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index daf1feb13af..3045f47721c 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -95,11 +95,12 @@ lround Lsa lsass LSHIFT +memchr memicmp MENUCOMMAND MENUDATA -MENUINFO MENUITEMINFOW +MENUINFO MOUSELEAVE mov mptt diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 652be19189b..a68bc4a326c 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -519,6 +519,7 @@ DECAUPSS DECAWM DECCKM DECCOLM +DECCRA DECDHL decdld DECDLD @@ -2632,6 +2633,7 @@ VSTS VSTT vstudio vswhere +vtapi vtapp VTE VTID diff --git a/.vscode/settings.json b/.vscode/settings.json index 142fa20f6ab..604f91797d9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -94,7 +94,11 @@ "xlocinfo": "cpp", "xmemory": "cpp", "xstddef": "cpp", - "xtr1common": "cpp" + "xtr1common": "cpp", + "coroutine": "cpp", + "format": "cpp", + "forward_list": "cpp", + "latch": "cpp" }, "files.exclude": { "**/bin/**": true, diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index ac7ab589514..ba840fdcf6a 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -2051,6 +2051,10 @@ "default": false, "description": "When true, this profile should always open in an elevated context. If the window isn't running as an Administrator, then a new elevated window will be created." }, + "experimental.connection.passthroughMode": { + "description": "When set to true, directs the PTY for this connection to use pass-through mode instead of the original Conhost PTY simulation engine. This is an experimental feature, and its continued existence is not guaranteed.", + "type": "boolean" + }, "experimental.retroTerminalEffect": { "description": "When set to true, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed.", "type": "boolean" diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 1f188b21037..d318d13f906 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -242,7 +242,7 @@ HRESULT HwndTerminal::Initialize() _terminal->Create(COORD{ 80, 25 }, 1000, *_renderer); _terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12)); _terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(204, 204, 204)); - _terminal->SetWriteInputCallback([=](std::wstring& input) noexcept { _WriteTextToConnection(input); }); + _terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); }); localPointerToThread->EnablePainting(); _multiClickTime = std::chrono::milliseconds{ GetDoubleClickTime() }; @@ -282,7 +282,7 @@ void HwndTerminal::RegisterScrollCallback(std::function cal _terminal->SetScrollPositionChangedCallback(callback); } -void HwndTerminal::_WriteTextToConnection(const std::wstring& input) noexcept +void HwndTerminal::_WriteTextToConnection(const std::wstring_view input) noexcept { if (!_pfnWriteCallback) { diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp index 0510675efc0..3a364bd0f18 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp @@ -108,7 +108,7 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo friend void _stdcall TerminalKillFocus(void* terminal); void _UpdateFont(int newDpi); - void _WriteTextToConnection(const std::wstring& text) noexcept; + void _WriteTextToConnection(const std::wstring_view text) noexcept; HRESULT _CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting); HRESULT _CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat); void _PasteTextFromClipboard() noexcept; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 91694653088..a137bf1637b 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1070,13 +1070,20 @@ namespace winrt::TerminalApp::implementation std::filesystem::path azBridgePath{ wil::GetModuleFileNameW(nullptr) }; azBridgePath.replace_filename(L"TerminalAzBridge.exe"); connection = TerminalConnection::ConptyConnection(); - connection.Initialize(TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.wstring(), - L".", - L"Azure", - nullptr, - ::base::saturated_cast(settings.InitialRows()), - ::base::saturated_cast(settings.InitialCols()), - winrt::guid())); + auto valueSet = TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.wstring(), + L".", + L"Azure", + nullptr, + ::base::saturated_cast(settings.InitialRows()), + ::base::saturated_cast(settings.InitialCols()), + winrt::guid()); + + if constexpr (Feature_VtPassthroughMode::IsEnabled()) + { + valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough())); + } + + connection.Initialize(valueSet); } else @@ -1114,13 +1121,17 @@ namespace winrt::TerminalApp::implementation } auto conhostConn = TerminalConnection::ConptyConnection(); - conhostConn.Initialize(TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(), - newWorkingDirectory, - settings.StartingTitle(), - envMap.GetView(), - ::base::saturated_cast(settings.InitialRows()), - ::base::saturated_cast(settings.InitialCols()), - winrt::guid())); + auto valueSet = TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(), + newWorkingDirectory, + settings.StartingTitle(), + envMap.GetView(), + ::base::saturated_cast(settings.InitialRows()), + ::base::saturated_cast(settings.InitialCols()), + winrt::guid()); + + valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough())); + + conhostConn.Initialize(valueSet); sessionGuid = conhostConn.Guid(); connection = conhostConn; diff --git a/src/cascadia/TerminalConnection/ConptyConnection.cpp b/src/cascadia/TerminalConnection/ConptyConnection.cpp index b4e5978440b..762d7b4f90a 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.cpp +++ b/src/cascadia/TerminalConnection/ConptyConnection.cpp @@ -266,6 +266,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation _initialCols = winrt::unbox_value_or(settings.TryLookup(L"initialCols").try_as(), _initialCols); _guid = winrt::unbox_value_or(settings.TryLookup(L"guid").try_as(), _guid); _environment = settings.TryLookup(L"environment").try_as(); + if constexpr (Feature_VtPassthroughMode::IsEnabled()) + { + _passthroughMode = winrt::unbox_value_or(settings.TryLookup(L"passthroughMode").try_as(), _passthroughMode); + } } if (_guid == guid{}) @@ -295,7 +299,17 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // handoff from an already-started PTY process. if (!_inPipe) { - THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, PSEUDOCONSOLE_RESIZE_QUIRK | PSEUDOCONSOLE_WIN32_INPUT_MODE, &_inPipe, &_outPipe, &_hPC)); + DWORD flags = PSEUDOCONSOLE_RESIZE_QUIRK | PSEUDOCONSOLE_WIN32_INPUT_MODE; + + if constexpr (Feature_VtPassthroughMode::IsEnabled()) + { + if (_passthroughMode) + { + WI_SetFlag(flags, PSEUDOCONSOLE_PASSTHROUGH_MODE); + } + } + + THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, flags, &_inPipe, &_outPipe, &_hPC)); THROW_IF_FAILED(_LaunchAttachedClient()); } // But if it was an inbound handoff... attempt to synchronize the size of it with what our connection diff --git a/src/cascadia/TerminalConnection/ConptyConnection.h b/src/cascadia/TerminalConnection/ConptyConnection.h index 4089a944675..fc4ed55c08e 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.h +++ b/src/cascadia/TerminalConnection/ConptyConnection.h @@ -85,6 +85,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation til::u8state _u8State{}; std::wstring _u16Str{}; std::array _buffer{}; + bool _passthroughMode{}; DWORD _OutputThread(); }; diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index f473a817439..820686d322b 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -77,7 +77,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // This event is explicitly revoked in the destructor: does not need weak_ref _connectionOutputEventToken = _connection.TerminalOutput({ this, &ControlCore::_connectionOutputHandler }); - _terminal->SetWriteInputCallback([this](std::wstring& wstr) { + _terminal->SetWriteInputCallback([this](std::wstring_view wstr) { _sendInputToConnection(wstr); }); diff --git a/src/cascadia/TerminalCore/ICoreSettings.idl b/src/cascadia/TerminalCore/ICoreSettings.idl index dd0b4939b3b..5b05a72c05e 100644 --- a/src/cascadia/TerminalCore/ICoreSettings.idl +++ b/src/cascadia/TerminalCore/ICoreSettings.idl @@ -22,6 +22,7 @@ namespace Microsoft.Terminal.Core Boolean ForceVTInput; Boolean TrimBlockSelection; Boolean DetectURLs; + Boolean VtPassthrough; Windows.Foundation.IReference TabColor; Windows.Foundation.IReference StartingTabColor; diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index ebff6fd2072..3aebe7ea1c8 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -21,6 +21,8 @@ namespace Microsoft::Terminal::Core virtual void PrintString(std::wstring_view string) = 0; + virtual bool ReturnResponse(std::wstring_view responseString) = 0; + virtual TextAttribute GetTextAttributes() const = 0; virtual void SetTextAttributes(const TextAttribute& attrs) = 0; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 4b84c73584a..5db2cff6b9e 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -1164,7 +1164,7 @@ void Terminal::_NotifyTerminalCursorPositionChanged() noexcept } } -void Terminal::SetWriteInputCallback(std::function pfn) noexcept +void Terminal::SetWriteInputCallback(std::function pfn) noexcept { _pfnWriteInput.swap(pfn); } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index a8b67233396..d094115d4de 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -77,10 +77,10 @@ class Microsoft::Terminal::Core::Terminal final : void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance); void SetFontInfo(const FontInfo& fontInfo); - // Write goes through the parser + // Write comes from the PTY and goes to our parser to be stored in the output buffer void Write(std::wstring_view stringView); - // WritePastedText goes directly to the connection + // WritePastedText comes from our input and goes back to the PTY's input channel void WritePastedText(std::wstring_view stringView); [[nodiscard]] std::unique_lock LockForReading(); @@ -97,6 +97,7 @@ class Microsoft::Terminal::Core::Terminal final : #pragma region ITerminalApi // These methods are defined in TerminalApi.cpp void PrintString(std::wstring_view stringView) override; + bool ReturnResponse(std::wstring_view responseString) override; TextAttribute GetTextAttributes() const override; void SetTextAttributes(const TextAttribute& attrs) override; Microsoft::Console::Types::Viewport GetBufferSize() override; @@ -197,7 +198,7 @@ class Microsoft::Terminal::Core::Terminal final : const bool IsUiaDataInitialized() const noexcept override; #pragma endregion - void SetWriteInputCallback(std::function pfn) noexcept; + void SetWriteInputCallback(std::function pfn) noexcept; void SetWarningBellCallback(std::function pfn) noexcept; void SetTitleChangedCallback(std::function pfn) noexcept; void SetTabColorChangedCallback(std::function)> pfn) noexcept; @@ -252,7 +253,7 @@ class Microsoft::Terminal::Core::Terminal final : #pragma endregion private: - std::function _pfnWriteInput; + std::function _pfnWriteInput; std::function _pfnWarningBell; std::function _pfnTitleChanged; std::function _pfnCopyToClipboard; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 592ce52d540..69d1b42cda0 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -21,6 +21,16 @@ TextAttribute Terminal::GetTextAttributes() const return _buffer->GetCurrentAttributes(); } +bool Terminal::ReturnResponse(std::wstring_view responseString) +{ + if (!_pfnWriteInput) + { + return false; + } + _pfnWriteInput(responseString); + return true; +} + void Terminal::SetTextAttributes(const TextAttribute& attrs) { _buffer->SetCurrentAttributes(attrs); diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 6adf0daed61..1747185b64a 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -442,6 +442,58 @@ bool TerminalDispatch::ResetMode(const DispatchTypes::ModeParams param) return _ModeParamsHelper(param, false); } +// Routine Description: +// - DSR - Reports status of a console property back to the STDIN based on the type of status requested. +// - This particular routine responds to ANSI status patterns only (CSI # n), not the DEC format (CSI ? # n) +// Arguments: +// - statusType - ANSI status type indicating what property we should report back +// Return Value: +// - True if handled successfully. False otherwise. +bool TerminalDispatch::DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) +{ + bool success = false; + + switch (statusType) + { + case DispatchTypes::AnsiStatusType::OS_OperatingStatus: + success = _OperatingStatus(); + break; + case DispatchTypes::AnsiStatusType::CPR_CursorPositionReport: + success = _CursorPositionReport(); + break; + } + + return success; +} + +// Routine Description: +// - DSR-OS - Reports the operating status back to the input channel +// Arguments: +// - +// Return Value: +// - True if handled successfully. False otherwise. +bool TerminalDispatch::_OperatingStatus() const +{ + // We always report a good operating condition. + return _WriteResponse(L"\x1b[0n"); +} + +// Routine Description: +// - DSR-CPR - Reports the current cursor position within the viewport back to the input channel +// Arguments: +// - +// Return Value: +// - True if handled successfully. False otherwise. +bool TerminalDispatch::_CursorPositionReport() const +{ + // Now send it back into the input channel of the console. + // First format the response string. + const auto pos = _terminalApi.GetCursorPosition(); + // VT has origin at 1,1 where as we use 0,0 internally + const auto response = wil::str_printf(L"\x1b[%d;%dR", pos.Y + 1, pos.X + 1); + return _WriteResponse(response); +} + // Method Description: // - Start a hyperlink // Arguments: @@ -545,6 +597,18 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) return false; } +// Routine Description: +// - Helper to send a string reply to the input stream of the console. +// - Used by various commands where the program attached would like a reply to one of the commands issued. +// Arguments: +// - reply - The reply string to transmit back to the input stream +// Return Value: +// - True if the string was sent to the connected application. False otherwise. +bool TerminalDispatch::_WriteResponse(const std::wstring_view reply) const +{ + return _terminalApi.ReturnResponse(reply); +} + // Routine Description: // - Support routine for routing private mode parameters to be set/reset as flags // Arguments: diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 1ec29bf8e08..cfec1aaadfe 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -75,6 +75,8 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc bool SetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) override; // DECSET bool ResetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) override; // DECRST + bool DeviceStatusReport(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::AnsiStatusType /*statusType*/) override; // DSR, DSR-OS, DSR-CPR + bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override; bool EndHyperlink() override; @@ -90,8 +92,12 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc TextAttribute& attr, const bool isForeground); + bool _WriteResponse(const std::wstring_view reply) const; bool _ModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams param, const bool enable); + bool _OperatingStatus() const; + bool _CursorPositionReport() const; + void _ClearSingleTabStop(); void _ClearAllTabStops(); void _ResetTabStops(); diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp index 86eefe56868..dac23b33a0e 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp @@ -298,6 +298,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation return Feature_AtlasEngine::IsEnabled(); } + bool ProfileViewModel::VtPassthroughAvailable() const noexcept + { + return Feature_VtPassthroughMode::IsEnabled(); + } + bool ProfileViewModel::UseParentProcessDirectory() { return StartingDirectory().empty(); diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h index 925fb567c2b..a4bc0f22bcb 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h @@ -73,6 +73,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void CreateUnfocusedAppearance(); void DeleteUnfocusedAppearance(); bool AtlasEngineAvailable() const noexcept; + bool VtPassthroughAvailable() const noexcept; VIEW_MODEL_OBSERVABLE_PROPERTY(ProfileSubPage, CurrentPage); @@ -103,6 +104,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation OBSERVABLE_PROJECTED_SETTING(_profile, BellStyle); OBSERVABLE_PROJECTED_SETTING(_profile, UseAtlasEngine); OBSERVABLE_PROJECTED_SETTING(_profile, Elevate); + OBSERVABLE_PROJECTED_SETTING(_profile, VtPassthrough) WINRT_PROPERTY(bool, IsBaseLayer, false); WINRT_PROPERTY(IHostedInWindow, WindowRoot, nullptr); diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl index 8571c7c9441..b05b76317a0 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl @@ -63,6 +63,7 @@ namespace Microsoft.Terminal.Settings.Editor Boolean ShowUnfocusedAppearance { get; }; AppearanceViewModel UnfocusedAppearance { get; }; Boolean AtlasEngineAvailable { get; }; + Boolean VtPassthroughAvailable { get; }; void CreateUnfocusedAppearance(); void DeleteUnfocusedAppearance(); @@ -94,5 +95,6 @@ namespace Microsoft.Terminal.Settings.Editor OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.BellStyle, BellStyle); OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, UseAtlasEngine); OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, Elevate); + OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, VtPassthrough); } } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml index 517cc3f9113..40d12cd30f9 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml @@ -127,6 +127,16 @@ + + + + + diff --git a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw index fcafb0bcf4f..09954874cec 100644 --- a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw @@ -1043,6 +1043,10 @@ Enable experimental text rendering engine An option to enable an experimental text rendering engine + + Enable experimental virtual terminal passthrough + An option to enable experimental virtual terminal passthrough connectivity option with the underlying ConPTY + Audible An option to choose from for the "bell style" setting. When selected, an audible cue is used to notify the user. diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h index 5cba5156767..279237f9fba 100644 --- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h +++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h @@ -76,7 +76,8 @@ Author(s): X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible) \ X(bool, UseAtlasEngine, "experimental.useAtlasEngine", false) \ X(Windows::Foundation::Collections::IVector, BellSound, "bellSound", nullptr) \ - X(bool, Elevate, "elevate", false) + X(bool, Elevate, "elevate", false) \ + X(bool, VtPassthrough, "experimental.connection.passthroughMode", false) // Intentionally omitted Profile settings: // * Name diff --git a/src/cascadia/TerminalSettingsModel/Profile.idl b/src/cascadia/TerminalSettingsModel/Profile.idl index d54c6431a53..f8f3dc8d1cd 100644 --- a/src/cascadia/TerminalSettingsModel/Profile.idl +++ b/src/cascadia/TerminalSettingsModel/Profile.idl @@ -64,6 +64,7 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.ScrollbarState, ScrollState); INHERITABLE_PROFILE_SETTING(String, Padding); INHERITABLE_PROFILE_SETTING(String, Commandline); + INHERITABLE_PROFILE_SETTING(Boolean, VtPassthrough); INHERITABLE_PROFILE_SETTING(String, StartingDirectory); String EvaluatedStartingDirectory { get; }; diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index 491affc5e7f..0b56266b708 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -241,6 +241,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation _Padding = profile.Padding(); _Commandline = profile.Commandline(); + _VtPassthrough = profile.VtPassthrough(); _StartingDirectory = profile.EvaluatedStartingDirectory(); diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h index 909ad8ab37a..40301422a8a 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h @@ -91,6 +91,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::TerminalSettings, bool, FocusFollowMouse, false); INHERITABLE_SETTING(Model::TerminalSettings, bool, TrimBlockSelection, true); INHERITABLE_SETTING(Model::TerminalSettings, bool, DetectURLs, true); + INHERITABLE_SETTING(Model::TerminalSettings, bool, VtPassthrough, false); INHERITABLE_SETTING(Model::TerminalSettings, Windows::Foundation::IReference, TabColor, nullptr); diff --git a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp index 3ee7c74784a..8c6d3245162 100644 --- a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp @@ -31,7 +31,7 @@ namespace TerminalCoreUnitTests TEST_METHOD(AltShiftKey); TEST_METHOD(InvalidKeyEvent); - void _VerifyExpectedInput(std::wstring& actualInput) + void _VerifyExpectedInput(std::wstring_view actualInput) { VERIFY_ARE_EQUAL(expectedinput.size(), actualInput.size()); VERIFY_ARE_EQUAL(expectedinput, actualInput); diff --git a/src/cascadia/inc/ControlProperties.h b/src/cascadia/inc/ControlProperties.h index 171cbb7eb4b..08f114eb389 100644 --- a/src/cascadia/inc/ControlProperties.h +++ b/src/cascadia/inc/ControlProperties.h @@ -45,7 +45,8 @@ X(bool, SuppressApplicationTitle) \ X(bool, ForceVTInput, false) \ X(winrt::hstring, StartingTitle) \ - X(bool, DetectURLs, true) + X(bool, DetectURLs, true) \ + X(bool, VtPassthrough, false) // --------------------------- Control Settings --------------------------- // All of these settings are defined in IControlSettings. diff --git a/src/features.xml b/src/features.xml index d9bc3a87e90..c2fde9d2765 100644 --- a/src/features.xml +++ b/src/features.xml @@ -84,4 +84,15 @@ Dev + + + Feature_VtPassthroughMode + Enables passthrough option per profile in Terminal and ConPTY ability to use passthrough API dispatch engine + AlwaysDisabled + + + Dev + Preview + + diff --git a/src/host/CommandListPopup.cpp b/src/host/CommandListPopup.cpp index 4aabc3f63ae..7cdc44eb0a2 100644 --- a/src/host/CommandListPopup.cpp +++ b/src/host/CommandListPopup.cpp @@ -342,7 +342,7 @@ void CommandListPopup::_drawList() WriteCoord.Y += 1i16; } - auto& api = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().api; + auto api = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().api; WriteCoord.Y = _region.Top + 1i16; SHORT i = std::max(gsl::narrow(_bottomIndex - Height() + 1), 0i16); @@ -379,10 +379,10 @@ void CommandListPopup::_drawList() WriteCoord.X = _region.Left + 1i16; - LOG_IF_FAILED(api.WriteConsoleOutputCharacterAImpl(_screenInfo, - { CommandNumberPtr, CommandNumberLength }, - WriteCoord, - CommandNumberLength)); + LOG_IF_FAILED(api->WriteConsoleOutputCharacterAImpl(_screenInfo, + { CommandNumberPtr, CommandNumberLength }, + WriteCoord, + CommandNumberLength)); // write command to screen auto command = _history.GetNth(i); @@ -417,10 +417,10 @@ void CommandListPopup::_drawList() WriteCoord.X = gsl::narrow(WriteCoord.X + CommandNumberLength); size_t used; - LOG_IF_FAILED(api.WriteConsoleOutputCharacterWImpl(_screenInfo, - { command.data(), lStringLength }, - WriteCoord, - used)); + LOG_IF_FAILED(api->WriteConsoleOutputCharacterWImpl(_screenInfo, + { command.data(), lStringLength }, + WriteCoord, + used)); // write attributes to screen if (i == _currentCommand) diff --git a/src/host/ConsoleArguments.cpp b/src/host/ConsoleArguments.cpp index 333f9e1d859..b3f03db0d3f 100644 --- a/src/host/ConsoleArguments.cpp +++ b/src/host/ConsoleArguments.cpp @@ -24,6 +24,7 @@ const std::wstring_view ConsoleArguments::WIN32_INPUT_MODE = L"--win32input"; const std::wstring_view ConsoleArguments::FEATURE_ARG = L"--feature"; const std::wstring_view ConsoleArguments::FEATURE_PTY_ARG = L"pty"; const std::wstring_view ConsoleArguments::COM_SERVER_ARG = L"-Embedding"; +const std::wstring_view ConsoleArguments::PASSTHROUGH_ARG = L"--passthrough"; std::wstring EscapeArgument(std::wstring_view ac) { @@ -461,6 +462,12 @@ void ConsoleArguments::s_ConsumeArg(_Inout_ std::vector& args, _In s_ConsumeArg(args, i); hr = S_OK; } + else if (arg == PASSTHROUGH_ARG) + { + _passthroughMode = true; + s_ConsumeArg(args, i); + hr = S_OK; + } else if (arg.substr(0, FILEPATH_LEADER_PREFIX.length()) == FILEPATH_LEADER_PREFIX) { // beginning of command line -- includes file path @@ -596,6 +603,11 @@ bool ConsoleArguments::ShouldRunAsComServer() const return _runAsComServer; } +bool ConsoleArguments::IsPassthroughMode() const noexcept +{ + return _passthroughMode; +} + HANDLE ConsoleArguments::GetServerHandle() const { return ULongToHandle(_serverHandle); diff --git a/src/host/ConsoleArguments.hpp b/src/host/ConsoleArguments.hpp index d82dc0bf24d..bb4a95b21e6 100644 --- a/src/host/ConsoleArguments.hpp +++ b/src/host/ConsoleArguments.hpp @@ -36,6 +36,7 @@ class ConsoleArguments bool IsHeadless() const; bool ShouldCreateServerHandle() const; bool ShouldRunAsComServer() const; + bool IsPassthroughMode() const noexcept; HANDLE GetServerHandle() const; HANDLE GetVtInHandle() const; @@ -77,6 +78,7 @@ class ConsoleArguments static const std::wstring_view FEATURE_ARG; static const std::wstring_view FEATURE_PTY_ARG; static const std::wstring_view COM_SERVER_ARG; + static const std::wstring_view PASSTHROUGH_ARG; private: #ifdef UNIT_TESTING @@ -95,7 +97,8 @@ class ConsoleArguments const DWORD serverHandle, const DWORD signalHandle, const bool inheritCursor, - const bool runAsComServer) : + const bool runAsComServer, + const bool passthroughMode) : _commandline(commandline), _clientCommandline(clientCommandline), _vtInHandle(vtInHandle), @@ -111,7 +114,8 @@ class ConsoleArguments _signalHandle(signalHandle), _inheritCursor(inheritCursor), _resizeQuirk(false), - _runAsComServer{ runAsComServer } + _runAsComServer{ runAsComServer }, + _passthroughMode{ passthroughMode } { } #endif @@ -133,6 +137,7 @@ class ConsoleArguments short _width; short _height; + bool _passthroughMode{ false }; bool _runAsComServer; bool _createServerHandle; DWORD _serverHandle; @@ -189,6 +194,7 @@ namespace WEX L"Signal Handle: '0x%x'\r\n", L"Inherit Cursor: '%ws'\r\n", L"Run As Com Server: '%ws'\r\n", + L"Passthrough Mode: '%ws'\r\n", ci.GetClientCommandline().c_str(), s_ToBoolString(ci.HasVtHandles()), ci.GetVtInHandle(), @@ -203,7 +209,8 @@ namespace WEX s_ToBoolString(ci.HasSignalHandle()), ci.GetSignalHandle(), s_ToBoolString(ci.GetInheritCursor()), - s_ToBoolString(ci.ShouldRunAsComServer())); + s_ToBoolString(ci.ShouldRunAsComServer()), + s_ToBoolString(ci.IsPassthroughMode())); } private: @@ -232,7 +239,9 @@ namespace WEX expected.GetServerHandle() == actual.GetServerHandle() && expected.HasSignalHandle() == actual.HasSignalHandle() && expected.GetSignalHandle() == actual.GetSignalHandle() && - expected.GetInheritCursor() == actual.GetInheritCursor(); + expected.GetInheritCursor() == actual.GetInheritCursor() && + expected.ShouldRunAsComServer() == actual.ShouldRunAsComServer() && + expected.IsPassthroughMode() == actual.IsPassthroughMode(); } static bool AreSame(const ConsoleArguments& expected, const ConsoleArguments& actual) @@ -257,7 +266,9 @@ namespace WEX !object.ShouldCreateServerHandle() && object.GetServerHandle() == 0 && (object.GetSignalHandle() == 0 || object.GetSignalHandle() == INVALID_HANDLE_VALUE) && - !object.GetInheritCursor(); + !object.GetInheritCursor() && + !object.ShouldRunAsComServer() && + !object.IsPassthroughMode(); } }; } diff --git a/src/host/VtApiRoutines.cpp b/src/host/VtApiRoutines.cpp new file mode 100644 index 00000000000..f2b007a2ffb --- /dev/null +++ b/src/host/VtApiRoutines.cpp @@ -0,0 +1,863 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "precomp.h" +#include "VtApiRoutines.h" +#include "../interactivity/inc/ServiceLocator.hpp" +#include "../types/inc/convert.hpp" + +using namespace Microsoft::Console::Interactivity; + +// When someone attempts to use the console APIs to do a "read back" +// of the console buffer, we have to give them **something**. +// These two structures are just some gaudy-colored replacement character +// text to give them data but represent they've done something that cannot +// be supported under VT passthrough mode. +// ---- +// They can't be supported because in passthrough we maintain no internal +// buffer to answer these questions, and there is no VT sequence that lets +// us query the final terminal's buffer state. Even if a VT sequence did exist +// (and we personally believe it shouldn't), there's a possibility that it would +// read a massive amount of data and cause severe perf issues as applications coded +// to this old API are likely leaning on it heavily and asking for this data in a +// loop via VT would be a nightmare of parsing and formatting and over-the-wire transmission. + +static constexpr CHAR_INFO s_readBackUnicode{ + { UNICODE_REPLACEMENT }, + FOREGROUND_INTENSITY | FOREGROUND_RED | BACKGROUND_GREEN +}; + +static constexpr CHAR_INFO s_readBackAscii{ + { L'?' }, + FOREGROUND_INTENSITY | FOREGROUND_RED | BACKGROUND_GREEN +}; + +VtApiRoutines::VtApiRoutines() : + m_inputCodepage(ServiceLocator::LocateGlobals().getConsoleInformation().CP), + m_outputCodepage(ServiceLocator::LocateGlobals().getConsoleInformation().OutputCP), + m_inputMode(), + m_outputMode(), + m_pUsualRoutines(), + m_pVtEngine(), + m_listeningForDSR(false) +{ +} + +#pragma warning(push) +#pragma warning(disable : 4100) // unreferenced param + +void VtApiRoutines::GetConsoleInputCodePageImpl(ULONG& codepage) noexcept +{ + codepage = m_inputCodepage; + return; +} + +void VtApiRoutines::GetConsoleOutputCodePageImpl(ULONG& codepage) noexcept +{ + codepage = m_outputCodepage; + return; +} + +void VtApiRoutines::GetConsoleInputModeImpl(InputBuffer& context, + ULONG& mode) noexcept +{ + mode = m_inputMode; + return; +} + +void VtApiRoutines::GetConsoleOutputModeImpl(SCREEN_INFORMATION& context, + ULONG& mode) noexcept +{ + mode = m_outputMode; + return; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleInputModeImpl(InputBuffer& context, + const ULONG mode) noexcept +{ + m_inputMode = mode; + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleOutputModeImpl(SCREEN_INFORMATION& context, + const ULONG Mode) noexcept +{ + m_outputMode = Mode; + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetNumberOfConsoleInputEventsImpl(const InputBuffer& context, + ULONG& events) noexcept +{ + return m_pUsualRoutines->GetNumberOfConsoleInputEventsImpl(context, events); +} + +void VtApiRoutines::_SynchronizeCursor(std::unique_ptr& waiter) noexcept +{ + // If we're about to tell the caller to wait, let's synchronize the cursor we have with what + // the terminal is presenting in case there's a cooked read going on. + // TODO GH#10001: we only need to do this in cooked read mode. + if (waiter) + { + m_listeningForDSR = true; + (void)m_pVtEngine->_ListenForDSR(); + (void)m_pVtEngine->RequestCursor(); + } +} + +[[nodiscard]] HRESULT VtApiRoutines::PeekConsoleInputAImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept +{ + const auto hr = m_pUsualRoutines->PeekConsoleInputAImpl(context, outEvents, eventsToRead, readHandleState, waiter); + _SynchronizeCursor(waiter); + return hr; +} + +[[nodiscard]] HRESULT VtApiRoutines::PeekConsoleInputWImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept +{ + const auto hr = m_pUsualRoutines->PeekConsoleInputWImpl(context, outEvents, eventsToRead, readHandleState, waiter); + _SynchronizeCursor(waiter); + return hr; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleInputAImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept +{ + const auto hr = m_pUsualRoutines->ReadConsoleInputAImpl(context, outEvents, eventsToRead, readHandleState, waiter); + _SynchronizeCursor(waiter); + return hr; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleInputWImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept +{ + const auto hr = m_pUsualRoutines->ReadConsoleInputWImpl(context, outEvents, eventsToRead, readHandleState, waiter); + _SynchronizeCursor(waiter); + return hr; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleAImpl(IConsoleInputObject& context, + gsl::span buffer, + size_t& written, + std::unique_ptr& waiter, + const std::string_view initialData, + const std::wstring_view exeName, + INPUT_READ_HANDLE_DATA& readHandleState, + const HANDLE clientHandle, + const DWORD controlWakeupMask, + DWORD& controlKeyState) noexcept +{ + const auto hr = m_pUsualRoutines->ReadConsoleAImpl(context, buffer, written, waiter, initialData, exeName, readHandleState, clientHandle, controlWakeupMask, controlKeyState); + // If we're about to tell the caller to wait, let's synchronize the cursor we have with what + // the terminal is presenting in case there's a cooked read going on. + // TODO GH10001: we only need to do this in cooked read mode. + if (clientHandle) + { + m_listeningForDSR = true; + (void)m_pVtEngine->_ListenForDSR(); + (void)m_pVtEngine->RequestCursor(); + } + return hr; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleWImpl(IConsoleInputObject& context, + gsl::span buffer, + size_t& written, + std::unique_ptr& waiter, + const std::string_view initialData, + const std::wstring_view exeName, + INPUT_READ_HANDLE_DATA& readHandleState, + const HANDLE clientHandle, + const DWORD controlWakeupMask, + DWORD& controlKeyState) noexcept +{ + const auto hr = m_pUsualRoutines->ReadConsoleWImpl(context, buffer, written, waiter, initialData, exeName, readHandleState, clientHandle, controlWakeupMask, controlKeyState); + // If we're about to tell the caller to wait, let's synchronize the cursor we have with what + // the terminal is presenting in case there's a cooked read going on. + // TODO GH10001: we only need to do this in cooked read mode. + if (clientHandle) + { + m_listeningForDSR = true; + (void)m_pVtEngine->_ListenForDSR(); + (void)m_pVtEngine->RequestCursor(); + } + return hr; +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleAImpl(IConsoleOutputObject& context, + const std::string_view buffer, + size_t& read, + bool requiresVtQuirk, + std::unique_ptr& waiter) noexcept +{ + if (CP_UTF8 == m_outputCodepage) + { + (void)m_pVtEngine->WriteTerminalUtf8(buffer); + } + else + { + (void)m_pVtEngine->WriteTerminalW(ConvertToW(m_outputCodepage, buffer)); + } + + (void)m_pVtEngine->_Flush(); + read = buffer.size(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleWImpl(IConsoleOutputObject& context, + const std::wstring_view buffer, + size_t& read, + bool requiresVtQuirk, + std::unique_ptr& waiter) noexcept +{ + (void)m_pVtEngine->WriteTerminalW(buffer); + (void)m_pVtEngine->_Flush(); + read = buffer.size(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleLangIdImpl(LANGID& langId) noexcept +{ + return m_pUsualRoutines->GetConsoleLangIdImpl(langId); +} + +[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext, + const WORD attribute, + const size_t lengthToWrite, + const COORD startingCoordinate, + size_t& cellsModified) noexcept +{ + (void)m_pVtEngine->_CursorPosition(startingCoordinate); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(attribute), true); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(attribute >> 4), false); + (void)m_pVtEngine->_WriteFill(lengthToWrite, s_readBackAscii.Char.AsciiChar); + (void)m_pVtEngine->_Flush(); + cellsModified = lengthToWrite; + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext, + const char character, + const size_t lengthToWrite, + const COORD startingCoordinate, + size_t& cellsModified) noexcept +{ + // I mean... if you get your jollies by using UTF8 for single byte codepoints... + // we may as well skip a lot of conversion work and just write it out. + if (m_outputCodepage == CP_UTF8 && character <= 0x7F) + { + (void)m_pVtEngine->_CursorPosition(startingCoordinate); + (void)m_pVtEngine->_WriteFill(lengthToWrite, character); + (void)m_pVtEngine->_Flush(); + cellsModified = lengthToWrite; + return S_OK; + } + else + { + const auto wstr = ConvertToW(m_outputCodepage, std::string_view{ &character, 1 }); + return FillConsoleOutputCharacterWImpl(OutContext, wstr.front(), lengthToWrite, startingCoordinate, cellsModified); + } +} + +[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext, + const wchar_t character, + const size_t lengthToWrite, + const COORD startingCoordinate, + size_t& cellsModified, + const bool enablePowershellShim) noexcept +{ + (void)m_pVtEngine->_CursorPosition(startingCoordinate); + const std::wstring_view sv{ &character, 1 }; + + // TODO GH10001: horrible. it'll WC2MB over and over...we should do that once then emit... and then rep... + // TODO GH10001: there's probably an optimization for if ((character & 0x7F) == character) --> call the UTF8 one. + for (size_t i = 0; i < lengthToWrite; ++i) + { + (void)m_pVtEngine->WriteTerminalW(sv); + } + + (void)m_pVtEngine->_Flush(); + cellsModified = lengthToWrite; + return S_OK; +} + +//// Process based. Restrict in protocol side? +//HRESULT GenerateConsoleCtrlEventImpl(const ULONG ProcessGroupFilter, +// const ULONG ControlEvent); + +void VtApiRoutines::SetConsoleActiveScreenBufferImpl(SCREEN_INFORMATION& newContext) noexcept +{ + return; +} + +void VtApiRoutines::FlushConsoleInputBuffer(InputBuffer& context) noexcept +{ + m_pUsualRoutines->FlushConsoleInputBuffer(context); +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleInputCodePageImpl(const ULONG codepage) noexcept +{ + m_inputCodepage = codepage; + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleOutputCodePageImpl(const ULONG codepage) noexcept +{ + m_outputCodepage = codepage; + return S_OK; +} + +void VtApiRoutines::GetConsoleCursorInfoImpl(const SCREEN_INFORMATION& context, + ULONG& size, + bool& isVisible) noexcept +{ + // TODO GH10001: good luck capturing this out of the input buffer when it comes back in. + //m_pVtEngine->RequestCursor(); + return; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleCursorInfoImpl(SCREEN_INFORMATION& context, + const ULONG size, + const bool isVisible) noexcept +{ + isVisible ? (void)m_pVtEngine->_ShowCursor() : (void)m_pVtEngine->_HideCursor(); + (void)m_pVtEngine->_Flush(); + return S_OK; +} + +//// driver will pare down for non-Ex method +void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& context, + CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept +{ + // TODO GH10001: this is technically full of potentially incorrect data. do we care? should we store it in here with set? + return m_pUsualRoutines->GetConsoleScreenBufferInfoExImpl(context, data); +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleScreenBufferInfoExImpl(SCREEN_INFORMATION& context, + const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept +{ + (void)m_pVtEngine->_ResizeWindow(data.srWindow.Right - data.srWindow.Left, data.srWindow.Bottom - data.srWindow.Top); + (void)m_pVtEngine->_CursorPosition(data.dwCursorPosition); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(data.wAttributes), true); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(data.wAttributes >> 4), false); + //color table? + // popup attributes... hold internally? + // TODO GH10001: popups are gonna erase the stuff behind them... deal with that somehow. + (void)m_pVtEngine->_Flush(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context, + const COORD size) noexcept +{ + // Don't transmit. The terminal figures out its own buffer size. + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context, + const COORD position) noexcept +{ + if (m_listeningForDSR) + { + context.GetActiveBuffer().GetTextBuffer().GetCursor().SetPosition(position); + m_pVtEngine->SetTerminalCursorTextPosition(position); + } + else + { + (void)m_pVtEngine->_CursorPosition(position); + (void)m_pVtEngine->_Flush(); + } + return S_OK; +} + +void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context, + COORD& size) noexcept +{ + m_pUsualRoutines->GetLargestConsoleWindowSizeImpl(context, size); // This is likely super weird but not weirder than existing ConPTY answers. + return; +} + +[[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context, + const SMALL_RECT& source, + const COORD target, + std::optional clip, + const char fillCharacter, + const WORD fillAttribute) noexcept +{ + // TODO GH10001: Use DECCRA + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context, + const SMALL_RECT& source, + const COORD target, + std::optional clip, + const wchar_t fillCharacter, + const WORD fillAttribute, + const bool enableCmdShim) noexcept +{ + // TODO GH10001: Use DECCRA + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleTextAttributeImpl(SCREEN_INFORMATION& context, + const WORD attribute) noexcept +{ + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(attribute), true); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(attribute >> 4), false); + (void)m_pVtEngine->_Flush(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context, + const bool isAbsolute, + const SMALL_RECT& windowRect) noexcept +{ + (void)m_pVtEngine->_ResizeWindow(windowRect.Right - windowRect.Left, windowRect.Bottom - windowRect.Top); + (void)m_pVtEngine->_Flush(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context, + const COORD origin, + gsl::span buffer, + size_t& written) noexcept +{ + std::fill_n(buffer.data(), buffer.size(), s_readBackUnicode.Attributes); // should be same as the ascii one. + written = buffer.size(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context, + const COORD origin, + gsl::span buffer, + size_t& written) noexcept +{ + std::fill_n(buffer.data(), buffer.size(), s_readBackAscii.Char.AsciiChar); + written = buffer.size(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context, + const COORD origin, + gsl::span buffer, + size_t& written) noexcept +{ + std::fill_n(buffer.data(), buffer.size(), s_readBackUnicode.Char.UnicodeChar); + written = buffer.size(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleInputAImpl(InputBuffer& context, + const gsl::span buffer, + size_t& written, + const bool append) noexcept +{ + return m_pUsualRoutines->WriteConsoleInputAImpl(context, buffer, written, append); +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleInputWImpl(InputBuffer& context, + const gsl::span buffer, + size_t& written, + const bool append) noexcept +{ + return m_pUsualRoutines->WriteConsoleInputWImpl(context, buffer, written, append); +} + +extern HRESULT _ConvertCellsToWInplace(const UINT codepage, + gsl::span buffer, + const Viewport& rectangle) noexcept; + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputAImpl(SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& requestRectangle, + Microsoft::Console::Types::Viewport& writtenRectangle) noexcept +{ + // No UTF8 optimization because the entire `CHAR_INFO` grid system doesn't make sense for UTF-8 + // with up to 4 bytes per cell...or more! + + RETURN_IF_FAILED(_ConvertCellsToWInplace(m_outputCodepage, buffer, requestRectangle)); + return WriteConsoleOutputWImpl(context, buffer, requestRectangle, writtenRectangle); +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputWImpl(SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& requestRectangle, + Microsoft::Console::Types::Viewport& writtenRectangle) noexcept +{ + COORD cursor{ requestRectangle.Left(), requestRectangle.Top() }; + + const size_t width = requestRectangle.Width(); + size_t pos = 0; + + while (pos < buffer.size()) + { + (void)m_pVtEngine->_CursorPosition(cursor); + + const auto subspan = buffer.subspan(pos, width); + + for (const auto& ci : subspan) + { + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(ci.Attributes), true); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(ci.Attributes >> 4), false); + (void)m_pVtEngine->WriteTerminalW(std::wstring_view{ &ci.Char.UnicodeChar, 1 }); + } + + ++cursor.Y; + pos += width; + } + + (void)m_pVtEngine->_Flush(); + + //TODO GH10001: trim to buffer size? + writtenRectangle = requestRectangle; + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext, + const gsl::span attrs, + const COORD target, + size_t& used) noexcept +{ + (void)m_pVtEngine->_CursorPosition(target); + + for (const auto& attr : attrs) + { + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(attr), true); + (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast(attr >> 4), false); + (void)m_pVtEngine->WriteTerminalUtf8(std::string_view{ &s_readBackAscii.Char.AsciiChar, 1 }); + } + + (void)m_pVtEngine->_Flush(); + + used = attrs.size(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext, + const std::string_view text, + const COORD target, + size_t& used) noexcept +{ + if (m_outputCodepage == CP_UTF8) + { + (void)m_pVtEngine->_CursorPosition(target); + (void)m_pVtEngine->WriteTerminalUtf8(text); + (void)m_pVtEngine->_Flush(); + return S_OK; + } + else + { + return WriteConsoleOutputCharacterWImpl(OutContext, ConvertToW(m_outputCodepage, text), target, used); + } +} + +[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext, + const std::wstring_view text, + const COORD target, + size_t& used) noexcept +{ + (void)m_pVtEngine->_CursorPosition(target); + (void)m_pVtEngine->WriteTerminalW(text); + (void)m_pVtEngine->_Flush(); + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& sourceRectangle, + Microsoft::Console::Types::Viewport& readRectangle) noexcept +{ + std::fill_n(buffer.data(), buffer.size(), s_readBackAscii); + // TODO GH10001: do we need to constrict readRectangle to within the known buffer size... probably. + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputWImpl(const SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& sourceRectangle, + Microsoft::Console::Types::Viewport& readRectangle) noexcept +{ + std::fill_n(buffer.data(), buffer.size(), s_readBackUnicode); + // TODO GH10001: do we need to constrict readRectangle to within the known buffer size... probably. + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleTitleAImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept +{ + written = 0; + needed = 0; + + if (!title.empty()) + { + title.front() = ANSI_NULL; + } + + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleTitleWImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept +{ + written = 0; + needed = 0; + + if (!title.empty()) + { + title.front() = UNICODE_NULL; + } + + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleOriginalTitleAImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept +{ + written = 0; + needed = 0; + + if (!title.empty()) + { + title.front() = ANSI_NULL; + } + + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleOriginalTitleWImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept +{ + written = 0; + needed = 0; + + if (!title.empty()) + { + title.front() = UNICODE_NULL; + } + + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleTitleAImpl(const std::string_view title) noexcept +{ + return SetConsoleTitleWImpl(ConvertToW(m_inputCodepage, title)); +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleTitleWImpl(const std::wstring_view title) noexcept +{ + (void)m_pVtEngine->UpdateTitle(title); + (void)m_pVtEngine->_Flush(); + return S_OK; +} + +void VtApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept +{ + buttons = 2; + return; +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context, + const DWORD index, + COORD& size) noexcept +{ + size.X = 8; + size.Y = 12; + return S_OK; +} + +//// driver will pare down for non-Ex method +[[nodiscard]] HRESULT VtApiRoutines::GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context, + const bool isForMaximumWindowSize, + CONSOLE_FONT_INFOEX& consoleFontInfoEx) noexcept +{ + return S_OK; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context, + const ULONG flags, + COORD& newSize) noexcept +{ + return S_OK; +} + +void VtApiRoutines::GetConsoleDisplayModeImpl(ULONG& flags) noexcept +{ + flags = 0; + return; +} + +[[nodiscard]] HRESULT VtApiRoutines::AddConsoleAliasAImpl(const std::string_view source, + const std::string_view target, + const std::string_view exeName) noexcept +{ + return m_pUsualRoutines->AddConsoleAliasAImpl(source, target, exeName); +} + +[[nodiscard]] HRESULT VtApiRoutines::AddConsoleAliasWImpl(const std::wstring_view source, + const std::wstring_view target, + const std::wstring_view exeName) noexcept +{ + return m_pUsualRoutines->AddConsoleAliasWImpl(source, target, exeName); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasAImpl(const std::string_view source, + gsl::span target, + size_t& written, + const std::string_view exeName) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasAImpl(source, target, written, exeName); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasWImpl(const std::wstring_view source, + gsl::span target, + size_t& written, + const std::wstring_view exeName) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasWImpl(source, target, written, exeName); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasesLengthAImpl(const std::string_view exeName, + size_t& bufferRequired) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasesLengthAImpl(exeName, bufferRequired); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasesLengthWImpl(const std::wstring_view exeName, + size_t& bufferRequired) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasesLengthWImpl(exeName, bufferRequired); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasExesLengthAImpl(size_t& bufferRequired) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasExesLengthAImpl(bufferRequired); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasExesLengthWImpl(size_t& bufferRequired) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasExesLengthWImpl(bufferRequired); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasesAImpl(const std::string_view exeName, + gsl::span alias, + size_t& written) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasesAImpl(exeName, alias, written); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasesWImpl(const std::wstring_view exeName, + gsl::span alias, + size_t& written) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasesWImpl(exeName, alias, written); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasExesAImpl(gsl::span aliasExes, + size_t& written) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasExesAImpl(aliasExes, written); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleAliasExesWImpl(gsl::span aliasExes, + size_t& written) noexcept +{ + return m_pUsualRoutines->GetConsoleAliasExesWImpl(aliasExes, written); +} + +[[nodiscard]] HRESULT VtApiRoutines::ExpungeConsoleCommandHistoryAImpl(const std::string_view exeName) noexcept +{ + return m_pUsualRoutines->ExpungeConsoleCommandHistoryAImpl(exeName); +} + +[[nodiscard]] HRESULT VtApiRoutines::ExpungeConsoleCommandHistoryWImpl(const std::wstring_view exeName) noexcept +{ + return m_pUsualRoutines->ExpungeConsoleCommandHistoryWImpl(exeName); +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleNumberOfCommandsAImpl(const std::string_view exeName, + const size_t numberOfCommands) noexcept +{ + return m_pUsualRoutines->SetConsoleNumberOfCommandsAImpl(exeName, numberOfCommands); +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleNumberOfCommandsWImpl(const std::wstring_view exeName, + const size_t numberOfCommands) noexcept +{ + return m_pUsualRoutines->SetConsoleNumberOfCommandsWImpl(exeName, numberOfCommands); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleCommandHistoryLengthAImpl(const std::string_view exeName, + size_t& length) noexcept +{ + return m_pUsualRoutines->GetConsoleCommandHistoryLengthAImpl(exeName, length); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleCommandHistoryLengthWImpl(const std::wstring_view exeName, + size_t& length) noexcept +{ + return m_pUsualRoutines->GetConsoleCommandHistoryLengthWImpl(exeName, length); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleCommandHistoryAImpl(const std::string_view exeName, + gsl::span commandHistory, + size_t& written) noexcept +{ + return m_pUsualRoutines->GetConsoleCommandHistoryAImpl(exeName, commandHistory, written); +} + +[[nodiscard]] HRESULT VtApiRoutines::GetConsoleCommandHistoryWImpl(const std::wstring_view exeName, + gsl::span commandHistory, + size_t& written) noexcept +{ + return m_pUsualRoutines->GetConsoleCommandHistoryWImpl(exeName, commandHistory, written); +} + +void VtApiRoutines::GetConsoleWindowImpl(HWND& hwnd) noexcept +{ + hwnd = ServiceLocator::LocatePseudoWindow(); + return; +} + +void VtApiRoutines::GetConsoleSelectionInfoImpl(CONSOLE_SELECTION_INFO& consoleSelectionInfo) noexcept +{ + consoleSelectionInfo = { 0 }; + return; +} + +void VtApiRoutines::GetConsoleHistoryInfoImpl(CONSOLE_HISTORY_INFO& consoleHistoryInfo) noexcept +{ + m_pUsualRoutines->GetConsoleHistoryInfoImpl(consoleHistoryInfo); + return; +} + +[[nodiscard]] HRESULT VtApiRoutines::SetConsoleHistoryInfoImpl(const CONSOLE_HISTORY_INFO& consoleHistoryInfo) noexcept +{ + return m_pUsualRoutines->SetConsoleHistoryInfoImpl(consoleHistoryInfo); +} + +[[nodiscard]] HRESULT VtApiRoutines::SetCurrentConsoleFontExImpl(IConsoleOutputObject& context, + const bool isForMaximumWindowSize, + const CONSOLE_FONT_INFOEX& consoleFontInfoEx) noexcept +{ + return S_OK; +} + +#pragma warning(pop) diff --git a/src/host/VtApiRoutines.h b/src/host/VtApiRoutines.h new file mode 100644 index 00000000000..ef6dd351e80 --- /dev/null +++ b/src/host/VtApiRoutines.h @@ -0,0 +1,392 @@ +/*++ +Copyright (c) Microsoft Corporation +Licensed under the MIT license. + +Module Name: +- VtApiRoutines.h + +Abstract: +- This file defines the interface to respond to all API calls by using VT on behalf of the client + +Author: +- Michael Niksa (miniksa) 26-Jul-2021 + +Revision History: +- Adapted from original items in srvinit.cpp, getset.cpp, directio.cpp, stream.cpp +--*/ + +#pragma once + +#include "../server/IApiRoutines.h" +#include "../renderer/vt/Xterm256Engine.hpp" + +class VtApiRoutines : public IApiRoutines +{ +public: + VtApiRoutines(); + +#pragma region ObjectManagement + /*HRESULT CreateInitialObjects(_Out_ InputBuffer** const ppInputObject, + _Out_ SCREEN_INFORMATION** const ppOutputObject); + */ + +#pragma endregion + +#pragma region L1 + void GetConsoleInputCodePageImpl(ULONG& codepage) noexcept override; + + void GetConsoleOutputCodePageImpl(ULONG& codepage) noexcept override; + + void GetConsoleInputModeImpl(InputBuffer& context, + ULONG& mode) noexcept override; + + void GetConsoleOutputModeImpl(SCREEN_INFORMATION& context, + ULONG& mode) noexcept override; + + [[nodiscard]] HRESULT SetConsoleInputModeImpl(InputBuffer& context, + const ULONG mode) noexcept override; + + [[nodiscard]] HRESULT SetConsoleOutputModeImpl(SCREEN_INFORMATION& context, + const ULONG Mode) noexcept override; + + [[nodiscard]] HRESULT GetNumberOfConsoleInputEventsImpl(const InputBuffer& context, + ULONG& events) noexcept override; + + [[nodiscard]] HRESULT PeekConsoleInputAImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept override; + + [[nodiscard]] HRESULT PeekConsoleInputWImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleInputAImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleInputWImpl(IConsoleInputObject& context, + std::deque>& outEvents, + const size_t eventsToRead, + INPUT_READ_HANDLE_DATA& readHandleState, + std::unique_ptr& waiter) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleAImpl(IConsoleInputObject& context, + gsl::span buffer, + size_t& written, + std::unique_ptr& waiter, + const std::string_view initialData, + const std::wstring_view exeName, + INPUT_READ_HANDLE_DATA& readHandleState, + const HANDLE clientHandle, + const DWORD controlWakeupMask, + DWORD& controlKeyState) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleWImpl(IConsoleInputObject& context, + gsl::span buffer, + size_t& written, + std::unique_ptr& waiter, + const std::string_view initialData, + const std::wstring_view exeName, + INPUT_READ_HANDLE_DATA& readHandleState, + const HANDLE clientHandle, + const DWORD controlWakeupMask, + DWORD& controlKeyState) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleAImpl(IConsoleOutputObject& context, + const std::string_view buffer, + size_t& read, + bool requiresVtQuirk, + std::unique_ptr& waiter) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleWImpl(IConsoleOutputObject& context, + const std::wstring_view buffer, + size_t& read, + bool requiresVtQuirk, + std::unique_ptr& waiter) noexcept override; + +#pragma region ThreadCreationInfo + [[nodiscard]] HRESULT GetConsoleLangIdImpl(LANGID& langId) noexcept override; +#pragma endregion + +#pragma endregion + +#pragma region L2 + + [[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext, + const WORD attribute, + const size_t lengthToWrite, + const COORD startingCoordinate, + size_t& cellsModified) noexcept override; + + [[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext, + const char character, + const size_t lengthToWrite, + const COORD startingCoordinate, + size_t& cellsModified) noexcept override; + + [[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext, + const wchar_t character, + const size_t lengthToWrite, + const COORD startingCoordinate, + size_t& cellsModified, + const bool enablePowershellShim = false) noexcept override; + + //// Process based. Restrict in protocol side? + //HRESULT GenerateConsoleCtrlEventImpl(const ULONG ProcessGroupFilter, + // const ULONG ControlEvent); + + void SetConsoleActiveScreenBufferImpl(SCREEN_INFORMATION& newContext) noexcept override; + + void FlushConsoleInputBuffer(InputBuffer& context) noexcept override; + + [[nodiscard]] HRESULT SetConsoleInputCodePageImpl(const ULONG codepage) noexcept override; + + [[nodiscard]] HRESULT SetConsoleOutputCodePageImpl(const ULONG codepage) noexcept override; + + void GetConsoleCursorInfoImpl(const SCREEN_INFORMATION& context, + ULONG& size, + bool& isVisible) noexcept override; + + [[nodiscard]] HRESULT SetConsoleCursorInfoImpl(SCREEN_INFORMATION& context, + const ULONG size, + const bool isVisible) noexcept override; + + //// driver will pare down for non-Ex method + void GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& context, + CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override; + + [[nodiscard]] HRESULT SetConsoleScreenBufferInfoExImpl(SCREEN_INFORMATION& context, + const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override; + + [[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context, + const COORD size) noexcept override; + + [[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context, + const COORD position) noexcept override; + + void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context, + COORD& size) noexcept override; + + [[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context, + const SMALL_RECT& source, + const COORD target, + std::optional clip, + const char fillCharacter, + const WORD fillAttribute) noexcept override; + + [[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context, + const SMALL_RECT& source, + const COORD target, + std::optional clip, + const wchar_t fillCharacter, + const WORD fillAttribute, + const bool enableCmdShim = false) noexcept override; + + [[nodiscard]] HRESULT SetConsoleTextAttributeImpl(SCREEN_INFORMATION& context, + const WORD attribute) noexcept override; + + [[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context, + const bool isAbsolute, + const SMALL_RECT& windowRect) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context, + const COORD origin, + gsl::span buffer, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context, + const COORD origin, + gsl::span buffer, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context, + const COORD origin, + gsl::span buffer, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleInputAImpl(InputBuffer& context, + const gsl::span buffer, + size_t& written, + const bool append) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleInputWImpl(InputBuffer& context, + const gsl::span buffer, + size_t& written, + const bool append) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleOutputAImpl(SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& requestRectangle, + Microsoft::Console::Types::Viewport& writtenRectangle) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleOutputWImpl(SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& requestRectangle, + Microsoft::Console::Types::Viewport& writtenRectangle) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext, + const gsl::span attrs, + const COORD target, + size_t& used) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext, + const std::string_view text, + const COORD target, + size_t& used) noexcept override; + + [[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext, + const std::wstring_view text, + const COORD target, + size_t& used) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& sourceRectangle, + Microsoft::Console::Types::Viewport& readRectangle) noexcept override; + + [[nodiscard]] HRESULT ReadConsoleOutputWImpl(const SCREEN_INFORMATION& context, + gsl::span buffer, + const Microsoft::Console::Types::Viewport& sourceRectangle, + Microsoft::Console::Types::Viewport& readRectangle) noexcept override; + + [[nodiscard]] HRESULT GetConsoleTitleAImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept override; + + [[nodiscard]] HRESULT GetConsoleTitleWImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept override; + + [[nodiscard]] HRESULT GetConsoleOriginalTitleAImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept override; + + [[nodiscard]] HRESULT GetConsoleOriginalTitleWImpl(gsl::span title, + size_t& written, + size_t& needed) noexcept override; + + [[nodiscard]] HRESULT SetConsoleTitleAImpl(const std::string_view title) noexcept override; + + [[nodiscard]] HRESULT SetConsoleTitleWImpl(const std::wstring_view title) noexcept override; + +#pragma endregion + +#pragma region L3 + void GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept override; + + [[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context, + const DWORD index, + COORD& size) noexcept override; + + //// driver will pare down for non-Ex method + [[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context, + const bool isForMaximumWindowSize, + CONSOLE_FONT_INFOEX& consoleFontInfoEx) noexcept override; + + [[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context, + const ULONG flags, + COORD& newSize) noexcept override; + + void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override; + + [[nodiscard]] HRESULT AddConsoleAliasAImpl(const std::string_view source, + const std::string_view target, + const std::string_view exeName) noexcept override; + + [[nodiscard]] HRESULT AddConsoleAliasWImpl(const std::wstring_view source, + const std::wstring_view target, + const std::wstring_view exeName) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasAImpl(const std::string_view source, + gsl::span target, + size_t& written, + const std::string_view exeName) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasWImpl(const std::wstring_view source, + gsl::span target, + size_t& written, + const std::wstring_view exeName) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasesLengthAImpl(const std::string_view exeName, + size_t& bufferRequired) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasesLengthWImpl(const std::wstring_view exeName, + size_t& bufferRequired) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasExesLengthAImpl(size_t& bufferRequired) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasExesLengthWImpl(size_t& bufferRequired) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasesAImpl(const std::string_view exeName, + gsl::span alias, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasesWImpl(const std::wstring_view exeName, + gsl::span alias, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasExesAImpl(gsl::span aliasExes, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT GetConsoleAliasExesWImpl(gsl::span aliasExes, + size_t& written) noexcept override; + +#pragma region CMDext Private API + + [[nodiscard]] HRESULT ExpungeConsoleCommandHistoryAImpl(const std::string_view exeName) noexcept override; + + [[nodiscard]] HRESULT ExpungeConsoleCommandHistoryWImpl(const std::wstring_view exeName) noexcept override; + + [[nodiscard]] HRESULT SetConsoleNumberOfCommandsAImpl(const std::string_view exeName, + const size_t numberOfCommands) noexcept override; + + [[nodiscard]] HRESULT SetConsoleNumberOfCommandsWImpl(const std::wstring_view exeName, + const size_t numberOfCommands) noexcept override; + + [[nodiscard]] HRESULT GetConsoleCommandHistoryLengthAImpl(const std::string_view exeName, + size_t& length) noexcept override; + + [[nodiscard]] HRESULT GetConsoleCommandHistoryLengthWImpl(const std::wstring_view exeName, + size_t& length) noexcept override; + + [[nodiscard]] HRESULT GetConsoleCommandHistoryAImpl(const std::string_view exeName, + gsl::span commandHistory, + size_t& written) noexcept override; + + [[nodiscard]] HRESULT GetConsoleCommandHistoryWImpl(const std::wstring_view exeName, + gsl::span commandHistory, + size_t& written) noexcept override; + +#pragma endregion + + void GetConsoleWindowImpl(HWND& hwnd) noexcept override; + + void GetConsoleSelectionInfoImpl(CONSOLE_SELECTION_INFO& consoleSelectionInfo) noexcept override; + + void GetConsoleHistoryInfoImpl(CONSOLE_HISTORY_INFO& consoleHistoryInfo) noexcept override; + + [[nodiscard]] HRESULT SetConsoleHistoryInfoImpl(const CONSOLE_HISTORY_INFO& consoleHistoryInfo) noexcept override; + + [[nodiscard]] HRESULT SetCurrentConsoleFontExImpl(IConsoleOutputObject& context, + const bool isForMaximumWindowSize, + const CONSOLE_FONT_INFOEX& consoleFontInfoEx) noexcept override; + +#pragma endregion + + IApiRoutines* m_pUsualRoutines; + UINT& m_inputCodepage; + UINT& m_outputCodepage; + ULONG m_inputMode; + ULONG m_outputMode; + bool m_listeningForDSR; + Microsoft::Console::Render::Xterm256Engine* m_pVtEngine; + +private: + void _SynchronizeCursor(std::unique_ptr& waiter) noexcept; +}; diff --git a/src/host/VtInputThread.cpp b/src/host/VtInputThread.cpp index c5a4501a869..e5a7be636ae 100644 --- a/src/host/VtInputThread.cpp +++ b/src/host/VtInputThread.cpp @@ -31,7 +31,8 @@ VtInputThread::VtInputThread(_In_ wil::unique_hfile hPipe, _u8State{}, _dwThreadId{ 0 }, _exitRequested{ false }, - _exitResult{ S_OK } + _exitResult{ S_OK }, + _pfnSetLookingForDSR{} { THROW_HR_IF(E_HANDLE, _hFile.get() == INVALID_HANDLE_VALUE); @@ -50,6 +51,9 @@ VtInputThread::VtInputThread(_In_ wil::unique_hfile hPipe, // we need this callback to be able to flush an unknown input sequence to the app auto flushCallback = std::bind(&StateMachine::FlushToTerminal, _pInputStateMachine.get()); engineRef->SetFlushToInputQueueCallback(flushCallback); + + // we need this callback to capture the reply if someone requests a status from the terminal + _pfnSetLookingForDSR = std::bind(&InputStateMachineEngine::SetLookingForDSR, engineRef, std::placeholders::_1); } // Method Description: @@ -138,6 +142,14 @@ void VtInputThread::DoReadInput(const bool throwOnFail) } } +void VtInputThread::SetLookingForDSR(const bool looking) noexcept +{ + if (_pfnSetLookingForDSR) + { + _pfnSetLookingForDSR(looking); + } +} + // Method Description: // - The ThreadProc for the VT Input Thread. Reads input from the pipe, and // passes it to _HandleRunInput to be processed by the diff --git a/src/host/VtInputThread.hpp b/src/host/VtInputThread.hpp index da3f08a7a0b..9d54d6bbf8d 100644 --- a/src/host/VtInputThread.hpp +++ b/src/host/VtInputThread.hpp @@ -26,6 +26,7 @@ namespace Microsoft::Console [[nodiscard]] HRESULT Start(); static DWORD WINAPI StaticVtInputThreadProc(_In_ LPVOID lpParameter); void DoReadInput(const bool throwOnFail); + void SetLookingForDSR(const bool looking) noexcept; private: [[nodiscard]] HRESULT _HandleRunInput(const std::string_view u8Str); @@ -38,6 +39,8 @@ namespace Microsoft::Console bool _exitRequested; HRESULT _exitResult; + std::function _pfnSetLookingForDSR; + std::unique_ptr _pInputStateMachine; til::u8state _u8State; }; diff --git a/src/host/VtIo.cpp b/src/host/VtIo.cpp index 5b482ecd185..6863ef080a6 100644 --- a/src/host/VtIo.cpp +++ b/src/host/VtIo.cpp @@ -14,6 +14,8 @@ #include "input.h" // ProcessCtrlEvents #include "output.h" // CloseConsoleProcessState +#include "VtApiRoutines.h" + using namespace Microsoft::Console; using namespace Microsoft::Console::Render; using namespace Microsoft::Console::VirtualTerminal; @@ -71,6 +73,7 @@ VtIo::VtIo() : _lookingForCursorPosition = pArgs->GetInheritCursor(); _resizeQuirk = pArgs->IsResizeQuirkEnabled(); _win32InputMode = pArgs->IsWin32InputModeEnabled(); + _passthroughMode = pArgs->IsPassthroughMode(); // If we were already given VT handles, set up the VT IO engine to use those. if (pArgs->InConptyMode()) @@ -137,8 +140,9 @@ VtIo::VtIo() : { return S_FALSE; } + auto& globals = ServiceLocator::LocateGlobals(); - const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + const CONSOLE_INFORMATION& gci = globals.getConsoleInformation(); try { @@ -155,22 +159,60 @@ VtIo::VtIo() : switch (_IoMode) { case VtIoMode::XTERM_256: - _pVtRenderEngine = std::make_unique(std::move(_hOutput), - initialViewport); + { + auto xterm256Engine = std::make_unique(std::move(_hOutput), + initialViewport); + if constexpr (Feature_VtPassthroughMode::IsEnabled()) + { + if (_passthroughMode) + { + auto vtapi = new VtApiRoutines(); + vtapi->m_pVtEngine = xterm256Engine.get(); + vtapi->m_pUsualRoutines = globals.api; + + xterm256Engine->SetPassthroughMode(true); + + if (_pVtInputThread) + { + auto pfnSetListenForDSR = std::bind(&VtInputThread::SetLookingForDSR, _pVtInputThread.get(), std::placeholders::_1); + xterm256Engine->SetLookingForDSRCallback(pfnSetListenForDSR); + } + + globals.api = vtapi; + } + } + + _pVtRenderEngine = std::move(xterm256Engine); break; + } case VtIoMode::XTERM: + { _pVtRenderEngine = std::make_unique(std::move(_hOutput), initialViewport, false); + if (_passthroughMode) + { + return E_NOTIMPL; + } break; + } case VtIoMode::XTERM_ASCII: + { _pVtRenderEngine = std::make_unique(std::move(_hOutput), initialViewport, true); + + if (_passthroughMode) + { + return E_NOTIMPL; + } break; + } default: + { return E_FAIL; } + } if (_pVtRenderEngine) { _pVtRenderEngine->SetTerminalOwner(this); diff --git a/src/host/VtIo.hpp b/src/host/VtIo.hpp index d3d3410ec1b..6c204d6cf44 100644 --- a/src/host/VtIo.hpp +++ b/src/host/VtIo.hpp @@ -66,6 +66,7 @@ namespace Microsoft::Console::VirtualTerminal bool _resizeQuirk{ false }; bool _win32InputMode{ false }; + bool _passthroughMode{ false }; std::unique_ptr _pVtRenderEngine; std::unique_ptr _pVtInputThread; diff --git a/src/host/directio.cpp b/src/host/directio.cpp index dd060156621..cc6d26fd153 100644 --- a/src/host/directio.cpp +++ b/src/host/directio.cpp @@ -604,9 +604,9 @@ void EventsToUnicode(_Inout_ std::deque>& inEvents, // - rectangle - This is the rectangle describing the region that the buffer covers. // Return Value: // - Generally S_OK. Could be a memory or math error code. -[[nodiscard]] static HRESULT _ConvertCellsToWInplace(const UINT codepage, - gsl::span buffer, - const Viewport& rectangle) noexcept +[[nodiscard]] HRESULT _ConvertCellsToWInplace(const UINT codepage, + gsl::span buffer, + const Viewport& rectangle) noexcept { try { diff --git a/src/host/globals.cpp b/src/host/globals.cpp index 6cbff4b52d1..d9450f0ce92 100644 --- a/src/host/globals.cpp +++ b/src/host/globals.cpp @@ -7,6 +7,11 @@ #pragma hdrstop +Globals::Globals() +{ + api = &defaultApiRoutines; +} + CONSOLE_INFORMATION& Globals::getConsoleInformation() { return ciConsoleInformation; diff --git a/src/host/globals.h b/src/host/globals.h index 3b116ea8ef5..50e42c82d5c 100644 --- a/src/host/globals.h +++ b/src/host/globals.h @@ -34,6 +34,8 @@ TRACELOGGING_DECLARE_PROVIDER(g_hConhostV2EventTraceProvider); class Globals { public: + Globals(); + UINT uiOEMCP = GetOEMCP(); UINT uiWindowsCP = GetACP(); HINSTANCE hInstance; @@ -65,7 +67,7 @@ class Globals bool IsHeadless() const; - ApiRoutines api; + IApiRoutines* api; bool handoffTarget = false; @@ -80,4 +82,5 @@ class Globals private: CONSOLE_INFORMATION ciConsoleInformation; + ApiRoutines defaultApiRoutines; }; diff --git a/src/host/host-common.vcxitems b/src/host/host-common.vcxitems index 46acdde1aea..fdd645c5940 100644 --- a/src/host/host-common.vcxitems +++ b/src/host/host-common.vcxitems @@ -52,6 +52,7 @@ + @@ -110,6 +111,7 @@ + diff --git a/src/host/lib/hostlib.vcxproj.filters b/src/host/lib/hostlib.vcxproj.filters index b8b3df1e25b..fb42149b626 100644 --- a/src/host/lib/hostlib.vcxproj.filters +++ b/src/host/lib/hostlib.vcxproj.filters @@ -177,6 +177,9 @@ Source Files + + Source Files + @@ -347,8 +350,11 @@ Header Files + + Header Files + - \ No newline at end of file + diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index cbae4519159..1b3ba0a2608 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -65,7 +65,7 @@ void ConhostInternalGetSet::PrintString(const std::wstring_view string) // - void ConhostInternalGetSet::GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) const { - ServiceLocator::LocateGlobals().api.GetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), screenBufferInfo); + ServiceLocator::LocateGlobals().api->GetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), screenBufferInfo); } // Routine Description: @@ -76,7 +76,7 @@ void ConhostInternalGetSet::GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_I // - void ConhostInternalGetSet::SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) { - THROW_IF_FAILED(ServiceLocator::LocateGlobals().api.SetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), screenBufferInfo)); + THROW_IF_FAILED(ServiceLocator::LocateGlobals().api->SetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), screenBufferInfo)); } // Routine Description: @@ -89,7 +89,7 @@ void ConhostInternalGetSet::SetCursorPosition(const COORD position) { auto& info = _io.GetActiveOutputBuffer(); const auto clampedPosition = info.GetTextBuffer().ClampPositionWithinLine(position); - THROW_IF_FAILED(ServiceLocator::LocateGlobals().api.SetConsoleCursorPositionImpl(info, clampedPosition)); + THROW_IF_FAILED(ServiceLocator::LocateGlobals().api->SetConsoleCursorPositionImpl(info, clampedPosition)); } // Method Description: @@ -177,7 +177,7 @@ void ConhostInternalGetSet::WriteInput(std::deque>& // - void ConhostInternalGetSet::SetWindowInfo(const bool absolute, const SMALL_RECT& window) { - THROW_IF_FAILED(ServiceLocator::LocateGlobals().api.SetConsoleWindowInfoImpl(_io.GetActiveOutputBuffer(), absolute, window)); + THROW_IF_FAILED(ServiceLocator::LocateGlobals().api->SetConsoleWindowInfoImpl(_io.GetActiveOutputBuffer(), absolute, window)); } // Routine Description: diff --git a/src/host/popup.cpp b/src/host/popup.cpp index 34683011145..4d4020ee7db 100644 --- a/src/host/popup.cpp +++ b/src/host/popup.cpp @@ -169,10 +169,10 @@ void Popup::_DrawPrompt(const UINT id) } size_t used; - LOG_IF_FAILED(ServiceLocator::LocateGlobals().api.WriteConsoleOutputCharacterWImpl(_screenInfo, - text, - WriteCoord, - used)); + LOG_IF_FAILED(ServiceLocator::LocateGlobals().api->WriteConsoleOutputCharacterWImpl(_screenInfo, + text, + WriteCoord, + used)); } // Routine Description: diff --git a/src/host/sources.inc b/src/host/sources.inc index aa7eae927dd..c77653b8bf2 100644 --- a/src/host/sources.inc +++ b/src/host/sources.inc @@ -93,6 +93,7 @@ SOURCES = \ ..\CommandListPopup.cpp \ ..\CopyFromCharPopup.cpp \ ..\CopyToCharPopup.cpp \ + ..\VtApiRoutines.cpp \ # ------------------------------------- diff --git a/src/host/srvinit.cpp b/src/host/srvinit.cpp index 055c9ec5546..6332b1bc7e8 100644 --- a/src/host/srvinit.cpp +++ b/src/host/srvinit.cpp @@ -944,7 +944,7 @@ DWORD WINAPI ConsoleIoThread(LPVOID lpParameter) auto& globals = ServiceLocator::LocateGlobals(); CONSOLE_API_MSG ReceiveMsg; - ReceiveMsg._pApiRoutines = &globals.api; + ReceiveMsg._pApiRoutines = globals.api; ReceiveMsg._pDeviceComm = globals.pDeviceComm; PCONSOLE_API_MSG ReplyMsg = nullptr; @@ -956,7 +956,7 @@ DWORD WINAPI ConsoleIoThread(LPVOID lpParameter) std::unique_ptr capturedMessage{ static_cast(lpParameter) }; ReceiveMsg = *capturedMessage.get(); - ReceiveMsg._pApiRoutines = &globals.api; + ReceiveMsg._pApiRoutines = globals.api; ReceiveMsg._pDeviceComm = globals.pDeviceComm; IoSorter::ServiceIoOperation(&ReceiveMsg, &ReplyMsg); } @@ -984,7 +984,7 @@ DWORD WINAPI ConsoleIoThread(LPVOID lpParameter) ReplyMsg = nullptr; continue; } - + ReceiveMsg._pApiRoutines = globals.api; IoSorter::ServiceIoOperation(&ReceiveMsg, &ReplyMsg); } diff --git a/src/host/ut_host/ConsoleArgumentsTests.cpp b/src/host/ut_host/ConsoleArgumentsTests.cpp index 69ab4debe81..e264e264123 100644 --- a/src/host/ut_host/ConsoleArgumentsTests.cpp +++ b/src/host/ut_host/ConsoleArgumentsTests.cpp @@ -83,7 +83,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe \"this is the commandline\""; @@ -105,7 +106,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless \"--vtmode bar this is the commandline\""; @@ -127,7 +129,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless --server 0x4 this is the commandline"; @@ -149,7 +152,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0x4, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless\t--vtmode\txterm\tthis\tis\tthe\tcommandline"; @@ -171,7 +175,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless\\ foo\\ --outpipe\\ bar\\ this\\ is\\ the\\ commandline"; @@ -193,7 +198,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless\\\tfoo\\\t--outpipe\\\tbar\\\tthis\\\tis\\\tthe\\\tcommandline"; @@ -215,7 +221,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --vtmode a\\\\\\\\\"b c\" d e"; @@ -237,7 +244,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe this is the commandline"; @@ -259,7 +267,8 @@ void ConsoleArgumentsTests::ArgSplittingTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? } @@ -286,7 +295,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe foo"; @@ -308,7 +318,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe foo -- bar"; @@ -330,7 +341,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --vtmode foo foo -- bar"; @@ -352,7 +364,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe console --vtmode foo foo -- bar"; @@ -374,7 +387,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe console --vtmode foo --outpipe foo -- bar"; @@ -396,7 +410,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --vtmode foo -- --outpipe foo bar"; @@ -418,7 +433,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --vtmode -- --headless bar"; @@ -440,7 +456,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --"; @@ -462,7 +479,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe"; @@ -484,7 +502,8 @@ void ConsoleArgumentsTests::ClientCommandlineTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? } @@ -511,7 +530,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --server 0x4"; @@ -533,7 +553,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe 0x4 0x8"; @@ -555,7 +576,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --server 0x4 0x8"; @@ -577,7 +599,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe 0x4 --server 0x8"; @@ -599,7 +622,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --server 0x4 --server 0x8"; @@ -621,7 +645,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe 0x4 -ForceV1"; @@ -643,7 +668,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe -ForceV1"; @@ -665,7 +691,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe 0x4 -ForceNoHandoff"; @@ -687,7 +714,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe -ForceNoHandoff"; @@ -709,7 +737,8 @@ void ConsoleArgumentsTests::LegacyFormatsTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? } @@ -760,7 +789,8 @@ void ConsoleArgumentsTests::CombineVtPipeHandleTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --vtmode xterm-256color"; @@ -782,7 +812,8 @@ void ConsoleArgumentsTests::CombineVtPipeHandleTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? } @@ -819,7 +850,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --width 120"; @@ -841,7 +873,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --height 30"; @@ -863,7 +896,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --width 0"; @@ -885,7 +919,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --width -1"; @@ -907,7 +942,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --width foo"; @@ -929,7 +965,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --width 2foo"; @@ -951,7 +988,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --width 65535"; @@ -973,7 +1011,8 @@ void ConsoleArgumentsTests::InitialSizeTests() 0ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? } @@ -1000,7 +1039,8 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless 0x4"; @@ -1022,7 +1062,8 @@ void ConsoleArgumentsTests::HeadlessArgTests() 4ul, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --headless --headless"; @@ -1044,7 +1085,8 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe -- foo.exe --headless"; @@ -1066,7 +1108,8 @@ void ConsoleArgumentsTests::HeadlessArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? } @@ -1097,7 +1140,8 @@ void ConsoleArgumentsTests::SignalHandleTests() 4ul, // serverHandle 8ul, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --server 0x4 --signal ASDF"; @@ -1119,7 +1163,8 @@ void ConsoleArgumentsTests::SignalHandleTests() 4ul, // serverHandle 0ul, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --signal --server 0x4"; @@ -1141,7 +1186,8 @@ void ConsoleArgumentsTests::SignalHandleTests() 0ul, // serverHandle 0ul, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? } @@ -1172,7 +1218,8 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --feature tty"; ArgTestsRunner(L"#2 Error case, pass an unsupported feature", @@ -1193,7 +1240,8 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --feature pty --feature pty"; @@ -1215,7 +1263,8 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode true); // successful parse? commandline = L"conhost.exe --feature pty --feature tty"; @@ -1237,7 +1286,8 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --feature pty --feature"; @@ -1259,7 +1309,8 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? commandline = L"conhost.exe --feature pty --feature --signal foo"; @@ -1281,6 +1332,7 @@ void ConsoleArgumentsTests::FeatureArgTests() 0, // serverHandle 0, // signalHandle false, // inheritCursor - false), // runAsComServer + false, // runAsComServer + false), // passthroughMode false); // successful parse? } diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index a61839d17c5..fc5887b2892 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -1863,7 +1863,7 @@ void ScreenBufferTests::ResizeAltBufferGetScreenBufferInfo() altBuffer.SetViewportSize(&newBufferSize); CONSOLE_SCREEN_BUFFER_INFOEX csbiex{ 0 }; - g.api.GetConsoleScreenBufferInfoExImpl(mainBuffer, csbiex); + g.api->GetConsoleScreenBufferInfoExImpl(mainBuffer, csbiex); const auto newActualMainView = mainBuffer.GetViewport(); const auto newActualAltView = altBuffer.GetViewport(); @@ -4973,7 +4973,7 @@ void ScreenBufferTests::SnapCursorWithTerminalScrolling() Log::Comment(NoThrowString().Format( L"Call SetConsoleCursorPosition to snap to the cursor")); - VERIFY_SUCCEEDED(g.api.SetConsoleCursorPositionImpl(si, secondWindowOrigin)); + VERIFY_SUCCEEDED(g.api->SetConsoleCursorPositionImpl(si, secondWindowOrigin)); const auto fourthView = si._viewport; const auto fourthVirtualBottom = si._virtualBottom; @@ -5049,12 +5049,12 @@ void ScreenBufferTests::ClearAlternateBuffer() #pragma region Test ScrollConsoleScreenBufferWImpl() // Clear text of alt buffer (same params as in CMD) - VERIFY_SUCCEEDED(g.api.ScrollConsoleScreenBufferWImpl(siMain, - { 0, 0, 120, 9001 }, - { 0, -9001 }, - std::nullopt, - L' ', - 7)); + VERIFY_SUCCEEDED(g.api->ScrollConsoleScreenBufferWImpl(siMain, + { 0, 0, 120, 9001 }, + { 0, -9001 }, + std::nullopt, + L' ', + 7)); // Verify text is now gone VERIFY_ARE_EQUAL(L" ", altBuffer.GetTextBuffer().GetCellDataAt({ 0, 0 })->Chars()); @@ -5062,7 +5062,7 @@ void ScreenBufferTests::ClearAlternateBuffer() #pragma region Test SetConsoleCursorPositionImpl() // Reset cursor position as we do with CLS command (same params as in CMD) - VERIFY_SUCCEEDED(g.api.SetConsoleCursorPositionImpl(siMain, { 0 })); + VERIFY_SUCCEEDED(g.api->SetConsoleCursorPositionImpl(siMain, { 0 })); // Verify state of alt buffer auto& altBufferCursor = altBuffer.GetTextBuffer().GetCursor(); diff --git a/src/inc/conpty-static.h b/src/inc/conpty-static.h index 052708a6bd5..b745a8b1631 100644 --- a/src/inc/conpty-static.h +++ b/src/inc/conpty-static.h @@ -17,6 +17,7 @@ extern "C" { #define PSEUDOCONSOLE_RESIZE_QUIRK (2u) #define PSEUDOCONSOLE_WIN32_INPUT_MODE (4u) +#define PSEUDOCONSOLE_PASSTHROUGH_MODE (8u) HRESULT WINAPI ConptyCreatePseudoConsole(COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC); diff --git a/src/interactivity/win32/windowio.cpp b/src/interactivity/win32/windowio.cpp index 0734af874f2..2d5d8436ec3 100644 --- a/src/interactivity/win32/windowio.cpp +++ b/src/interactivity/win32/windowio.cpp @@ -565,11 +565,11 @@ BOOL HandleSysKeyEvent(const HWND hWnd, const UINT Message, const WPARAM wParam, CONSOLE_FONT_INFOEX font = { 0 }; font.cbSize = sizeof(font); - RETURN_IF_FAILED(globals.api.GetCurrentConsoleFontExImpl(screenInfo, false, font)); + RETURN_IF_FAILED(globals.api->GetCurrentConsoleFontExImpl(screenInfo, false, font)); font.dwFontSize.Y += delta; - RETURN_IF_FAILED(globals.api.SetCurrentConsoleFontExImpl(screenInfo, false, font)); + RETURN_IF_FAILED(globals.api->SetCurrentConsoleFontExImpl(screenInfo, false, font)); return S_OK; } diff --git a/src/renderer/vt/Xterm256Engine.cpp b/src/renderer/vt/Xterm256Engine.cpp index 499feb2002d..33a0e92ec59 100644 --- a/src/renderer/vt/Xterm256Engine.cpp +++ b/src/renderer/vt/Xterm256Engine.cpp @@ -30,8 +30,10 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, const RenderSettings& /*renderSettings*/, const gsl::not_null pData, const bool /*usingSoftFont*/, - const bool /*isSettingDefaultBrushes*/) noexcept + const bool isSettingDefaultBrushes) noexcept { + RETURN_HR_IF(S_FALSE, _passthrough && isSettingDefaultBrushes); + RETURN_IF_FAILED(VtEngine::_RgbUpdateDrawingBrushes(textAttributes)); RETURN_IF_FAILED(_UpdateHyperlinkAttr(textAttributes, pData)); diff --git a/src/renderer/vt/Xterm256Engine.hpp b/src/renderer/vt/Xterm256Engine.hpp index 5c8cde61831..9d704c34dd8 100644 --- a/src/renderer/vt/Xterm256Engine.hpp +++ b/src/renderer/vt/Xterm256Engine.hpp @@ -18,6 +18,8 @@ Author(s): #include "XtermEngine.hpp" +class VtApiRoutines; + namespace Microsoft::Console::Render { class Xterm256Engine : public XtermEngine @@ -36,6 +38,8 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT ManuallyClearScrollback() noexcept override; + friend class ::VtApiRoutines; + private: [[nodiscard]] HRESULT _UpdateExtendedAttrs(const TextAttribute& textAttributes) noexcept; [[nodiscard]] HRESULT _UpdateHyperlinkAttr(const TextAttribute& textAttributes, diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp index cb8004cfd0f..f9cbb183477 100644 --- a/src/renderer/vt/XtermEngine.cpp +++ b/src/renderer/vt/XtermEngine.cpp @@ -46,6 +46,16 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, // during the frame. _nextCursorIsVisible = false; + // Do not perform synchronization clearing in passthrough mode. + // In passthrough, the terminal leads and we follow what it is + // handling from the client application. + // (This is in contrast to full PTY mode where WE, the ConPTY, lead and + // it follows our state.) + if (_passthrough) + { + _firstPaint = false; + } + if (_firstPaint) { // MSFT:17815688 diff --git a/src/renderer/vt/state.cpp b/src/renderer/vt/state.cpp index bfea737bb12..2f9d83decda 100644 --- a/src/renderer/vt/state.cpp +++ b/src/renderer/vt/state.cpp @@ -54,7 +54,8 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, _bufferLine{}, _buffer{}, _formatBuffer{}, - _conversionBuffer{} + _conversionBuffer{}, + _pfnSetLookingForDSR{} { #ifndef UNIT_TESTING // When unit testing, we can instantiate a VtEngine without a pipe. @@ -65,6 +66,37 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, #endif } +// Method Description: +// - Writes a fill of characters to our file handle (repeat of same character over and over) +[[nodiscard]] HRESULT VtEngine::_WriteFill(const size_t n, const char c) noexcept +try +{ + _trace.TraceStringFill(n, c); +#ifdef UNIT_TESTING + if (_usingTestCallback) + { + const std::string str(n, c); + // Try to get the last error. If that wasn't set, then the test probably + // doesn't set last error. No matter. We'll just return with E_FAIL + // then. This is a unit test, we don't particularly care. + const auto succeeded = _pfnTestCallback(str.data(), str.size()); + auto hr = E_FAIL; + if (!succeeded) + { + const auto err = ::GetLastError(); + // If there wasn't an error in GLE, just use E_FAIL + hr = SUCCEEDED_WIN32(err) ? hr : HRESULT_FROM_WIN32(err); + } + return succeeded ? S_OK : hr; + } +#endif + + // TODO GH10001: Replace me with REP + _buffer.append(n, c); + return S_OK; +} +CATCH_RETURN(); + // Method Description: // - Writes the characters to our file handle. If we're building the unit tests, // we can instead write to the test callback, in order to avoid needing to @@ -379,6 +411,23 @@ HRESULT VtEngine::RequestCursor() noexcept return S_OK; } +// Method Description: +// - Sends a notification through to the `VtInputThread` that it should +// watch for and capture the response from a DSR message we're about to send. +// This is typically `RequestCursor` at the time of writing this, but in theory +// could be another DSR as well. +// Arguments: +// - +// Return Value: +// - S_OK if all goes well. Invalid state error if no notification function is installed. +// (see `SetLookingForDSRCallback` to install one.) +[[nodiscard]] HRESULT VtEngine::_ListenForDSR() noexcept +{ + RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !_pfnSetLookingForDSR); + _pfnSetLookingForDSR(true); + return S_OK; +} + // Method Description: // - Tell the vt renderer to begin a resize operation. During a resize // operation, the vt renderer should _not_ request to be repainted during a @@ -415,7 +464,7 @@ void VtEngine::EndResizeRequest() // conpty scenario. // - See also: GH#3490, #4354, #4741 // Arguments: -// - +// - resizeQuirk - True to turn on the quirk. False otherwise. // Return Value: // - true iff we were started with the `--resizeQuirk` flag enabled. void VtEngine::SetResizeQuirk(const bool resizeQuirk) @@ -423,6 +472,29 @@ void VtEngine::SetResizeQuirk(const bool resizeQuirk) _resizeQuirk = resizeQuirk; } +// Method Description: +// - Configure the renderer to understand that we're operating in limited-draw +// passthrough mode. We do not need to handle full responsibility for replicating +// buffer state to the attached terminal. +// Arguments: +// - passthrough - True to turn on passthrough mode. False otherwise. +// Return Value: +// - true iff we were started with an output mode for passthrough. false otherwise. +void VtEngine::SetPassthroughMode(const bool passthrough) noexcept +{ + _passthrough = passthrough; +} + +void VtEngine::SetLookingForDSRCallback(std::function pfnLooking) noexcept +{ + _pfnSetLookingForDSR = pfnLooking; +} + +void VtEngine::SetTerminalCursorTextPosition(const COORD cursor) noexcept +{ + _lastText = cursor; +} + // Method Description: // - Manually emit a "Erase Scrollback" sequence to the connected terminal. We // need to do this in certain cases that we've identified where we believe the diff --git a/src/renderer/vt/tracing.cpp b/src/renderer/vt/tracing.cpp index 6e76efed8d5..5e8fb5b5815 100644 --- a/src/renderer/vt/tracing.cpp +++ b/src/renderer/vt/tracing.cpp @@ -64,6 +64,23 @@ std::string toPrintableString(const std::string_view& inString) } return retval; } +void RenderTracing::TraceStringFill(const size_t n, const char c) const +{ +#ifndef UNIT_TESTING + if (TraceLoggingProviderEnabled(g_hConsoleVtRendererTraceProvider, WINEVENT_LEVEL_VERBOSE, TIL_KEYWORD_TRACE)) + { + TraceLoggingWrite(g_hConsoleVtRendererTraceProvider, + "VtEngine_TraceStringFill", + TraceLoggingUInt64(gsl::narrow_cast(n)), + TraceLoggingChar(c), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + } +#else + UNREFERENCED_PARAMETER(n); + UNREFERENCED_PARAMETER(c); +#endif UNIT_TESTING +} void RenderTracing::TraceString(const std::string_view& instr) const { #ifndef UNIT_TESTING diff --git a/src/renderer/vt/tracing.hpp b/src/renderer/vt/tracing.hpp index f3aa7fbb005..973605a19e7 100644 --- a/src/renderer/vt/tracing.hpp +++ b/src/renderer/vt/tracing.hpp @@ -26,6 +26,7 @@ namespace Microsoft::Console::VirtualTerminal public: RenderTracing(); ~RenderTracing(); + void TraceStringFill(const size_t n, const char c) const; void TraceString(const std::string_view& str) const; void TraceInvalidate(const til::rect& view) const; void TraceLastText(const til::point lastText) const; diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 56afda42116..ee2a1cd720d 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -80,6 +80,9 @@ namespace Microsoft::Console::Render void BeginResizeRequest(); void EndResizeRequest(); void SetResizeQuirk(const bool resizeQuirk); + void SetPassthroughMode(const bool passthrough) noexcept; + void SetLookingForDSRCallback(std::function pfnLooking) noexcept; + void SetTerminalCursorTextPosition(const COORD coordCursor) noexcept; [[nodiscard]] virtual HRESULT ManuallyClearScrollback() noexcept; [[nodiscard]] HRESULT RequestWin32Input() noexcept; @@ -92,6 +95,8 @@ namespace Microsoft::Console::Render TextAttribute _lastTextAttributes; + std::function _pfnSetLookingForDSR; + Microsoft::Console::Types::Viewport _lastViewport; std::pmr::unsynchronized_pool_resource _pool; @@ -126,8 +131,10 @@ namespace Microsoft::Console::Render bool _delayedEolWrap{ false }; bool _resizeQuirk{ false }; + bool _passthrough{ false }; std::optional _newBottomLineBG{ std::nullopt }; + [[nodiscard]] HRESULT _WriteFill(const size_t n, const char c) noexcept; [[nodiscard]] HRESULT _Write(std::string_view const str) noexcept; [[nodiscard]] HRESULT _Flush() noexcept; @@ -186,6 +193,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _EndHyperlink() noexcept; [[nodiscard]] HRESULT _RequestCursor() noexcept; + [[nodiscard]] HRESULT _ListenForDSR() noexcept; [[nodiscard]] HRESULT _RequestWin32Input() noexcept; diff --git a/src/server/IApiRoutines.h b/src/server/IApiRoutines.h index 996227f0636..a4e4ba047f1 100644 --- a/src/server/IApiRoutines.h +++ b/src/server/IApiRoutines.h @@ -44,6 +44,8 @@ class IApiRoutines #pragma endregion + virtual ~IApiRoutines(){}; + #pragma region L1 virtual void GetConsoleInputCodePageImpl(ULONG& codepage) noexcept = 0; diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp index 2965ec4b617..40a9d0c4094 100644 --- a/src/terminal/parser/InputStateMachineEngine.cpp +++ b/src/terminal/parser/InputStateMachineEngine.cpp @@ -101,6 +101,11 @@ InputStateMachineEngine::InputStateMachineEngine(std::unique_ptr pDispatch, const bool lookingForDSR); + void SetLookingForDSR(const bool looking) noexcept; + bool ActionExecute(const wchar_t wch) override; bool ActionExecuteFromEscape(const wchar_t wch) override; diff --git a/src/tools/closetest/closetest.cpp b/src/tools/closetest/closetest.cpp index 16d2a184fa8..00da8d53b83 100644 --- a/src/tools/closetest/closetest.cpp +++ b/src/tools/closetest/closetest.cpp @@ -298,6 +298,7 @@ static std::vector getConsoleProcessList() const DWORD count1 = GetConsoleProcessList(&ret[0], (DWORD)ret.size()); assert(count1 >= 1 && "GetConsoleProcessList failed"); ret.resize(count1); +#pragma warning(suppress : 4189) // It's used in the assert const DWORD count2 = GetConsoleProcessList(&ret[0], (DWORD)ret.size()); assert(count1 == count2 && "GetConsoleProcessList failed"); return ret; @@ -373,7 +374,7 @@ static void spawnChildTree(DWORD masterPid, const std::vector& ext PROCESS_INFORMATION pi{}; success = CreateProcessW(exeName().c_str(), &cmdline[0], nullptr, nullptr, FALSE, 0, nullptr, nullptr, &sui, &pi); assert(success && "CreateProcessW failed"); - +#pragma warning(suppress : 4189) // It's used in the assert const DWORD waitRet = WaitForSingleObject(readyEvent, INFINITE); assert(waitRet == WAIT_OBJECT_0 && "WaitForSingleObject failed"); CloseHandle(readyEvent); @@ -483,6 +484,7 @@ static BOOL WINAPI ctrlHandler(DWORD type) static HANDLE duplicateHandle(HANDLE srcProc, HANDLE srcHandle) { HANDLE ret{}; +#pragma warning(suppress : 4189) // It's used in the assert const auto success = DuplicateHandle(srcProc, srcHandle, GetCurrentProcess(), &ret, 0, FALSE, DUPLICATE_SAME_ACCESS); assert(success && "DuplicateHandle failed"); @@ -603,6 +605,7 @@ static int doChild(std::deque argv) // Assign self to a job object. if (jobHandle != nullptr) { +#pragma warning(suppress : 4189) // It's used in the assert const BOOL success = AssignProcessToJobObject(jobHandle, GetCurrentProcess()); assert(success && "AssignProcessToJobObject failed"); diff --git a/src/winconpty/winconpty.cpp b/src/winconpty/winconpty.cpp index 7653ce6bd5c..0292c0f47d2 100644 --- a/src/winconpty/winconpty.cpp +++ b/src/winconpty/winconpty.cpp @@ -94,12 +94,13 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken, RETURN_IF_WIN32_BOOL_FALSE(SetHandleInformation(signalPipeConhostSide.get(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)); // GH4061: Ensure that the path to executable in the format is escaped so C:\Program.exe cannot collide with C:\Program Files - const wchar_t* pwszFormat = L"\"%s\" --headless %s%s%s--width %hu --height %hu --signal 0x%x --server 0x%x"; + const wchar_t* pwszFormat = L"\"%s\" --headless %s%s%s%s--width %hu --height %hu --signal 0x%x --server 0x%x"; // This is plenty of space to hold the formatted string wchar_t cmd[MAX_PATH]{}; const BOOL bInheritCursor = (dwFlags & PSEUDOCONSOLE_INHERIT_CURSOR) == PSEUDOCONSOLE_INHERIT_CURSOR; const BOOL bResizeQuirk = (dwFlags & PSEUDOCONSOLE_RESIZE_QUIRK) == PSEUDOCONSOLE_RESIZE_QUIRK; const BOOL bWin32InputMode = (dwFlags & PSEUDOCONSOLE_WIN32_INPUT_MODE) == PSEUDOCONSOLE_WIN32_INPUT_MODE; + const BOOL bPassthroughMode = (dwFlags & PSEUDOCONSOLE_PASSTHROUGH_MODE) == PSEUDOCONSOLE_PASSTHROUGH_MODE; swprintf_s(cmd, MAX_PATH, pwszFormat, @@ -107,6 +108,7 @@ HRESULT _CreatePseudoConsole(const HANDLE hToken, bInheritCursor ? L"--inheritcursor " : L"", bWin32InputMode ? L"--win32input " : L"", bResizeQuirk ? L"--resizeQuirk " : L"", + bPassthroughMode ? L"--passthrough " : L"", size.X, size.Y, signalPipeConhostSide.get(), diff --git a/src/winconpty/winconpty.h b/src/winconpty/winconpty.h index f2a7ff429ee..5c6a2f501c0 100644 --- a/src/winconpty/winconpty.h +++ b/src/winconpty/winconpty.h @@ -25,6 +25,7 @@ typedef struct _PseudoConsole // #define PSEUDOCONSOLE_INHERIT_CURSOR (0x1) #define PSEUDOCONSOLE_RESIZE_QUIRK (0x2) #define PSEUDOCONSOLE_WIN32_INPUT_MODE (0x4) +#define PSEUDOCONSOLE_PASSTHROUGH_MODE (0x8) // Implementations of the various PseudoConsole functions. HRESULT _CreatePseudoConsole(const HANDLE hToken, From b57fe85997c587e45066ecbed4a3d3fed6b749f0 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 31 Mar 2022 13:17:32 -0500 Subject: [PATCH 28/67] Auto-focus window renamer textbox on open (#12798) Does what it says on the tin. This is maximal BODGE. `TeachingTip` doesn't provide an `Opened` event. (https://github.com/microsoft/microsoft-ui-xaml/issues/1607). But we want to focus the renamer text box when it's opened. We can't do that immediately, the TextBox technically isn't in the visual tree yet. We have to wait for it to get added some time after we call IsOpen. How do we do that reliably? Usually, for this kind of thing, we'd just use a one-off LayoutUpdated event, as a notification that the TextBox was added to the tree. HOWEVER: * The _first_ time this is fired, when the box is _first_ opened, yeeting focus doesn't work on the first LayoutUpdated. It does work on the second LayoutUpdated. Okay, so we'll wait for two LayoutUpdated events, and focus on the second. * On subsequent opens: We only ever get a single LayoutUpdated. Period. But, you can successfully focus it on that LayoutUpdated. So, we'll keep track of how many LayoutUpdated's we've _ever_ gotten. If we've had at least 2, then we can focus the text box. We're also not using a ContentDialog for this, because in Xaml Islands a text box in a ContentDialog won't receive _any_ keypresses. Fun! ## References * microsoft/microsoft-ui-xaml#1607 * microsoft/microsoft-ui-xaml#6910 * microsoft/microsoft-ui-xaml#3257 * microsoft/terminal#9662 ## PR Checklist * [x] Will close out #12021, but that's an a11y bug that needs secondary validation * [x] Closes #11322 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed Tested manually --- .../TerminalApp/AppActionHandlers.cpp | 48 ++++++++++++++++--- src/cascadia/TerminalApp/TerminalPage.cpp | 26 +++++++++- src/cascadia/TerminalApp/TerminalPage.h | 5 ++ src/cascadia/TerminalApp/TerminalPage.xaml | 1 + 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index dd01c2a2e22..a82575656a9 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -844,18 +844,54 @@ namespace winrt::TerminalApp::implementation } _UpdateTeachingTipTheme(WindowRenamer().try_as()); - WindowRenamer().IsOpen(true); - // PAIN: We can't immediately focus the textbox in the TeachingTip. It's - // not technically focusable until it is opened. However, it doesn't - // provide an event to tell us when it is opened. That's tracked in - // microsoft/microsoft-ui-xaml#1607. So for now, the user _needs_ to - // click on the text box manually. + // BODGY: GH#12021 + // + // TeachingTip doesn't provide an Opened event. + // (microsoft/microsoft-ui-xaml#1607). But we want to focus the renamer + // text box when it's opened. We can't do that immediately, the TextBox + // technically isn't in the visual tree yet. We have to wait for it to + // get added some time after we call IsOpen. How do we do that reliably? + // Usually, for this kind of thing, we'd just use a one-off + // LayoutUpdated event, as a notification that the TextBox was added to + // the tree. HOWEVER: + // * The _first_ time this is fired, when the box is _first_ opened, + // tossing focus doesn't work on the first LayoutUpdated. It does + // work on the second LayoutUpdated. Okay, so we'll wait for two + // LayoutUpdated events, and focus on the second. + // * On subsequent opens: We only ever get a single LayoutUpdated. + // Period. But, you can successfully focus it on that LayoutUpdated. + // + // So, we'll keep track of how many LayoutUpdated's we've _ever_ gotten. + // If we've had at least 2, then we can focus the text box. // // We're also not using a ContentDialog for this, because in Xaml // Islands a text box in a ContentDialog won't receive _any_ keypresses. // Fun! // WindowRenamerTextBox().Focus(FocusState::Programmatic); + _renamerLayoutUpdatedRevoker.revoke(); + _renamerLayoutUpdatedRevoker = WindowRenamerTextBox().LayoutUpdated(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) { + if (auto self{ weakThis.get() }) + { + auto& count{ self->_renamerLayoutCount }; + + // Don't just always increment this, we don't want to deal with overflow situations + if (count < 2) + { + count++; + } + + if (count >= 2) + { + self->_renamerLayoutUpdatedRevoker.revoke(); + self->WindowRenamerTextBox().Focus(FocusState::Programmatic); + } + } + }); + // Make sure to mark that enter was not pressed in the renamer quite + // yet. More details in TerminalPage::_WindowRenamerKeyDown. + _renamerPressedEnter = false; + WindowRenamer().IsOpen(true); args.Handled(true); } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index a137bf1637b..851aa47a746 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -3621,6 +3621,26 @@ namespace winrt::TerminalApp::implementation // of thing with co_return winrt::make(false). } + // Method Description: + // - Used to track if the user pressed enter with the renamer open. If we + // immediately focus it after hitting Enter on the command palette, then + // the Enter keydown will dismiss the command palette and open the + // renamer, and then the enter keyup will go to the renamer. So we need to + // make sure both a down and up go to the renamer. + // Arguments: + // - e: the KeyRoutedEventArgs describing the key that was released + // Return Value: + // - + void TerminalPage::_WindowRenamerKeyDown(const IInspectable& /*sender*/, + winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) + { + const auto key = e.OriginalKey(); + if (key == Windows::System::VirtualKey::Enter) + { + _renamerPressedEnter = true; + } + } + // Method Description: // - Manually handle Enter and Escape for committing and dismissing a window // rename. This is highly similar to the TabHeaderControl's KeyUp handler. @@ -3631,16 +3651,18 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_WindowRenamerKeyUp(const IInspectable& sender, winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) { - if (e.OriginalKey() == Windows::System::VirtualKey::Enter) + const auto key = e.OriginalKey(); + if (key == Windows::System::VirtualKey::Enter && _renamerPressedEnter) { // User is done making changes, close the rename box _WindowRenamerActionClick(sender, nullptr); } - else if (e.OriginalKey() == Windows::System::VirtualKey::Escape) + else if (key == Windows::System::VirtualKey::Escape) { // User wants to discard the changes they made WindowRenamerTextBox().Text(WindowName()); WindowRenamer().IsOpen(false); + _renamerPressedEnter = false; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 2e48d9db883..1a72fe40c12 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -215,6 +215,10 @@ namespace winrt::TerminalApp::implementation std::shared_ptr _windowIdToast{ nullptr }; std::shared_ptr _windowRenameFailedToast{ nullptr }; + winrt::Windows::UI::Xaml::Controls::TextBox::LayoutUpdated_revoker _renamerLayoutUpdatedRevoker; + int _renamerLayoutCount{ 0 }; + bool _renamerPressedEnter{ false }; + winrt::Windows::Foundation::IAsyncOperation _ShowDialogHelper(const std::wstring_view& name); void _ShowAboutDialog(); @@ -414,6 +418,7 @@ namespace winrt::TerminalApp::implementation void _WindowRenamerActionClick(const IInspectable& sender, const IInspectable& eventArgs); void _RequestWindowRename(const winrt::hstring& newName); + void _WindowRenamerKeyDown(const IInspectable& sender, winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); void _WindowRenamerKeyUp(const IInspectable& sender, winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); void _UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element); diff --git a/src/cascadia/TerminalApp/TerminalPage.xaml b/src/cascadia/TerminalApp/TerminalPage.xaml index 5ca8ed25858..2f6e8f66960 100644 --- a/src/cascadia/TerminalApp/TerminalPage.xaml +++ b/src/cascadia/TerminalApp/TerminalPage.xaml @@ -193,6 +193,7 @@ IsLightDismissEnabled="True"> From e428272752968c00ad9d4a32d3bad5ea010e991b Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Thu, 31 Mar 2022 13:46:17 -0700 Subject: [PATCH 29/67] Remove maintainers from the list (#12802) --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index fef18a43983..c4d7aa6174e 100644 --- a/README.md +++ b/README.md @@ -272,11 +272,8 @@ If you would like to ask a question that you feel doesn't warrant an issue * Kayla Cinnamon, Program Manager: [@cinnamon\_msft](https://twitter.com/cinnamon_msft) * Dustin Howett, Engineering Lead: [@dhowett](https://twitter.com/DHowett) -* Michael Niksa, Senior Developer: - [@michaelniksa](https://twitter.com/MichaelNiksa) * Mike Griese, Senior Developer: [@zadjii](https://twitter.com/zadjii) * Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft) -* Leon Liang, Developer: [@leonmsft](https://twitter.com/leonmsft) * Pankaj Bhojwani, Developer * Leonard Hecker, Developer: [@LeonardHecker](https://twitter.com/LeonardHecker) From 2c3313e7f014f8b072a99ff06f9a234177be2f5a Mon Sep 17 00:00:00 2001 From: Ian O'Neill Date: Mon, 4 Apr 2022 18:27:09 +0100 Subject: [PATCH 30/67] Prevent Fuzz pipeline failure by refactoring nuget restore pipeline steps (#12796) ## Summary of the Pull Request Prevents the Fuzz pipeline from failing by refactoring the nuget restore pipeline steps. ## References Broken in #12778. ## PR Checklist * [ ] Closes #xxx * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [ ] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx --- build/pipelines/release.yml | 31 +-------------- .../templates/build-console-audit-job.yml | 38 +------------------ .../build-console-compliance-job.yml | 31 +-------------- .../templates/build-console-fuzzing.yml | 25 +----------- .../templates/build-console-steps.yml | 36 +----------------- .../templates/restore-nuget-steps.yml | 36 ++++++++++++++++++ 6 files changed, 41 insertions(+), 156 deletions(-) create mode 100644 build/pipelines/templates/restore-nuget-steps.yml diff --git a/build/pipelines/release.yml b/build/pipelines/release.yml index 301e8709b6f..ad97caf8e69 100644 --- a/build/pipelines/release.yml +++ b/build/pipelines/release.yml @@ -100,36 +100,7 @@ jobs: If ($Arch -Eq "x86") { $Arch = "Win32" } Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}" - - task: NuGetToolInstaller@1 - displayName: Use NuGet 5.10 - inputs: - versionSpec: 5.10 - - task: NuGetAuthenticate@0 - # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. - # This should be `task: NuGetCommand@2` - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for extraneous build actions - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: build/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' - - task: NuGetCommand@2 - displayName: NuGet custom - inputs: - command: custom - selectOrConfig: config - nugetConfigPath: NuGet.Config - arguments: restore OpenConsole.sln -SolutionDirectory $(Build.SourcesDirectory) - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for global nuget - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: dep/nuget/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' + - template: .\templates\restore-nuget-steps.yml # Pull the Windows SDK for the developer tools like the debuggers so we can index sources later - template: .\templates\install-winsdk-steps.yml - task: UniversalPackages@0 diff --git a/build/pipelines/templates/build-console-audit-job.yml b/build/pipelines/templates/build-console-audit-job.yml index 591c2a7b12e..5e3a3ca0c3f 100644 --- a/build/pipelines/templates/build-console-audit-job.yml +++ b/build/pipelines/templates/build-console-audit-job.yml @@ -21,43 +21,7 @@ jobs: clean: true fetchDepth: 1 - - task: NuGetToolInstaller@0 - displayName: Ensure NuGet 4.8.1 - inputs: - versionSpec: 4.8.1 - - # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. - # This should be `task: NuGetCommand@2` - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for extraneous build actions - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: build/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' - - # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. - # This should be `task: NuGetCommand@2` - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: OpenConsole.sln - restoreDirectory: '$(Build.SourcesDirectory)\packages' - - # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. - # This should be `task: NuGetCommand@2` - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for global nuget - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: dep/nuget/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' + - template: restore-nuget-steps.yml - task: VSBuild@1 displayName: 'Build solution **\OpenConsole.sln' diff --git a/build/pipelines/templates/build-console-compliance-job.yml b/build/pipelines/templates/build-console-compliance-job.yml index 3ae3fb197ee..a7837e435cb 100644 --- a/build/pipelines/templates/build-console-compliance-job.yml +++ b/build/pipelines/templates/build-console-compliance-job.yml @@ -30,36 +30,7 @@ jobs: If ($Arch -Eq "x86") { $Arch = "Win32" } Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}" - - task: NuGetToolInstaller@1 - displayName: Use NuGet 5.10 - inputs: - versionSpec: 5.10 - - task: NuGetAuthenticate@0 - # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. - # This should be `task: NuGetCommand@2` - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for extraneous build actions - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: build/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' - - task: NuGetCommand@2 - displayName: NuGet custom - inputs: - command: custom - selectOrConfig: config - nugetConfigPath: NuGet.Config - arguments: restore OpenConsole.sln -SolutionDirectory $(Build.SourcesDirectory) - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for global nuget - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: dep/nuget/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' + - steps: restore-nuget-steps.yml - task: UniversalPackages@0 displayName: Download terminal-internal Universal Package inputs: diff --git a/build/pipelines/templates/build-console-fuzzing.yml b/build/pipelines/templates/build-console-fuzzing.yml index 1c8dee82cc2..8771c06d619 100644 --- a/build/pipelines/templates/build-console-fuzzing.yml +++ b/build/pipelines/templates/build-console-fuzzing.yml @@ -21,30 +21,7 @@ jobs: submodules: true clean: true - - task: NuGetToolInstaller@0 - displayName: 'Use NuGet 5.2.0' - inputs: - versionSpec: 5.2.0 - - # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. - # This should be `task: NuGetCommand@2` - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for solution - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: OpenConsole.sln - restoreDirectory: '$(Build.SourcesDirectory)\packages' - - - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for extraneous build actions - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: build/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' + - template: restore-nuget-steps.yml # The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves. - script: | diff --git a/build/pipelines/templates/build-console-steps.yml b/build/pipelines/templates/build-console-steps.yml index 65e1d146aa3..13eddaa3e78 100644 --- a/build/pipelines/templates/build-console-steps.yml +++ b/build/pipelines/templates/build-console-steps.yml @@ -7,41 +7,7 @@ steps: clean: true fetchDepth: 1 -- task: NuGetToolInstaller@0 - displayName: 'Use NuGet 5.2.0' - inputs: - versionSpec: 5.2.0 - -- task: NuGetAuthenticate@0 - -# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. -# This should be `task: NuGetCommand@2` -- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for extraneous build actions - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: build/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' - -- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for solution - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: OpenConsole.sln - restoreDirectory: '$(Build.SourcesDirectory)\packages' - -- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages for global nuget - inputs: - command: restore - feedsToUse: config - configPath: NuGet.config - restoreSolution: dep/nuget/packages.config - restoreDirectory: '$(Build.SourcesDirectory)\packages' +- template: restore-nuget-steps.yml # The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves. - script: | diff --git a/build/pipelines/templates/restore-nuget-steps.yml b/build/pipelines/templates/restore-nuget-steps.yml new file mode 100644 index 00000000000..08ae24f042a --- /dev/null +++ b/build/pipelines/templates/restore-nuget-steps.yml @@ -0,0 +1,36 @@ +steps: +- task: NuGetToolInstaller@0 + displayName: 'Use NuGet 5.2.0' + inputs: + versionSpec: 5.2.0 + +- task: NuGetAuthenticate@0 + +# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. +# This should be `task: NuGetCommand@2` +- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for extraneous build actions + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: build/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' + +- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for solution + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: OpenConsole.sln + restoreDirectory: '$(Build.SourcesDirectory)\packages' + +- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for global nuget + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: dep/nuget/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' From f694f0ddb78d288e0492b186c8fcc7078e95f739 Mon Sep 17 00:00:00 2001 From: Ian O'Neill Date: Mon, 4 Apr 2022 21:59:16 +0100 Subject: [PATCH 31/67] Add common nuget import to Fuzz project so that it compiles (#12821) Adds the common nuget import to the Fuzz project so that it compiles. ## References Broken in #12778, Issue identified by #12796 ## Validation Steps Performed `Host.FuzzWrapper` project builds. --- src/host/ft_fuzzer/Host.FuzzWrapper.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/host/ft_fuzzer/Host.FuzzWrapper.vcxproj b/src/host/ft_fuzzer/Host.FuzzWrapper.vcxproj index ac5ad0884f5..f18a02561c3 100644 --- a/src/host/ft_fuzzer/Host.FuzzWrapper.vcxproj +++ b/src/host/ft_fuzzer/Host.FuzzWrapper.vcxproj @@ -9,6 +9,7 @@ Application + @@ -87,4 +88,5 @@ + From bc6bf15a626b4235c35f2c57142f1fac4cd760d2 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 4 Apr 2022 16:46:54 -0500 Subject: [PATCH 32/67] Force the bundle major version to be over 3000 (#12819) Before #12691, the msixbundle version was of the format YYYY.MM.DD.0. After #12691, it became the same as the build of Terminal it contained. This caused some trouble for _some_ systems: major version 1 is much, much smaller than 2022. Adding 3000 to the major version component, _only for the bundle_, gets around this. Ugh. Fixes #12816. --- build/pipelines/release.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/build/pipelines/release.yml b/build/pipelines/release.yml index ad97caf8e69..189ef696869 100644 --- a/build/pipelines/release.yml +++ b/build/pipelines/release.yml @@ -292,11 +292,16 @@ jobs: displayName: Download Artifacts ${{ platform }} $(TerminalTargetWindowsVersion) inputs: artifactName: appx-${{ platform }}-Release-$(TerminalTargetWindowsVersion) - - task: PowerShell@2 + # Add 3000 to the major version component, but only for the bundle. + # This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before + # we switched to uniform naming. + - pwsh: |- + $VersionEpoch = 3000 + $Components = "$(XES_APPXMANIFESTVERSION)" -Split "\." + $Components[0] = ([int]$Components[0] + $VersionEpoch) + $BundleVersion = $Components -Join "." + .\build\scripts\Create-AppxBundle.ps1 -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath "$(System.ArtifactsDirectory)\Microsoft.WindowsTerminal_$(TerminalTargetWindowsVersion)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle" displayName: Create WindowsTerminal*.msixbundle - inputs: - filePath: build\scripts\Create-AppxBundle.ps1 - arguments: -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion $(XES_APPXMANIFESTVERSION) -OutputPath "$(System.ArtifactsDirectory)\Microsoft.WindowsTerminal_$(TerminalTargetWindowsVersion)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle" - task: EsrpCodeSigning@1 displayName: Submit *.msixbundle to ESRP for code signing inputs: From 8405c7a6972a869736f2bed2357435402a77e31f Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 4 Apr 2022 16:49:50 -0500 Subject: [PATCH 33/67] Autocomplete keyframe animations when occluded on Windows 11 (#12820) On certain builds of Windows, when Terminal is set as the default it will accumulate an unbounded amount of queued animations while the screen is off and it is servicing window management for console applications. This results in Terminal hanging when left overnight, as it has millions of animations to process. The new call into TerminalThemeHelpers will tell our compositor to automatically complete animations that are scheduled while the screen is off. Fixes MSFT-38506980 --- dep/nuget/packages.config | 2 +- src/cascadia/WindowsTerminal/AppHost.cpp | 11 +++++++++++ src/common.nugetversions.targets | 4 ++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/dep/nuget/packages.config b/dep/nuget/packages.config index 5d0f1f2e637..7b532a860bf 100644 --- a/dep/nuget/packages.config +++ b/dep/nuget/packages.config @@ -8,7 +8,7 @@ - + diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index a12f1f1ca6a..929ee07838e 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -11,6 +11,8 @@ #include "VirtualDesktopUtils.h" #include "icon.h" +#include + using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Composition; using namespace winrt::Windows::UI::Xaml; @@ -399,6 +401,15 @@ void AppHost::Initialize() _revokers.OpenSystemMenu = _logic.OpenSystemMenu(winrt::auto_revoke, { this, &AppHost::_OpenSystemMenu }); _revokers.QuitRequested = _logic.QuitRequested(winrt::auto_revoke, { this, &AppHost::_RequestQuitAll }); + // BODGY + // On certain builds of Windows, when Terminal is set as the default + // it will accumulate an unbounded amount of queued animations while + // the screen is off and it is servicing window management for console + // applications. This call into TerminalThemeHelpers will tell our + // compositor to automatically complete animations that are scheduled + // while the screen is off. + TerminalTrySetAutoCompleteAnimationsWhenOccluded(static_cast<::IUnknown*>(winrt::get_abi(_logic.GetRoot())), true); + _window->UpdateTitle(_logic.Title()); // Set up the content of the application. If the app has a custom titlebar, diff --git a/src/common.nugetversions.targets b/src/common.nugetversions.targets index 70621262600..9c902f4b7b9 100644 --- a/src/common.nugetversions.targets +++ b/src/common.nugetversions.targets @@ -53,7 +53,7 @@ - + @@ -90,7 +90,7 @@ - + From 446f2807573ffda411f548a519835d15cacdcd9b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 4 Apr 2022 17:35:02 -0500 Subject: [PATCH 34/67] Try to silently fall back to a local monarch (#12825) This is a crazy idea Dustin and I had. > we can't repro this at will. But we kinda have an idea of where the deref is. We don't know if the small patch (throw, and try again) will fix it. We're sure that the "just fall back to an isolated monarch" will work. I'd almost rather take a build testing the small patch first, to see if that works > This might seem crazy > in 1.12, isolated monarch. In 1.13, "small patch". In 1.14, we can wait and see I can write more details in the morning. It's 5pm here so if we want this today, here it is. @dhowett double check my velocity flag logic here. Should be always true for Release, and off for Dev, Preview. * [x] closes #12774 --- src/cascadia/Remoting/Monarch.h | 2 +- src/cascadia/Remoting/WindowManager.cpp | 46 +++++++++++++++++++++++++ src/features.xml | 11 ++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/cascadia/Remoting/Monarch.h b/src/cascadia/Remoting/Monarch.h index ae85396b29a..a9eac206daf 100644 --- a/src/cascadia/Remoting/Monarch.h +++ b/src/cascadia/Remoting/Monarch.h @@ -27,7 +27,7 @@ constexpr GUID Monarch_clsid 0x7eb1, 0x4f3e, { - 0x85, 0xf5, 0x8b, 0xdd, 0x73, 0x86, 0xcc, 0xe3 + 0x85, 0xf5, 0x8b, 0xdd, 0x73, 0x86, 0xcc, 0xe4 } }; diff --git a/src/cascadia/Remoting/WindowManager.cpp b/src/cascadia/Remoting/WindowManager.cpp index 89f337830bf..d9d42100c8e 100644 --- a/src/cascadia/Remoting/WindowManager.cpp +++ b/src/cascadia/Remoting/WindowManager.cpp @@ -347,6 +347,52 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation void WindowManager::_createMonarchAndCallbacks() { _createMonarch(); + + if (_monarch == nullptr) + { + // See MSFT:38540483, GH#12774 for details. + TraceLoggingWrite(g_hRemotingProvider, + "WindowManager_NullMonarchTryAgain", + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + // Here we're gonna just give it a quick second try.Probably not + // definitive, but might help. + _createMonarch(); + } + + if (_monarch == nullptr) + { + // See MSFT:38540483, GH#12774 for details. + if constexpr (Feature_IsolatedMonarchMode::IsEnabled()) + { + // Fall back to having a in proc monarch. Were now isolated from + // other windows. This is a pretty torn state, but at least we + // didn't just explode. + TraceLoggingWrite(g_hRemotingProvider, + "WindowManager_NullMonarchIsolateMode", + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + + _monarch = winrt::make(); + } + else + { + // The monarch is null. We're hoping that we can find another, + // hopefully us. We're gonna go back around the loop again and + // see what happens. If this is really an infinite loop (where + // the OS won't even give us back US as the monarch), then I + // suppose we'll find out soon enough. + TraceLoggingWrite(g_hRemotingProvider, + "WindowManager_NullMonarchTryAgain", + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingKeyword(TIL_KEYWORD_TRACE)); + + winrt::hresult_error(E_UNEXPECTED, L"Did not expect the Monarch to ever be null"); + } + } + + // We're pretty confident that we have a Monarch here. + // Save the result of checking if we're the king. We want to avoid // unnecessary calls back and forth if we can. _isKing = _areWeTheKing(); diff --git a/src/features.xml b/src/features.xml index c2fde9d2765..d08b97a9026 100644 --- a/src/features.xml +++ b/src/features.xml @@ -95,4 +95,15 @@ Preview + + + Feature_IsolatedMonarchMode + Enables a test flag for MSFT:38540483. When enabled, if we ever create a null Monarch, we'll stealthily try to fall back to an in-proc monarch instance. + AlwaysEnabled + + + Dev + Preview + + From 675bf984a87ba712599b37b94eb09fa03555f72d Mon Sep 17 00:00:00 2001 From: achermack <40219585+achermack@users.noreply.github.com> Date: Mon, 4 Apr 2022 18:59:21 -0500 Subject: [PATCH 35/67] Add a quote to fix the build for paths with spaces (#12803) Adds " around the GenerateHeaderForJson.ps1 to support directories with a space as described in #12745 Closes #12745 --- .../Microsoft.Terminal.Settings.ModelLib.vcxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj index c37026831c5..4d168b7724e 100644 --- a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj +++ b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj @@ -1,5 +1,6 @@ - + {CA5CAD1A-d7ec-4107-b7c6-79cb77ae2907} Win32Proj @@ -230,8 +231,7 @@ - @@ -285,15 +285,15 @@ we can include in the code directly. This way, we don't need to worry about failing to load the default settings at runtime. --> - + - + - + From e9785e450acd7d16727e3ef72fb74f95e692b3be Mon Sep 17 00:00:00 2001 From: Mathias Kaas-Olsen Date: Tue, 5 Apr 2022 12:51:43 +0200 Subject: [PATCH 36/67] Include keyboard modalities when processing key events (#12823) Followed reproduction steps from linked issue #12818, wt.exe shows expected behaviour for capslock, scrolllock and numlock (assuming numlock is an "enhanced" key): ``` C:\Users\Kaas\source\Playground\x64\Debug>Playground.exe KeyState: Up, KeyCode: 0x0d, ScanCode: 0x1c, Unicode: (0x000d), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: a (0x0061), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: s (0x0073), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: d (0x0064), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x41, ScanCode: 0x1e, Unicode: A (0x0041), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x44, ScanCode: 0x20, Unicode: D (0x0044), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x91, ScanCode: 0x46, Unicode: (0x0000), Modifiers: 0x00c0 KeyState: Up, KeyCode: 0x91, ScanCode: 0x46, Unicode: (0x0000), Modifiers: 0x00c0 KeyState: Down, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x00c0 KeyState: Up, KeyCode: 0x53, ScanCode: 0x1f, Unicode: S (0x0053), Modifiers: 0x00c0 KeyState: Down, KeyCode: 0x90, ScanCode: 0x45, Unicode: (0x0000), Modifiers: 0x01e0 KeyState: Up, KeyCode: 0x90, ScanCode: 0x45, Unicode: (0x0000), Modifiers: 0x01e0 KeyState: Down, KeyCode: 0x4e, ScanCode: 0x31, Unicode: N (0x004e), Modifiers: 0x00e0 KeyState: Up, KeyCode: 0x4e, ScanCode: 0x31, Unicode: N (0x004e), Modifiers: 0x00e0 KeyState: Down, KeyCode: 0x90, ScanCode: 0x45, Unicode: (0x0000), Modifiers: 0x01c0 KeyState: Up, KeyCode: 0x90, ScanCode: 0x45, Unicode: (0x0000), Modifiers: 0x01c0 KeyState: Down, KeyCode: 0x91, ScanCode: 0x46, Unicode: (0x0000), Modifiers: 0x0080 KeyState: Up, KeyCode: 0x91, ScanCode: 0x46, Unicode: (0x0000), Modifiers: 0x0080 KeyState: Down, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Up, KeyCode: 0x14, ScanCode: 0x3a, Unicode: (0x0000), Modifiers: 0x0000 KeyState: Down, KeyCode: 0x51, ScanCode: 0x10, Unicode: q (0x0071), Modifiers: 0x0000 ``` Closes #12818 --- src/cascadia/TerminalControl/TermControl.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index d09c1c06884..818a10c9b4b 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -2163,6 +2163,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } + constexpr std::array modalities{ { + { VirtualKey::CapitalLock, ControlKeyStates::CapslockOn }, + { VirtualKey::NumberKeyLock, ControlKeyStates::NumlockOn }, + { VirtualKey::Scroll, ControlKeyStates::ScrolllockOn }, + } }; + + for (const auto& mod : modalities) + { + const auto state = window.GetKeyState(mod.vkey); + const auto isLocked = WI_IsFlagSet(state, CoreVirtualKeyStates::Locked); + + if (isLocked) + { + flags |= mod.flags; + } + } + return flags; } From 8aa38d3437d654bcb8a7c6fbdd28435b849855cd Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 5 Apr 2022 12:52:28 +0200 Subject: [PATCH 37/67] Upgrade clang-format to 13.0.1 (#12826) This commit fixes some formatting bugs by upgrading clang-format and ensures that our code is again formatted the same way Visual Studio 2022 would do it. --- src/api-ms-win-core-synch-l1-2-0/main.cpp | 6 +++--- src/cascadia/TerminalApp/TerminalTab.cpp | 4 ++-- .../WindowsTerminal/NonClientIslandWindow.cpp | 4 ++-- src/propsheet/dbcs.cpp | 6 ++---- src/propsheet/misc.cpp | 12 +++--------- src/propsheet/preview.cpp | 3 +-- src/renderer/gdi/state.cpp | 4 +++- tools/packages.config | 2 +- 8 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/api-ms-win-core-synch-l1-2-0/main.cpp b/src/api-ms-win-core-synch-l1-2-0/main.cpp index 7bbc50ac7e2..e13ac11933b 100644 --- a/src/api-ms-win-core-synch-l1-2-0/main.cpp +++ b/src/api-ms-win-core-synch-l1-2-0/main.cpp @@ -28,7 +28,7 @@ namespace class [[nodiscard]] SRWLockGuard { public: - explicit SRWLockGuard(SRWLOCK & lock) noexcept : + explicit SRWLockGuard(SRWLOCK& lock) noexcept : _lock(&lock) { AcquireSRWLockExclusive(_lock); @@ -42,7 +42,7 @@ namespace SRWLockGuard(const SRWLockGuard&) = delete; SRWLockGuard& operator=(const SRWLockGuard&) = delete; - SRWLockGuard(SRWLockGuard &&) = delete; + SRWLockGuard(SRWLockGuard&&) = delete; SRWLockGuard& operator=(SRWLockGuard&&) = delete; private: @@ -77,7 +77,7 @@ namespace GuardedWaitContext(const GuardedWaitContext&) = delete; GuardedWaitContext& operator=(const GuardedWaitContext&) = delete; - GuardedWaitContext(GuardedWaitContext &&) = delete; + GuardedWaitContext(GuardedWaitContext&&) = delete; GuardedWaitContext& operator=(GuardedWaitContext&&) = delete; }; diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 96ecad9d8b9..6dec987f567 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -864,7 +864,7 @@ namespace winrt::TerminalApp::implementation } }); - events.taskbarToken = control.SetTaskbarProgress([dispatcher, weakThis](auto&&, auto &&) -> winrt::fire_and_forget { + events.taskbarToken = control.SetTaskbarProgress([dispatcher, weakThis](auto&&, auto&&) -> winrt::fire_and_forget { co_await wil::resume_foreground(dispatcher); // Check if Tab's lifetime has expired if (auto tab{ weakThis.get() }) @@ -1069,7 +1069,7 @@ namespace winrt::TerminalApp::implementation // Add a Closed event handler to the Pane. If the pane closes out from // underneath us, and it's zoomed, we want to be able to make sure to // update our state accordingly to un-zoom that pane. See GH#7252. - auto closedToken = pane->Closed([weakThis, weakPane](auto&& /*s*/, auto && /*e*/) -> winrt::fire_and_forget { + auto closedToken = pane->Closed([weakThis, weakPane](auto&& /*s*/, auto&& /*e*/) -> winrt::fire_and_forget { if (auto tab{ weakThis.get() }) { if (tab->_zoomedPane) diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp index 7327656970f..cfafe8db448 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp @@ -506,8 +506,8 @@ void NonClientIslandWindow::_OnMaximizeChange() noexcept const auto isIconified = WI_IsFlagSet(windowStyle, WS_ICONIC); const auto state = _isMaximized ? winrt::TerminalApp::WindowVisualState::WindowVisualStateMaximized : - isIconified ? winrt::TerminalApp::WindowVisualState::WindowVisualStateIconified : - winrt::TerminalApp::WindowVisualState::WindowVisualStateNormal; + isIconified ? winrt::TerminalApp::WindowVisualState::WindowVisualStateIconified : + winrt::TerminalApp::WindowVisualState::WindowVisualStateNormal; try { diff --git a/src/propsheet/dbcs.cpp b/src/propsheet/dbcs.cpp index e90615ebac7..8465977588a 100644 --- a/src/propsheet/dbcs.cpp +++ b/src/propsheet/dbcs.cpp @@ -63,8 +63,7 @@ void MakeAltRasterFont( } [[nodiscard]] NTSTATUS - InitializeDbcsMisc( - VOID) +InitializeDbcsMisc(VOID) { return TrueTypeFontList::s_Initialize(); } @@ -158,8 +157,7 @@ GetAltFaceName( } [[nodiscard]] NTSTATUS - DestroyDbcsMisc( - VOID) +DestroyDbcsMisc(VOID) { return TrueTypeFontList::s_Destroy(); } diff --git a/src/propsheet/misc.cpp b/src/propsheet/misc.cpp index 89c5583a29c..954fd6ff828 100644 --- a/src/propsheet/misc.cpp +++ b/src/propsheet/misc.cpp @@ -119,9 +119,7 @@ AddFaceNode( return pNew; } -VOID - DestroyFaceNodes( - VOID) +VOID DestroyFaceNodes(VOID) { PFACENODE pNext, pTmp; @@ -435,16 +433,12 @@ int AddFont( return FE_FONTOK; // and continue enumeration } -VOID - InitializeFonts( - VOID) +VOID InitializeFonts(VOID) { LOG_IF_FAILED(EnumerateFonts(EF_DEFFACE)); // Just the Default font } -VOID - DestroyFonts( - VOID) +VOID DestroyFonts(VOID) { ULONG FontIndex; diff --git a/src/propsheet/preview.cpp b/src/propsheet/preview.cpp index 6890dac2844..64ed9fae402 100644 --- a/src/propsheet/preview.cpp +++ b/src/propsheet/preview.cpp @@ -43,8 +43,7 @@ POINT NonClientSize; RECT WindowRect; DWORD PreviewFlags; -VOID - UpdatePreviewRect(VOID) +VOID UpdatePreviewRect(VOID) /*++ diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp index 0d36d39c6cd..52a105d6b80 100644 --- a/src/renderer/gdi/state.cpp +++ b/src/renderer/gdi/state.cpp @@ -301,7 +301,9 @@ GdiEngine::~GdiEngine() // If the font type has changed, select an appropriate font variant or soft font. const auto usingItalicFont = textAttributes.IsItalic(); - const auto fontType = usingSoftFont ? FontType::Soft : usingItalicFont ? FontType::Italic : FontType::Default; + const auto fontType = usingSoftFont ? FontType::Soft : + usingItalicFont ? FontType::Italic : + FontType::Default; if (fontType != _lastFontType) { switch (fontType) diff --git a/tools/packages.config b/tools/packages.config index a552f5bc0ea..f52e4f8eab2 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,4 +1,4 @@ - + From 9e03800438df42b4e89716aaabbed842926b136a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Apr 2022 06:16:34 -0500 Subject: [PATCH 38/67] Replace `RadioButton` expanders with `ComboBox`es (#12833) Replaces all the `RadioButton` expanders with `ComboBox`es, which can have the options inline, as opposed to in the expander content. For example, here's a single commit with the changes for a single one of these settings: https://github.com/microsoft/terminal/commit/745c77d03e402a35901bfc5516486e315b0f673f ### Checklist * [x] Closes #12648 * [x] Actually closes #9566 as well (by just removing all radio buttons) * [x] I work here * [x] Tested manually * [x] I'd love @carlos-zamora to have an a11y pass at this, just to see if it's egregious or not. ### Before, after: ![image](https://user-images.githubusercontent.com/18356694/161822068-939ff875-00ff-454a-8b58-cb843ba801f4.png) --- .../TerminalSettingsEditor/Appearances.xaml | 43 ++++++++----------- .../GlobalAppearance.xaml | 28 ++++++------ .../TerminalSettingsEditor/Interaction.xaml | 28 ++++++------ .../TerminalSettingsEditor/Launch.xaml | 42 +++++++++--------- .../Profiles_Advanced.xaml | 28 ++++++------ .../Profiles_Appearance.xaml | 16 +++---- 6 files changed, 90 insertions(+), 95 deletions(-) diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.xaml b/src/cascadia/TerminalSettingsEditor/Appearances.xaml index 606cfa82698..9feeb203281 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.xaml +++ b/src/cascadia/TerminalSettingsEditor/Appearances.xaml @@ -19,12 +19,7 @@ - - - - - @@ -118,7 +113,7 @@ @@ -176,12 +171,12 @@ - + SettingOverrideSource="{x:Bind Appearance.CursorShapeOverrideSource, Mode=OneWay}"> + @@ -245,12 +240,12 @@ ClearSettingValue="{x:Bind Appearance.ClearBackgroundImageStretchMode}" HasSettingValue="{x:Bind Appearance.HasBackgroundImageStretchMode, Mode=OneWay}" SettingOverrideSource="{x:Bind Appearance.BackgroundImageStretchModeOverrideSource, Mode=OneWay}" - Style="{StaticResource ExpanderSettingContainerStyle}" Visibility="{x:Bind Appearance.BackgroundImageSettingsVisible, Mode=OneWay}"> - + @@ -472,12 +467,12 @@ - + SettingOverrideSource="{x:Bind Appearance.IntenseTextStyleOverrideSource, Mode=OneWay}"> + diff --git a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml index 2a0bdbcb98a..2d15f1c2103 100644 --- a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml +++ b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml @@ -17,9 +17,9 @@ - - + @@ -40,12 +40,12 @@ - - + + @@ -79,12 +79,12 @@ - - + + diff --git a/src/cascadia/TerminalSettingsEditor/Interaction.xaml b/src/cascadia/TerminalSettingsEditor/Interaction.xaml index 8c0e7a08060..57f54132c46 100644 --- a/src/cascadia/TerminalSettingsEditor/Interaction.xaml +++ b/src/cascadia/TerminalSettingsEditor/Interaction.xaml @@ -17,9 +17,9 @@ - - + @@ -33,12 +33,12 @@ - - + + @@ -69,12 +69,12 @@ - - + + diff --git a/src/cascadia/TerminalSettingsEditor/Launch.xaml b/src/cascadia/TerminalSettingsEditor/Launch.xaml index 308ce6a10ab..fe0f5607f9e 100644 --- a/src/cascadia/TerminalSettingsEditor/Launch.xaml +++ b/src/cascadia/TerminalSettingsEditor/Launch.xaml @@ -18,9 +18,9 @@ - - + - +