mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-11 04:38:24 -06:00
Indicate support for OSC 52 in the DA1 report (#19034)
## Summary of the Pull Request Some applications that make use of the `OSC 52` clipboard sequence will only do so if they can be certain that the terminal actually has that functionality. Indicating our support for `OSC 52` in the `DA1` report will give them an easy way to detect that. ## References and Relevant Issues `OSC 52` support was added to Windows Terminal in issue #5823, and to ConHost in issue #18949. ## Detailed Description of the Pull Request / Additional comments Support for writing to the clipboard is indicated in the primary device attributes report by the extension parameter `52`. This is obviously not a standard DEC extension, but it's one that's been agreed upon by a number of modern terminals. The extension is only reported when writing to the clipboard is actually permitted (Windows Terminal has an option to disable that). ## Validation Steps Performed I've updated the Device Attributes unit test to check that we're reporting extension `52` when clipboard access is enabled, and not reporting it when disabled. ## PR Checklist - [x] Closes #19017 - [x] Tests added/passed
This commit is contained in:
parent
4cf492e36b
commit
00ee88400a
@ -94,7 +94,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
|||||||
|
|
||||||
if (_stateMachine)
|
if (_stateMachine)
|
||||||
{
|
{
|
||||||
SetVtChecksumReportSupport(settings.AllowVtChecksumReport());
|
SetOptionalFeatures(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTerminalInput().ForceDisableWin32InputMode(settings.ForceVTInput());
|
_getTerminalInput().ForceDisableWin32InputMode(settings.ForceVTInput());
|
||||||
@ -232,10 +232,13 @@ void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
|
|||||||
engine.Dispatch().SetCursorStyle(cursorStyle);
|
engine.Dispatch().SetCursorStyle(cursorStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::SetVtChecksumReportSupport(const bool enabled)
|
void Terminal::SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettings settings)
|
||||||
{
|
{
|
||||||
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
|
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
|
||||||
engine.Dispatch().SetVtChecksumReportSupport(enabled);
|
auto features = til::enumset<ITermDispatch::OptionalFeature>{};
|
||||||
|
features.set(ITermDispatch::OptionalFeature::ChecksumReport, settings.AllowVtChecksumReport());
|
||||||
|
features.set(ITermDispatch::OptionalFeature::ClipboardWrite, settings.AllowVtClipboardWrite());
|
||||||
|
engine.Dispatch().SetOptionalFeatures(features);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Terminal::IsXtermBracketedPasteModeEnabled() const noexcept
|
bool Terminal::IsXtermBracketedPasteModeEnabled() const noexcept
|
||||||
|
|||||||
@ -95,7 +95,7 @@ public:
|
|||||||
void SetHighContrastMode(bool hc) noexcept;
|
void SetHighContrastMode(bool hc) noexcept;
|
||||||
void SetFontInfo(const FontInfo& fontInfo);
|
void SetFontInfo(const FontInfo& fontInfo);
|
||||||
void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle);
|
void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle);
|
||||||
void SetVtChecksumReportSupport(const bool enabled);
|
void SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettings settings);
|
||||||
bool IsXtermBracketedPasteModeEnabled() const noexcept;
|
bool IsXtermBracketedPasteModeEnabled() const noexcept;
|
||||||
std::wstring_view GetWorkingDirectory() noexcept;
|
std::wstring_view GetWorkingDirectory() noexcept;
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,12 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
|
|||||||
public:
|
public:
|
||||||
using StringHandler = std::function<bool(const wchar_t)>;
|
using StringHandler = std::function<bool(const wchar_t)>;
|
||||||
|
|
||||||
|
enum class OptionalFeature
|
||||||
|
{
|
||||||
|
ChecksumReport,
|
||||||
|
ClipboardWrite,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 26432) // suppress rule of 5 violation on interface because tampering with this is fraught with peril
|
#pragma warning(disable : 26432) // suppress rule of 5 violation on interface because tampering with this is fraught with peril
|
||||||
virtual ~ITermDispatch() = 0;
|
virtual ~ITermDispatch() = 0;
|
||||||
@ -133,7 +139,6 @@ public:
|
|||||||
virtual void ScreenAlignmentPattern() = 0; // DECALN
|
virtual void ScreenAlignmentPattern() = 0; // DECALN
|
||||||
|
|
||||||
virtual void SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
|
virtual void SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
|
||||||
virtual void SetVtChecksumReportSupport(const bool enabled) = 0;
|
|
||||||
|
|
||||||
virtual void SetClipboard(wil::zwstring_view content) = 0; // OSCSetClipboard
|
virtual void SetClipboard(wil::zwstring_view content) = 0; // OSCSetClipboard
|
||||||
|
|
||||||
@ -185,6 +190,8 @@ public:
|
|||||||
virtual StringHandler RestorePresentationState(const DispatchTypes::PresentationReportFormat format) = 0; // DECRSPS
|
virtual StringHandler RestorePresentationState(const DispatchTypes::PresentationReportFormat format) = 0; // DECRSPS
|
||||||
|
|
||||||
virtual void PlaySounds(const VTParameters parameters) = 0; // DECPS
|
virtual void PlaySounds(const VTParameters parameters) = 0; // DECPS
|
||||||
|
|
||||||
|
virtual void SetOptionalFeatures(const til::enumset<OptionalFeature> features) = 0;
|
||||||
};
|
};
|
||||||
inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() = default;
|
inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() = default;
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|||||||
@ -1297,11 +1297,6 @@ void AdaptDispatch::SelectAttributeChangeExtent(const DispatchTypes::ChangeExten
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdaptDispatch::SetVtChecksumReportSupport(const bool enabled) noexcept
|
|
||||||
{
|
|
||||||
_vtChecksumReportEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - DECRQCRA - Computes and reports a checksum of the specified area of
|
// - DECRQCRA - Computes and reports a checksum of the specified area of
|
||||||
// the buffer memory.
|
// the buffer memory.
|
||||||
@ -1318,7 +1313,7 @@ void AdaptDispatch::RequestChecksumRectangularArea(const VTInt id, const VTInt p
|
|||||||
// If this feature is not enabled, we'll just report a zero checksum.
|
// If this feature is not enabled, we'll just report a zero checksum.
|
||||||
if constexpr (Feature_VtChecksumReport::IsEnabled())
|
if constexpr (Feature_VtChecksumReport::IsEnabled())
|
||||||
{
|
{
|
||||||
if (_vtChecksumReportEnabled)
|
if (_optionalFeatures.test(OptionalFeature::ChecksumReport))
|
||||||
{
|
{
|
||||||
// If the page number is 0, then we're meant to return a checksum of all
|
// If the page number is 0, then we're meant to return a checksum of all
|
||||||
// of the pages, but we have no need for that, so we'll just return 0.
|
// of the pages, but we have no need for that, so we'll just return 0.
|
||||||
@ -1483,8 +1478,16 @@ void AdaptDispatch::DeviceAttributes()
|
|||||||
// 28 = Rectangular area operations
|
// 28 = Rectangular area operations
|
||||||
// 32 = Text macros
|
// 32 = Text macros
|
||||||
// 42 = ISO Latin-2 character set
|
// 42 = ISO Latin-2 character set
|
||||||
|
// 52 = Clipboard access
|
||||||
|
|
||||||
_ReturnCsiResponse(L"?61;4;6;7;14;21;22;23;24;28;32;42c");
|
if (_optionalFeatures.test(OptionalFeature::ClipboardWrite))
|
||||||
|
{
|
||||||
|
_ReturnCsiResponse(L"?61;4;6;7;14;21;22;23;24;28;32;42;52c");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ReturnCsiResponse(L"?61;4;6;7;14;21;22;23;24;28;32;42c");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@ -4790,3 +4793,8 @@ void AdaptDispatch::PlaySounds(const VTParameters parameters)
|
|||||||
_api.PlayMidiNote(noteNumber, noteNumber == 71 ? 0 : velocity, duration);
|
_api.PlayMidiNote(noteNumber, noteNumber == 71 ? 0 : velocity, duration);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdaptDispatch::SetOptionalFeatures(const til::enumset<OptionalFeature> features) noexcept
|
||||||
|
{
|
||||||
|
_optionalFeatures = features;
|
||||||
|
}
|
||||||
|
|||||||
@ -188,7 +188,7 @@ namespace Microsoft::Console::VirtualTerminal
|
|||||||
|
|
||||||
void PlaySounds(const VTParameters parameters) override; // DECPS
|
void PlaySounds(const VTParameters parameters) override; // DECPS
|
||||||
|
|
||||||
void SetVtChecksumReportSupport(const bool enabled) noexcept override;
|
void SetOptionalFeatures(const til::enumset<OptionalFeature> features) noexcept override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Mode
|
enum class Mode
|
||||||
@ -313,7 +313,7 @@ namespace Microsoft::Console::VirtualTerminal
|
|||||||
std::unique_ptr<FontBuffer> _fontBuffer;
|
std::unique_ptr<FontBuffer> _fontBuffer;
|
||||||
std::shared_ptr<MacroBuffer> _macroBuffer;
|
std::shared_ptr<MacroBuffer> _macroBuffer;
|
||||||
std::optional<unsigned int> _initialCodePage;
|
std::optional<unsigned int> _initialCodePage;
|
||||||
bool _vtChecksumReportEnabled = false;
|
til::enumset<OptionalFeature> _optionalFeatures = { OptionalFeature::ClipboardWrite };
|
||||||
|
|
||||||
// We have two instances of the saved cursor state, because we need
|
// We have two instances of the saved cursor state, because we need
|
||||||
// one for the main buffer (at index 0), and another for the alt buffer
|
// one for the main buffer (at index 0), and another for the alt buffer
|
||||||
|
|||||||
@ -178,7 +178,7 @@ public:
|
|||||||
|
|
||||||
void PlaySounds(const VTParameters /*parameters*/) override{}; // DECPS
|
void PlaySounds(const VTParameters /*parameters*/) override{}; // DECPS
|
||||||
|
|
||||||
void SetVtChecksumReportSupport(const bool /*enabled*/) override{};
|
void SetOptionalFeatures(const til::enumset<OptionalFeature> /*features*/) override{};
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma warning(default : 26440) // Restore "can be declared noexcept" warning
|
#pragma warning(default : 26440) // Restore "can be declared noexcept" warning
|
||||||
|
|||||||
@ -415,7 +415,6 @@ public:
|
|||||||
auto& renderer = _testGetSet->_renderer;
|
auto& renderer = _testGetSet->_renderer;
|
||||||
auto& renderSettings = renderer._renderSettings;
|
auto& renderSettings = renderer._renderSettings;
|
||||||
auto adapter = std::make_unique<AdaptDispatch>(*_testGetSet, &renderer, renderSettings, _terminalInput);
|
auto adapter = std::make_unique<AdaptDispatch>(*_testGetSet, &renderer, renderSettings, _terminalInput);
|
||||||
adapter->SetVtChecksumReportSupport(true);
|
|
||||||
|
|
||||||
fSuccess = adapter.get() != nullptr;
|
fSuccess = adapter.get() != nullptr;
|
||||||
if (fSuccess)
|
if (fSuccess)
|
||||||
@ -1737,11 +1736,15 @@ public:
|
|||||||
Log::Comment(L"Test 1: Verify normal response.");
|
Log::Comment(L"Test 1: Verify normal response.");
|
||||||
_testGetSet->PrepData();
|
_testGetSet->PrepData();
|
||||||
_pDispatch->DeviceAttributes();
|
_pDispatch->DeviceAttributes();
|
||||||
|
_testGetSet->ValidateInputEvent(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42;52c");
|
||||||
|
|
||||||
auto pwszExpectedResponse = L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42c";
|
Log::Comment(L"Test 2: Verify response with clipboard disabled.");
|
||||||
_testGetSet->ValidateInputEvent(pwszExpectedResponse);
|
_testGetSet->PrepData();
|
||||||
|
_pDispatch->SetOptionalFeatures({});
|
||||||
|
_pDispatch->DeviceAttributes();
|
||||||
|
_testGetSet->ValidateInputEvent(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42c");
|
||||||
|
|
||||||
Log::Comment(L"Test 2: Verify failure when ReturnResponse doesn't work.");
|
Log::Comment(L"Test 3: Verify failure when ReturnResponse doesn't work.");
|
||||||
_testGetSet->PrepData();
|
_testGetSet->PrepData();
|
||||||
_testGetSet->_returnResponseResult = FALSE;
|
_testGetSet->_returnResponseResult = FALSE;
|
||||||
|
|
||||||
@ -2187,6 +2190,8 @@ public:
|
|||||||
|
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
|
_pDispatch->SetOptionalFeatures(ITermDispatch::OptionalFeature::ChecksumReport);
|
||||||
|
|
||||||
Log::Comment(L"Test 1: ASCII characters");
|
Log::Comment(L"Test 1: ASCII characters");
|
||||||
outputText(L"A"sv);
|
outputText(L"A"sv);
|
||||||
verifyChecksumReport(L"FF4F");
|
verifyChecksumReport(L"FF4F");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user