-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for OSC 52 (copy-to-clipboard) #5823
Changes from 1 commit
e4fe3fc
946ac27
0fa22cb
dcac598
1e462be
559f7fc
644ba34
e8eb5ef
91a3843
2c9c297
3b16808
83d6700
5d8a07b
56719e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,17 @@ | |
|
||
#include "precomp.h" | ||
|
||
#include <winrt/Windows.Security.Cryptography.h> | ||
#include <winrt/Windows.Storage.Streams.h> | ||
|
||
#include "stateMachine.hpp" | ||
#include "OutputStateMachineEngine.hpp" | ||
|
||
#include "ascii.hpp" | ||
using namespace Microsoft::Console; | ||
using namespace Microsoft::Console::VirtualTerminal; | ||
using namespace winrt::Windows::Security::Cryptography; | ||
using namespace winrt::Windows::Storage::Streams; | ||
|
||
// takes ownership of pDispatch | ||
OutputStateMachineEngine::OutputStateMachineEngine(std::unique_ptr<ITermDispatch> pDispatch) : | ||
|
@@ -726,7 +731,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, | |
{ | ||
bool success = false; | ||
std::wstring title; | ||
std::wstring copyContent; | ||
std::wstring setClipboardContent; | ||
bool queryClipboard = false; | ||
size_t tableIndex = 0; | ||
DWORD color = 0; | ||
|
||
|
@@ -735,7 +741,7 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, | |
case OscActionCodes::SetIconAndWindowTitle: | ||
case OscActionCodes::SetWindowIcon: | ||
case OscActionCodes::SetWindowTitle: | ||
success = _GetOscString(string, title); | ||
success = _GetOscTitle(string, title); | ||
break; | ||
case OscActionCodes::SetColor: | ||
success = _GetOscSetColorTable(string, tableIndex, color); | ||
|
@@ -745,8 +751,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, | |
case OscActionCodes::SetCursorColor: | ||
success = _GetOscSetColor(string, color); | ||
break; | ||
case OscActionCodes::CopyToClipboard: | ||
success = _GetOscString(string, copyContent); | ||
case OscActionCodes::SetClipboard: | ||
success = _GetOscSetClipboard(string, setClipboardContent, queryClipboard); | ||
break; | ||
case OscActionCodes::ResetCursorColor: | ||
// the console uses 0xffffffff as an "invalid color" value | ||
|
@@ -784,8 +790,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, | |
success = _dispatch->SetCursorColor(color); | ||
TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCSCC); | ||
break; | ||
case OscActionCodes::CopyToClipboard: | ||
success = _dispatch->CopyToClipboard(copyContent); | ||
case OscActionCodes::SetClipboard: | ||
if (!queryClipboard) | ||
{ | ||
success = _dispatch->SetClipboard(setClipboardContent); | ||
} | ||
TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCSCC); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be the wrong TermTelemetry code! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked http://inwap.com/pdp10/ansicode.txt to find a proper name for that code, but failed. So I named it as |
||
break; | ||
case OscActionCodes::ResetCursorColor: | ||
|
@@ -1197,16 +1206,16 @@ bool OutputStateMachineEngine::_VerifyDeviceAttributesParams(const std::basic_st | |
// Routine Description: | ||
// - Null terminates, then returns, the string that we've collected as part of the OSC string. | ||
// Arguments: | ||
// - inString - Osc String input. | ||
// - outString - Where to place the Osc String. | ||
// - string - Osc String input | ||
// - title - Where to place the Osc String to use as a title. | ||
// Return Value: | ||
// - True if there was a string to output. | ||
bool OutputStateMachineEngine::_GetOscString(const std::wstring_view inString, | ||
std::wstring& outString) const | ||
// - True if there was a title to output. (a title with length=0 is still valid) | ||
bool OutputStateMachineEngine::_GetOscTitle(const std::wstring_view string, | ||
std::wstring& title) const | ||
{ | ||
outString = inString; | ||
title = string; | ||
|
||
return !inString.empty(); | ||
return !string.empty(); | ||
} | ||
|
||
// Routine Description: | ||
|
@@ -1739,6 +1748,47 @@ bool OutputStateMachineEngine::_GetRepeatCount(std::basic_string_view<size_t> pa | |
return success; | ||
} | ||
|
||
// Routine Description: | ||
// - Parse OscSetClipboard parameters with the format `Pc;Pd`. Currently the first parameter `Pc` is | ||
// ignored. The second parameter `Pd` should be a valid base64 string or character `?`. | ||
// Arguments: | ||
// - string - Osc String input. | ||
// - content - Content to set to clipboard. | ||
// - queryClipboard - Whether to get clipboard content and return it to terminal with base64 encoded. | ||
// Return Value: | ||
// - True if there was a valid base64 string or the passed parameter was `?`. | ||
bool OutputStateMachineEngine::_GetOscSetClipboard(const std::wstring_view string, | ||
std::wstring& content, | ||
bool& queryClipboard) const noexcept | ||
{ | ||
bool success = false; | ||
size_t pos = string.find(';'); | ||
if (pos != std::wstring_view::npos) | ||
{ | ||
std::wstring_view substr = string.substr(pos + 1); | ||
if (substr == L"?") | ||
{ | ||
queryClipboard = true; | ||
success = true; | ||
} | ||
else | ||
{ | ||
try | ||
{ | ||
auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::hstring(substr)); | ||
auto reader = DataReader::FromBuffer(buffer); | ||
content = reader.ReadString(buffer.Length()); | ||
success = true; | ||
} | ||
catch (...) | ||
zadjii-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
} | ||
} | ||
} | ||
|
||
return success; | ||
} | ||
|
||
// Method Description: | ||
// - Clears our last stored character. The last stored character is the last | ||
// graphical character we printed, which is reset if any other action is | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for naming consistency (when we inevitably get a tool that parses these comments)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Which is in the works back on the first page of pull requests :P)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.