[DefApp] Teach connection and tab to negotiate initial size (#10772)

- For tabs started from the Terminal, the initial sizing information is
  passed into the connection and used to establish the PTY. Those
  parameters are given over to the `OpenConsole.exe` acting as PTY to
  establish the initial buffer/window size.
- However, for tabs started from outside, the PTY is created with some
  default buffer information FIRST as the Terminal hasn't even been
  involved yet. As such, when the Terminal gets that connection, it must
  tell the PTY to resize just as it connects to match the window size
  it's about to use.
- Ongoing resize operations in the Terminal did and still work fine
  because they transmitted the updated size with the
  `ResizePseudoConsole` API.

## Validation Steps Performed
- [x] Confirmed existing tabs opening have correct initial size in PTY
  (like with CMD `mode con` command)
- [x] Confirmed inbound cmd tabs have correct initial size in PTY via
  `mode con` command per bug repro

Closes #9811
This commit is contained in:
Michael Niksa 2021-07-26 12:31:48 -07:00 committed by GitHub
parent 3a71ead757
commit 862217b04b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 2 deletions

View file

@ -105,6 +105,14 @@ namespace winrt::TerminalApp::implementation
// Create a connection based on the values in our settings object if we weren't given one.
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profileGuid, settings.DefaultSettings());
// If we had an `existingConnection`, then this is an inbound handoff from somewhere else.
// We need to tell it about our size information so it can match the dimensions of what
// we are about to present.
if (existingConnection)
{
connection.Resize(settings.DefaultSettings().InitialRows(), settings.DefaultSettings().InitialCols());
}
TerminalConnection::ITerminalConnection debugConnection{ nullptr };
if (_settings.GlobalSettings().DebugFeaturesEnabled())
{

View file

@ -289,12 +289,21 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
_transitionToState(ConnectionState::Connecting);
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
// If we do not have pipes already, then this is a fresh connection... not an inbound one that is a received
// handoff from an already-started PTY process.
if (!_inPipe)
{
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, PSEUDOCONSOLE_RESIZE_QUIRK | PSEUDOCONSOLE_WIN32_INPUT_MODE, &_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
// window is expecting it to be on the first layout.
else
{
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), dimensions));
}
_startTime = std::chrono::high_resolution_clock::now();
@ -423,11 +432,14 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
void ConptyConnection::Resize(uint32_t rows, uint32_t columns)
{
if (!_hPC)
// If we haven't started connecting at all, it's still fair to update
// the initial rows and columns before we set things up.
if (!_isStateAtOrBeyond(ConnectionState::Connecting))
{
_initialRows = rows;
_initialCols = columns;
}
// Otherwise, we can really only dispatch a resize if we're already connected.
else if (_isConnected())
{
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), { Utils::ClampToShortMax(columns, 1), Utils::ClampToShortMax(rows, 1) }));