From d4dde314ffbc97cb3431e8803e8fb46ce36c2274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 28 Dec 2025 13:44:36 +0100 Subject: [PATCH] Use Primary Device Attributes to detect OSC-52 support Up until recently, there were no reliable way to detect if a terminal supported OSC-52 or not. A number or terminal emulators decided to remedy this by including '52' in their primary DA response. In short, the presence of 52 in the DA response means the terminal supports *writing* to the clipboard. Reading the clipboard is _usually_ supported, but not guaranteed. It should be noted that Emacs uses both the 'c' and 'p' parameters in OSC-52, to copy to either PRIMARY, or CLIPBOARD, while the specification only requires the terminal to implement 'c'. If a terminal doesn't support 'p', the OSC-52 request will be silently ignored. * lisp/term/xterm.el (xterm--init, xterm--primary-da-handler): Query primary device attributes for OSC-52 support. (Bug#80083) Copyright-paperwork-exempt: yes --- lisp/term/xterm.el | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index f173508d777..3300c2d83cc 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el @@ -822,6 +822,16 @@ Return the pasted text as a string." ;;(xterm--init-activate-get-selection) (xterm--init-activate-set-selection)))))) +(defun xterm--primary-da-handler () + ;; The reply should be: \e [ ? NUMBER1 ; ... ; NUMBER_N c + (let ((str (xterm--read-string ?c))) + (when (member "52" (split-string str ";" t)) + ;; Many modern terminals include 52 in their primary DA response, + ;; to indicate support for *writing* to the OS clipboard. The + ;; specification does not guarantee the clipboard can be read. See + ;; https://github.com/contour-terminal/vt-extensions/blob/master/clipboard-extension.md + (xterm--init-activate-set-selection)))) + (defvar xterm-query-timeout 2 "Seconds to wait for an answer from the terminal. Can be nil to mean \"no timeout\".") @@ -948,14 +958,18 @@ We run the first FUNCTION whose STRING matches the input events." (tty-set-up-initial-frame-faces) (if (eq xterm-extra-capabilities 'check) - ;; Try to find out the type of terminal by sending a "Secondary - ;; Device Attributes (DA)" query. - (xterm--query "\e[>0c" - ;; Some terminals (like macOS's Terminal.app) respond to - ;; this query as if it were a "Primary Device Attributes" - ;; query instead, so we should handle that too. - '(("\e[?" . xterm--version-handler) - ("\e[>" . xterm--version-handler))) + (progn + ;; Try to find out the type of terminal by sending a "Secondary + ;; Device Attributes (DA)" query. + (xterm--query "\e[>0c" + ;; Some terminals (like macOS's Terminal.app) respond to + ;; this query as if it were a "Primary Device Attributes" + ;; query instead, so we should handle that too. + '(("\e[?" . xterm--version-handler) + ("\e[>" . xterm--version-handler))) + ;; Check primary DA for OSC-52 support + (xterm--query "\e[c" + '(("\e[?" . xterm--primary-da-handler)))) (when (memq 'reportBackground xterm-extra-capabilities) (xterm--query "\e]11;?\e\\"