Skip to content

Add Binary Paste Mode (DEC mode 2033) for image/binary clipboard paste#1898

Open
christianparpart wants to merge 1 commit intomasterfrom
feature/binary-paste
Open

Add Binary Paste Mode (DEC mode 2033) for image/binary clipboard paste#1898
christianparpart wants to merge 1 commit intomasterfrom
feature/binary-paste

Conversation

@christianparpart
Copy link
Member

@christianparpart christianparpart commented Feb 23, 2026

protocol extension

Introduces DEC private mode 2033 that lets terminal applications receive binary clipboard data (e.g., images) via DCS sequences with MIME type metadata and base64 encoding. Feature detection uses DECRQM (CSI ? 2033 $ p), which cleanly distinguishes "supported but disabled" (Ps=2) from "not recognized" (Ps=0).

notes

  • I explicitly decided against chunking, for simplicity
  • obviously, one could use this also for sending clear text with mime text/plain. This is not prohibited. Then it's text with a mime type, whereas paste / bracketed paste can only be used for clear text, binary paste can send any data (text as well as binary).

checklist

  • consider extending it to allow the client app to request the accepted mime types

@github-actions github-actions bot added documentation Improvements or additions to documentation VT: Backend Virtual Terminal Backend (libterminal API) frontend Contour Terminal Emulator (GUI frontend) test Unit tests labels Feb 23, 2026
@github-actions github-actions bot added the CI GitHub Actions & CI label Feb 23, 2026
@christianparpart christianparpart marked this pull request as draft February 23, 2026 01:34
@christianparpart christianparpart force-pushed the feature/binary-paste branch 2 times, most recently from 42f5493 to 675f366 Compare February 23, 2026 08:54
@christianparpart christianparpart marked this pull request as ready for review February 23, 2026 09:07
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces Binary Paste Mode (DEC mode 2033), a terminal protocol extension that enables terminal applications to receive binary clipboard data (such as images) via DCS sequences with MIME type metadata and base64 encoding. The implementation includes feature detection via DECRQM, allowing applications to distinguish between "supported but disabled" and "not recognized" states.

Changes:

  • Added DEC private mode 2033 with DCS-based sub-command architecture for binary data delivery ('d') and MIME preference configuration ('c')
  • Extended sequence parameter type from uint16_t to uint32_t to support larger binary payload sizes
  • Implemented clipboard handling with size limits (10 MB hard limit, 5 MB soft limit requiring user permission) and MIME type priority matching

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vtbackend/primitives.h Added BinaryPaste DECMode enum (2033) with conversion functions
src/vtbackend/Sequence.h Changed parameter storage from uint16_t to uint32_t to support larger values
src/vtbackend/Terminal.h Added API for binary paste mode, MIME preferences, and default MIME types
src/vtbackend/Terminal.cpp Implemented mode handlers, preference management, and reset behavior
src/vtbackend/InputGenerator.h/cpp Added generateBinaryPaste for DCS sequence generation with base64 encoding
src/vtbackend/Screen.h/cpp Added hookBinaryPaste for parsing incoming MIME preference configuration
src/vtbackend/Functions.h Defined BINARYPASTE DCS function with sub-command architecture
src/contour/TerminalSession.h/cpp Integrated clipboard MIME type detection, size validation, and permission handling
src/vtbackend/BinaryPaste_test.cpp Comprehensive test suite covering mode control, data delivery, and MIME configuration
docs/vt-extensions/binary-paste.md Complete protocol specification with examples and adoption state tracking
examples/watch-clipboard-paste.cpp Reference implementation demonstrating binary paste mode usage
CMakeLists.txt, mkdocs.yml, metainfo.xml Build configuration, documentation index, and release notes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Introduce a new VT protocol extension that allows terminal applications to
receive binary clipboard data (e.g., images) with MIME type metadata via
DCS sequences. Applications opt in via DECSET 2033; feature detection
uses DECRQM (CSI ? 2033 $ p) to distinguish "supported but disabled"
from "not supported".

Protocol: DCS 2033 ; <size> b <mime-type> ; <base64-data> ST

- DECMode 2033: opt-in mode with standard DECSET/DECRST/DECRQM support
- InputGenerator::generateBinaryPaste() produces DCS binary paste sequences
- Terminal::sendBinaryPaste() routes binary data through the input pipeline
- TerminalSession::pasteFromClipboard() inspects clipboard MIME types when
  mode is enabled, with priority: png > jpeg > gif > bmp > svg+xml
- Size limits: 10 MB hard, 5 MB soft (user permission prompt)
- Size validation: decoded payload must match declared Ps parameter
- VT sequence parameters widened from uint16_t to uint32_t to support
  payload sizes beyond 64 KB (max ~4 GB)
- 7 E2E tests covering mode control, DECRQM, DCS generation, and reset
- VT extension spec at docs/vt-extensions/binary-paste.md with adoption table
- Example app: examples/watch-clipboard-paste.cpp

Signed-off-by: Christian Parpart <christian@parpart.family>
Copy link
Member

@Yaraslaut Yaraslaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments, otherwise great addition

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we put it inside https://github.com/contour-terminal/vt-extensions/ as well ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah absolutely

Comment on lines +829 to +834
if (!appPrefs.empty())
for (auto const& mime: appPrefs)
mimeTypesToTry.emplace_back(mime);
else
for (auto const& mime: vtbackend::Terminal::DefaultBinaryPasteMimeTypes)
mimeTypesToTry.emplace_back(mime);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add brackets for every scope you add

auto const data = md->data(qMime);

// 10 MB hard limit for binary paste
if (data.size() > 10 * 1024 * 1024)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have it as constexpr variable

}

// 5 MB soft limit: request user permission
if (data.size() > 5 * 1024 * 1024)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also constexpr variable

}

auto const dataSpan = std::span<uint8_t const>(
reinterpret_cast<uint8_t const*>(data.constData()), static_cast<size_t>(data.size()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, i am slightly confused about the static cast for the size function, do we need it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI GitHub Actions & CI documentation Improvements or additions to documentation frontend Contour Terminal Emulator (GUI frontend) test Unit tests VT: Backend Virtual Terminal Backend (libterminal API)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants