mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-05 21:59:47 +00:00
Send a CPR request on every unknown sequence (#20009)
This PR is 90% wiring up OOP interfaces. Closes #19926 ## Validation Steps Performed * Run `github.com/xtermjs/vtc` * Observed `UnknownSequence` calls under a debugger
This commit is contained in:
@@ -1522,6 +1522,10 @@ void Terminal::SerializeMainBuffer(HANDLE handle) const
|
||||
_mainBuffer->SerializeTo(handle);
|
||||
}
|
||||
|
||||
void Terminal::UnknownSequence() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void Terminal::ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode)
|
||||
{
|
||||
const auto colorSelection = [this](const til::point coordStartInclusive, const til::point coordEndExclusive, const TextAttribute& attr) {
|
||||
|
||||
@@ -131,6 +131,7 @@ public:
|
||||
|
||||
#pragma region ITerminalApi
|
||||
// These methods are defined in TerminalApi.cpp
|
||||
void UnknownSequence() noexcept override;
|
||||
void ReturnResponse(const std::wstring_view response) override;
|
||||
bool IsConPTY() const noexcept override;
|
||||
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() noexcept override;
|
||||
|
||||
@@ -24,6 +24,22 @@ ConhostInternalGetSet::ConhostInternalGetSet(_In_ IIoProvider& io) :
|
||||
{
|
||||
}
|
||||
|
||||
void ConhostInternalGetSet::UnknownSequence() noexcept
|
||||
{
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
|
||||
// VT sequences unknown to us may cause the cursor position to change in a way that
|
||||
// we don't know about. In this case, we need to mark the cursor position as "dirty".
|
||||
//
|
||||
// The worst offender is likely PowerShell. It uses VT sequences but also calls
|
||||
// GetConsoleScreenBufferInfoEx for *every single line of output* (!!!). This prevents
|
||||
// us from using a more conservative solution (e.g. always fetching the cursor position).
|
||||
if (gci.IsInVtIoMode())
|
||||
{
|
||||
gci.GetActiveOutputBuffer().SetConptyCursorPositionMayBeWrong();
|
||||
}
|
||||
}
|
||||
|
||||
// - Sends a string response 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.
|
||||
// - This will generate two "key presses" (one down, one up) for every character in the string and place them into the head of the console's input stream.
|
||||
|
||||
@@ -29,6 +29,7 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::
|
||||
public:
|
||||
ConhostInternalGetSet(_In_ Microsoft::Console::IIoProvider& io);
|
||||
|
||||
void UnknownSequence() noexcept override;
|
||||
void ReturnResponse(const std::wstring_view response) override;
|
||||
|
||||
bool IsConPTY() const noexcept override;
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
#pragma warning(disable : 26432) // suppress rule of 5 violation on interface because tampering with this is fraught with peril
|
||||
virtual ~ITermDispatch() = 0;
|
||||
|
||||
virtual void UnknownSequence() noexcept = 0;
|
||||
virtual void Print(const wchar_t wchPrintable) = 0;
|
||||
virtual void PrintString(const std::wstring_view string) = 0;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
ITerminalApi& operator=(const ITerminalApi&) = delete;
|
||||
ITerminalApi& operator=(ITerminalApi&&) = delete;
|
||||
|
||||
virtual void UnknownSequence() noexcept = 0;
|
||||
virtual void ReturnResponse(const std::wstring_view response) = 0;
|
||||
|
||||
struct BufferState
|
||||
|
||||
@@ -48,6 +48,11 @@ AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettin
|
||||
{
|
||||
}
|
||||
|
||||
void AdaptDispatch::UnknownSequence() noexcept
|
||||
{
|
||||
_api.UnknownSequence();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Translates and displays a single character
|
||||
// Arguments:
|
||||
@@ -3607,6 +3612,10 @@ void AdaptDispatch::DoConEmuAction(const std::wstring_view string)
|
||||
_pages.ActivePage().Buffer().StartCommand();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
}
|
||||
else
|
||||
{
|
||||
_api.UnknownSequence();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -3638,6 +3647,10 @@ void AdaptDispatch::DoITerm2Action(const std::wstring_view string)
|
||||
_pages.ActivePage().Buffer().StartPrompt();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
}
|
||||
else
|
||||
{
|
||||
_api.UnknownSequence();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -3708,9 +3721,14 @@ void AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_api.UnknownSequence();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_api.UnknownSequence();
|
||||
}
|
||||
|
||||
// When we add the rest of the FTCS sequences (GH#11000), we should add a
|
||||
// simple state machine here to track the most recently emitted mark from
|
||||
@@ -3785,6 +3803,10 @@ void AdaptDispatch::DoVsCodeAction(const std::wstring_view string)
|
||||
|
||||
// If it's poorly formatted, just eat it
|
||||
}
|
||||
else
|
||||
{
|
||||
_api.UnknownSequence();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
public:
|
||||
AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept;
|
||||
|
||||
void UnknownSequence() noexcept override;
|
||||
void Print(const wchar_t wchPrintable) override;
|
||||
void PrintString(const std::wstring_view string) override;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Console::VirtualTerminal::ITermDispatch
|
||||
{
|
||||
public:
|
||||
void UnknownSequence() noexcept override {}
|
||||
void Print(const wchar_t wchPrintable) override = 0;
|
||||
void PrintString(const std::wstring_view string) override = 0;
|
||||
|
||||
|
||||
@@ -60,6 +60,10 @@ using namespace Microsoft::Console::VirtualTerminal;
|
||||
class TestGetSet final : public ITerminalApi
|
||||
{
|
||||
public:
|
||||
void UnknownSequence() noexcept override
|
||||
{
|
||||
}
|
||||
|
||||
void ReturnResponse(const std::wstring_view response) override
|
||||
{
|
||||
Log::Comment(L"ReturnResponse MOCK called...");
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
IStateMachineEngine& operator=(const IStateMachineEngine&) = default;
|
||||
IStateMachineEngine& operator=(IStateMachineEngine&&) = default;
|
||||
|
||||
virtual void UnknownSequence() noexcept = 0;
|
||||
virtual bool EncounteredWin32InputModeSequence() const noexcept = 0;
|
||||
|
||||
virtual bool ActionExecute(const wchar_t wch) = 0;
|
||||
|
||||
@@ -129,6 +129,10 @@ til::enumset<DeviceAttribute, uint64_t> InputStateMachineEngine::WaitUntilDA1(DW
|
||||
return til::enumset<DeviceAttribute, uint64_t>::from_bits(val);
|
||||
}
|
||||
|
||||
void InputStateMachineEngine::UnknownSequence() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
bool InputStateMachineEngine::EncounteredWin32InputModeSequence() const noexcept
|
||||
{
|
||||
return _encounteredWin32InputModeSequence;
|
||||
|
||||
@@ -166,6 +166,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
void CaptureNextCursorPositionReport() noexcept;
|
||||
til::enumset<DeviceAttribute, uint64_t> WaitUntilDA1(DWORD timeout) noexcept;
|
||||
|
||||
void UnknownSequence() noexcept override;
|
||||
bool EncounteredWin32InputModeSequence() const noexcept override;
|
||||
|
||||
bool ActionExecute(const wchar_t wch) override;
|
||||
|
||||
@@ -24,6 +24,11 @@ OutputStateMachineEngine::OutputStateMachineEngine(std::unique_ptr<ITermDispatch
|
||||
THROW_HR_IF_NULL(E_INVALIDARG, _dispatch.get());
|
||||
}
|
||||
|
||||
void OutputStateMachineEngine::UnknownSequence() noexcept
|
||||
{
|
||||
_dispatch->UnknownSequence();
|
||||
}
|
||||
|
||||
bool OutputStateMachineEngine::EncounteredWin32InputModeSequence() const noexcept
|
||||
{
|
||||
return false;
|
||||
@@ -683,6 +688,7 @@ bool OutputStateMachineEngine::ActionCsiDispatch(const VTID id, const VTParamete
|
||||
_dispatch->PopKittyKeyboardProtocol(parameters.at(0));
|
||||
break;
|
||||
default:
|
||||
_dispatch->UnknownSequence();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -737,7 +743,7 @@ IStateMachineEngine::StringHandler OutputStateMachineEngine::ActionDcsDispatch(c
|
||||
handler = _dispatch->RestorePresentationState(parameters.at(0));
|
||||
break;
|
||||
default:
|
||||
handler = nullptr;
|
||||
_dispatch->UnknownSequence();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -858,6 +864,10 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::CurrentWorkingDirectory:
|
||||
// TODO: Add support for OSC 7 = CWD sequences?
|
||||
// In GH#8214 it was decided that it's a bad idea due to WSL compat.
|
||||
break;
|
||||
case OscActionCodes::Hyperlink:
|
||||
{
|
||||
std::wstring params;
|
||||
@@ -901,6 +911,7 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_dispatch->UnknownSequence();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -921,6 +932,7 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||
bool OutputStateMachineEngine::ActionSs3Dispatch(const wchar_t /*wch*/, const VTParameters /*parameters*/) noexcept
|
||||
{
|
||||
// The output engine doesn't handle any SS3 sequences.
|
||||
_dispatch->UnknownSequence();
|
||||
_ClearLastChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
OutputStateMachineEngine(std::unique_ptr<ITermDispatch> pDispatch);
|
||||
|
||||
void UnknownSequence() noexcept override;
|
||||
bool EncounteredWin32InputModeSequence() const noexcept override;
|
||||
|
||||
bool ActionExecute(const wchar_t wch) override;
|
||||
@@ -203,13 +204,14 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
ExitVt52Mode = VTID("<")
|
||||
};
|
||||
|
||||
enum OscActionCodes : unsigned int
|
||||
enum OscActionCodes : size_t
|
||||
{
|
||||
SetIconAndWindowTitle = 0,
|
||||
SetWindowIcon = 1,
|
||||
SetWindowTitle = 2,
|
||||
SetWindowProperty = 3, // Not implemented
|
||||
SetColor = 4,
|
||||
CurrentWorkingDirectory = 7,
|
||||
Hyperlink = 8,
|
||||
ConEmuAction = 9,
|
||||
SetForegroundColor = 10,
|
||||
|
||||
@@ -1044,6 +1044,7 @@ void StateMachine::_EnterSosPmApcString() noexcept
|
||||
{
|
||||
_state = VTStates::SosPmApcString;
|
||||
_cachedSequence.reset();
|
||||
_engine->UnknownSequence();
|
||||
_trace.TraceStateChange(L"SosPmApcString");
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public:
|
||||
dcsDataString.clear();
|
||||
}
|
||||
|
||||
void UnknownSequence() noexcept override
|
||||
{
|
||||
}
|
||||
|
||||
bool EncounteredWin32InputModeSequence() const noexcept override
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user