Repository: microsoft/terminal
File: src/terminal/adapter/InteractDispatch.cpp (C++)

Code before:
{
    const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
    gci.GetActiveInputBuffer()->Write(inputEvents);
}

// Method Description:
// - Writes a key event to the host in a fashion that will enable the host to
//   process special keys such as Ctrl-C or Ctrl+Break. The host will then
//   decide what to do with it, including potentially sending an interrupt to a
//   client application.
// Arguments:
// - event: The key to send to the host.
void InteractDispatch::WriteCtrlKey(const INPUT_RECORD& event)
{
    HandleGenericKeyEvent(event, false);
}

// Method Description:
// - Writes a string of input to the host.
// Arguments:
// - string : a string to write to the console.
void InteractDispatch::WriteString(const std::wstring_view string)
{
    const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
    gci.GetActiveInputBuffer()->WriteString(string);
}

//Method Description:
// Window Manipulation - Performs a variety of actions relating to the window,
//      such as moving the window position, resizing the window, querying
//      window state, forcing the window to repaint, etc.
//  This is kept separate from the output version, as there may be
//      codes that are supported in one direction but not the other.
//Arguments:
// - function - An identifier of the WindowManipulation function to perform
// - parameter1 - The first optional parameter for the function
// - parameter2 - The second optional parameter for the function
void InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType function,
                                          const VTParameter parameter1,
                                          const VTParameter parameter2)
{
    // Other Window Manipulation functions:
    //  MSFT:13271098 - QueryViewport
    //  MSFT:13271146 - QueryScreenSize
    switch (function)
    {
    case DispatchTypes::WindowManipulationType::DeIconifyWindow:
        _api.ShowWindow(true);
        break;
    case DispatchTypes::WindowManipulationType::IconifyWindow:
        _api.ShowWindow(false);

Review comment (suggestion):
You're going to hate me for bringing this up, but I think we might actually need both versions of this function, with `ActionPrintString` calling the old version (i.e. generating key events), and `ActionPassThroughString` calling your new version that writes directly to the input buffer.

The reason being that we still need to support third-party terminals that don't necessarily implement win32-input-mode, and you can see how that affects things by commenting out our implementation of the win32-input-mode in `AdaptDispatch`.

With this PR applied, regular character keys no longer generate up and down key events with their actual virtual key code - you just get a single null virtual key code with the appropriate char value. That may be good enough in many cases, but I suspect there will be some apps that require full key events.

So for that to work correctly, I think `ActionPrintString` needs to be left as it was using the old implementation of `WriteString`. And to fix the VT responses, we just need to make `ActionPassThroughString` call your new version.

Code after:
{
    const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
    gci.GetActiveInputBuffer()->Write(inputEvents);
}

// Method Description:
// - Writes a key event to the host in a fashion that will enable the host to
//   process special keys such as Ctrl-C or Ctrl+Break. The host will then
//   decide what to do with it, including potentially sending an interrupt to a
//   client application.
// Arguments:
// - event: The key to send to the host.
void InteractDispatch::WriteCtrlKey(const INPUT_RECORD& event)
{
    HandleGenericKeyEvent(event, false);
}

// Call this method to write some plain text to the InputBuffer.
//
// Since the hosting terminal for ConPTY may not support win32-input-mode,
// it may send an "A" key as an "A", for which we need to generate up/down events.
// Because of this, we cannot simply call InputBuffer::WriteString directly.
void InteractDispatch::WriteString(const std::wstring_view string)
{
    if (!string.empty())
    {
        const auto codepage = _api.GetConsoleOutputCP();
        InputEventQueue keyEvents;

        for (const auto& wch : string)
        {
            CharToKeyEvents(wch, codepage, keyEvents);
        }

        WriteInput(keyEvents);
    }
}

void InteractDispatch::WriteStringRaw(std::wstring_view string)
{
    const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
    gci.GetActiveInputBuffer()->WriteString(string);
}

//Method Description:
// Window Manipulation - Performs a variety of actions relating to the window,
//      such as moving the window position, resizing the window, querying
//      window state, forcing the window to repaint, etc.
//  This is kept separate from the output version, as there may be
//      codes that are supported in one direction but not the other.
//Arguments: