Skip to content

Commit 32e69d7

Browse files
j4jamesDHowett
authored andcommitted
Indicate support for OSC 52 in the DA1 report (#19034)
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. `OSC 52` support was added to Windows Terminal in issue #5823, and to ConHost in issue #18949. 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). 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. - [x] Closes #19017 - [x] Tests added/passed (cherry picked from commit 00ee884) Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgbpe4k Service-Version: 1.22
1 parent 43f800d commit 32e69d7

File tree

7 files changed

+42
-19
lines changed

7 files changed

+42
-19
lines changed

src/cascadia/TerminalCore/Terminal.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
9393

9494
if (_stateMachine)
9595
{
96-
SetVtChecksumReportSupport(settings.AllowVtChecksumReport());
96+
SetOptionalFeatures(settings);
9797
}
9898

9999
_getTerminalInput().ForceDisableWin32InputMode(settings.ForceVTInput());
@@ -218,10 +218,13 @@ void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
218218
engine.Dispatch().SetCursorStyle(cursorStyle);
219219
}
220220

221-
void Terminal::SetVtChecksumReportSupport(const bool enabled)
221+
void Terminal::SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettings settings)
222222
{
223223
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
224-
engine.Dispatch().SetVtChecksumReportSupport(enabled);
224+
auto features = til::enumset<ITermDispatch::OptionalFeature>{};
225+
features.set(ITermDispatch::OptionalFeature::ChecksumReport, settings.AllowVtChecksumReport());
226+
features.set(ITermDispatch::OptionalFeature::ClipboardWrite, settings.AllowVtClipboardWrite());
227+
engine.Dispatch().SetOptionalFeatures(features);
225228
}
226229

227230
bool Terminal::IsXtermBracketedPasteModeEnabled() const noexcept

src/cascadia/TerminalCore/Terminal.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class Microsoft::Terminal::Core::Terminal final :
9494
void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance);
9595
void SetFontInfo(const FontInfo& fontInfo);
9696
void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle);
97-
void SetVtChecksumReportSupport(const bool enabled);
97+
void SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettings settings);
9898
bool IsXtermBracketedPasteModeEnabled() const noexcept;
9999
std::wstring_view GetWorkingDirectory() noexcept;
100100

src/terminal/adapter/ITermDispatch.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
2525
public:
2626
using StringHandler = std::function<bool(const wchar_t)>;
2727

28+
enum class OptionalFeature
29+
{
30+
ChecksumReport,
31+
ClipboardWrite,
32+
};
33+
2834
#pragma warning(push)
2935
#pragma warning(disable : 26432) // suppress rule of 5 violation on interface because tampering with this is fraught with peril
3036
virtual ~ITermDispatch() = 0;
@@ -132,7 +138,6 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
132138
virtual void ScreenAlignmentPattern() = 0; // DECALN
133139

134140
virtual void SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
135-
virtual void SetVtChecksumReportSupport(const bool enabled) = 0;
136141

137142
virtual void SetClipboard(wil::zwstring_view content) = 0; // OSCSetClipboard
138143

@@ -184,6 +189,8 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
184189
virtual StringHandler RestorePresentationState(const DispatchTypes::PresentationReportFormat format) = 0; // DECRSPS
185190

186191
virtual void PlaySounds(const VTParameters parameters) = 0; // DECPS
192+
193+
virtual void SetOptionalFeatures(const til::enumset<OptionalFeature> features) = 0;
187194
};
188195
inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() = default;
189196
#pragma warning(pop)

src/terminal/adapter/adaptDispatch.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,11 +1304,6 @@ void AdaptDispatch::SelectAttributeChangeExtent(const DispatchTypes::ChangeExten
13041304
}
13051305
}
13061306

1307-
void AdaptDispatch::SetVtChecksumReportSupport(const bool enabled) noexcept
1308-
{
1309-
_vtChecksumReportEnabled = enabled;
1310-
}
1311-
13121307
// Routine Description:
13131308
// - DECRQCRA - Computes and reports a checksum of the specified area of
13141309
// the buffer memory.
@@ -1325,7 +1320,7 @@ void AdaptDispatch::RequestChecksumRectangularArea(const VTInt id, const VTInt p
13251320
// If this feature is not enabled, we'll just report a zero checksum.
13261321
if constexpr (Feature_VtChecksumReport::IsEnabled())
13271322
{
1328-
if (_vtChecksumReportEnabled)
1323+
if (_optionalFeatures.test(OptionalFeature::ChecksumReport))
13291324
{
13301325
// If the page number is 0, then we're meant to return a checksum of all
13311326
// of the pages, but we have no need for that, so we'll just return 0.
@@ -1491,8 +1486,16 @@ void AdaptDispatch::DeviceAttributes()
14911486
// 28 = Rectangular area operations
14921487
// 32 = Text macros
14931488
// 42 = ISO Latin-2 character set
1489+
// 52 = Clipboard access
14941490

1495-
_api.ReturnResponse(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42c");
1491+
if (_optionalFeatures.test(OptionalFeature::ClipboardWrite))
1492+
{
1493+
_api.ReturnResponse(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42;52c");
1494+
}
1495+
else
1496+
{
1497+
_api.ReturnResponse(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42c");
1498+
}
14961499
}
14971500

14981501
// Routine Description:
@@ -4769,3 +4772,8 @@ void AdaptDispatch::PlaySounds(const VTParameters parameters)
47694772
_api.PlayMidiNote(noteNumber, noteNumber == 71 ? 0 : velocity, duration);
47704773
});
47714774
}
4775+
4776+
void AdaptDispatch::SetOptionalFeatures(const til::enumset<OptionalFeature> features) noexcept
4777+
{
4778+
_optionalFeatures = features;
4779+
}

src/terminal/adapter/adaptDispatch.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ namespace Microsoft::Console::VirtualTerminal
187187

188188
void PlaySounds(const VTParameters parameters) override; // DECPS
189189

190-
void SetVtChecksumReportSupport(const bool enabled) noexcept override;
190+
void SetOptionalFeatures(const til::enumset<OptionalFeature> features) noexcept override;
191191

192192
private:
193193
enum class Mode
@@ -308,7 +308,7 @@ namespace Microsoft::Console::VirtualTerminal
308308
std::unique_ptr<FontBuffer> _fontBuffer;
309309
std::shared_ptr<MacroBuffer> _macroBuffer;
310310
std::optional<unsigned int> _initialCodePage;
311-
bool _vtChecksumReportEnabled = false;
311+
til::enumset<OptionalFeature> _optionalFeatures = { OptionalFeature::ClipboardWrite };
312312

313313
// We have two instances of the saved cursor state, because we need
314314
// one for the main buffer (at index 0), and another for the alt buffer

src/terminal/adapter/termDispatch.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons
177177

178178
void PlaySounds(const VTParameters /*parameters*/) override{}; // DECPS
179179

180-
void SetVtChecksumReportSupport(const bool /*enabled*/) override{};
180+
void SetOptionalFeatures(const til::enumset<OptionalFeature> /*features*/) override{};
181181
};
182182

183183
#pragma warning(default : 26440) // Restore "can be declared noexcept" warning

src/terminal/adapter/ut_adapter/adapterTest.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,6 @@ class AdapterTest
405405
auto& renderer = _testGetSet->_renderer;
406406
auto& renderSettings = renderer._renderSettings;
407407
auto adapter = std::make_unique<AdaptDispatch>(*_testGetSet, &renderer, renderSettings, _terminalInput);
408-
adapter->SetVtChecksumReportSupport(true);
409408

410409
fSuccess = adapter.get() != nullptr;
411410
if (fSuccess)
@@ -1727,11 +1726,15 @@ class AdapterTest
17271726
Log::Comment(L"Test 1: Verify normal response.");
17281727
_testGetSet->PrepData();
17291728
_pDispatch->DeviceAttributes();
1729+
_testGetSet->ValidateInputEvent(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42;52c");
17301730

1731-
auto pwszExpectedResponse = L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42c";
1732-
_testGetSet->ValidateInputEvent(pwszExpectedResponse);
1731+
Log::Comment(L"Test 2: Verify response with clipboard disabled.");
1732+
_testGetSet->PrepData();
1733+
_pDispatch->SetOptionalFeatures({});
1734+
_pDispatch->DeviceAttributes();
1735+
_testGetSet->ValidateInputEvent(L"\x1b[?61;4;6;7;14;21;22;23;24;28;32;42c");
17331736

1734-
Log::Comment(L"Test 2: Verify failure when ReturnResponse doesn't work.");
1737+
Log::Comment(L"Test 3: Verify failure when ReturnResponse doesn't work.");
17351738
_testGetSet->PrepData();
17361739
_testGetSet->_returnResponseResult = FALSE;
17371740

@@ -2177,6 +2180,8 @@ class AdapterTest
21772180

21782181
using namespace std::string_view_literals;
21792182

2183+
_pDispatch->SetOptionalFeatures(ITermDispatch::OptionalFeature::ChecksumReport);
2184+
21802185
Log::Comment(L"Test 1: ASCII characters");
21812186
outputText(L"A"sv);
21822187
verifyChecksumReport(L"FF4F");

0 commit comments

Comments
 (0)