terminal/src/cascadia/TerminalConnection/ConptyConnection.h

98 lines
3.9 KiB
C
Raw Normal View History

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "ConptyConnection.g.h"
#include "ConnectionStateHolder.h"
#include "../inc/cppwinrt_utils.h"
#include <conpty-static.h>
namespace wil
{
// These belong in WIL upstream, so when we reingest the change that has them we'll get rid of ours.
using unique_static_pseudoconsole_handle = wil::unique_any<HPCON, decltype(&::ConptyClosePseudoConsole), ::ConptyClosePseudoConsole>;
}
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
struct ConptyConnection : ConptyConnectionT<ConptyConnection>, ConnectionStateHolder<ConptyConnection>
{
ConptyConnection(const HANDLE hSig,
const HANDLE hIn,
const HANDLE hOut,
const HANDLE hRef,
const HANDLE hServerProcess,
const HANDLE hClientProcess);
Switch Connections to use `ValueSet`s to initialize them (#10184) #### ⚠️ targets #10051 ## Summary of the Pull Request This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties. Why? For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection. **IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings. We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments `ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used. ## Validation Steps Performed It still builds and runs.
2021-07-20 17:02:17 +02:00
ConptyConnection() noexcept = default;
void Initialize(const Windows::Foundation::Collections::ValueSet& settings);
static winrt::fire_and_forget final_release(std::unique_ptr<ConptyConnection> connection);
void Start();
void WriteInput(hstring const& data);
void Resize(uint32_t rows, uint32_t columns);
void Close() noexcept;
void ClearBuffer();
winrt::guid Guid() const noexcept;
static void StartInboundListener();
static void StopInboundListener();
static winrt::event_token NewConnection(NewConnectionHandler const& handler);
static void NewConnection(winrt::event_token const& token);
Switch Connections to use `ValueSet`s to initialize them (#10184) #### ⚠️ targets #10051 ## Summary of the Pull Request This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties. Why? For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection. **IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings. We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments `ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used. ## Validation Steps Performed It still builds and runs.
2021-07-20 17:02:17 +02:00
static Windows::Foundation::Collections::ValueSet CreateSettings(const winrt::hstring& cmdline,
const winrt::hstring& startingDirectory,
const winrt::hstring& startingTitle,
Windows::Foundation::Collections::IMapView<hstring, hstring> const& environment,
uint32_t rows,
uint32_t columns,
winrt::guid const& guid);
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
private:
HRESULT _LaunchAttachedClient() noexcept;
void _indicateExitWithStatus(unsigned int status) noexcept;
void _ClientTerminated() noexcept;
static HRESULT NewHandoff(HANDLE in, HANDLE out, HANDLE signal, HANDLE ref, HANDLE server, HANDLE client) noexcept;
uint32_t _initialRows{};
uint32_t _initialCols{};
Switch Connections to use `ValueSet`s to initialize them (#10184) #### ⚠️ targets #10051 ## Summary of the Pull Request This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties. Why? For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection. **IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings. We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments `ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used. ## Validation Steps Performed It still builds and runs.
2021-07-20 17:02:17 +02:00
hstring _commandline{};
hstring _startingDirectory{};
hstring _startingTitle{};
Windows::Foundation::Collections::ValueSet _environment{ nullptr };
guid _guid{}; // A unique session identifier for connected client
Gather data on profile customization and tab settings to help us improve defaults (#4534) ## Summary of the Pull Request This will collect some user choices related to profiles and tab settings to help us understand if and how we should change the in-built defaults. ## PR Checklist * [x] Closes #3855 * [x] I work here. * [x] Manual test only. * [x] Meh, no doc update. * [x] Am core contributor. ## Detailed Description of the Pull Request / Additional comments The following data is collected with examples of the types of questions we intend to answer: 1. What is the name of the executable attached to the PTY? (What shells are popular? Should we focus our testing on them? Are there any common ones we are blind to that we should know about?) - "Microsoft.Windows.Terminal.Connection" {e912fe7b-eeb6-52a5-c628-abe388e5f792} - "ConPtyConnected" event - "SessionGuid" value = WT_SESSION - "Client" value = Name of EXE 2. Is Acrylic used on a tab? And with what opacity? (Do people really want acrylic? Should it be default? What opacity is most pleasing in our context?) - "Microsoft.Windows.Terminal.App" {24a1622f-7da7-5c77-3303-d850bd1ab2ed} - "TabInformation" event - "EventVer" value is now 1u - "UseAcrylic" value is now TRUE/FALSE on the setting choice - "TintOpacity" value is now Float on the setting choice 3. What font are people choosing? (Do people move away from Cascadia Code? Which ones are the most popular for us to validate when updating the renderer?) - "Microsoft.Windows.Terminal.App" {24a1622f-7da7-5c77-3303-d850bd1ab2ed} - "TabInformation" event - "FontFace" value is now string font from settings 4. What keybindings do people choose to customize (Add or Remove)? (Are there extremely common keys that folks bind or unbind that we should have adjusted by default in a fresh install?) - "Microsoft.Windows.Terminal.App" {24a1622f-7da7-5c77-3303-d850bd1ab2ed} - "CustomKeybindings" event - "Keybindings" value is the entire JSON segment that describes the user keybindings from `settings.json`. 5. Do people change their default profile from the PowerShell one we set? If so, to what? (Should we not set PowerShell as the default? Should we adjust the ranking of our dynamic generators to favor the most popular ones to bubble to the top?) - "Microsoft.Windows.Terminal.App" {24a1622f-7da7-5c77-3303-d850bd1ab2ed} - "CustomDefaultProfile" event - "DefaultProfile" value is the GUID of the chosen profile ## Validation Steps Performed 1. Implemented the events 2. Launched the ETL channel viewer 3. Triggered the events 4. Saw the data come out
2020-02-12 21:02:48 +01:00
hstring _clientName{}; // The name of the process hosted by this ConPTY connection (as of launch).
bool _receivedFirstByte{ false };
std::chrono::high_resolution_clock::time_point _startTime{};
wil::unique_hfile _inPipe; // The pipe for writing input to
wil::unique_hfile _outPipe; // The pipe for reading output from
wil::unique_handle _hOutputThread;
wil::unique_process_information _piClient;
wil::unique_static_pseudoconsole_handle _hPC;
wil::unique_threadpool_wait _clientExitWait;
Switch Connections to use `ValueSet`s to initialize them (#10184) #### ⚠️ targets #10051 ## Summary of the Pull Request This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties. Why? For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection. **IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings. We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments `ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used. ## Validation Steps Performed It still builds and runs.
2021-07-20 17:02:17 +02:00
til::u8state _u8State{};
std::wstring _u16Str{};
std::array<char, 4096> _buffer{};
DWORD _OutputThread();
};
}
namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation
{
struct ConptyConnection : ConptyConnectionT<ConptyConnection, implementation::ConptyConnection>
{
};
}