X11剪贴板如何处理多个数据格式?

46

也许你也有过这样的经历——有时候,当你从某个网页复制文本到你最喜爱的网络邮件客户端的富文本电子邮件草稿中时,你不喜欢被粘贴的片段有不同的字体/大小/重量...它似乎记住了风格(通常是选中的图片)。那么,如果你将相同的东西粘贴到像Vim这样的文本编辑器中,为什么没有HTML,只有纯文本呢?

alt text

看起来剪贴板以各种格式维护所选数据。如何以任何一种格式访问数据(通过编程或某些实用程序)?X11剪贴板是如何工作的?


我有一个想法已经有一段时间了,那就是浏览器也会维护它们自己的剪贴板,但这意味着它只能在该浏览器应用程序进程内工作,而这并不是事实。 - mykhal
如果您想从命令行查看MIME类型,请参考以下链接:https://unix.stackexchange.com/questions/163081/application-that-allows-to-show-clipboard-contents-and-its-mime-type - aksh1618
2个回答

39

你从中复制的应用程序会展示它可以提供的格式(大多数由MIME类型标识)。你粘贴到的应用程序必须选择其首选格式并从源应用程序请求该格式。

你可能无法看到所有样式信息的原因是,应用程序不支持包含样式信息的常见格式。

你还可能遇到问题,因为应用程序可能尝试粘贴HTML,但实际上无法处理所有HTML。或者应用程序可能存在漏洞,或者可能无法达成对特定MIME类型的真正意义的共识。

当然,几乎所有应用程序都可以复制和粘贴纯文本,但除此之外就不确定了。如果你没有得到似乎有意义的内容,你可以向其中一个应用程序提交错误报告。

你可能会注意到,如果你退出正在复制的应用程序,你将无法再次粘贴。(除非你运行一个“剪贴板管理器”或类似工具。)这是因为在目标应用程序请求要粘贴的格式之前,没有数据实际离开源应用程序。

有“剪贴板管理器”会立即请求任何时候复制的数据并存储该数据,以便在源应用程序退出后粘贴,但它们也有缺点(如果数据很大或以10种格式提供怎么办等)。

以下Python代码将显示当前复制数据的可用格式,如果你安装了pygtk。该应用程序显示ctrl+c复制的数据,而不是中键单击复制的彩蛋。(参见http://freedesktop.org/wiki/Specifications/ClipboardsWiki

#!/usr/bin/python

import gtk;
clipboard = gtk.clipboard_get()
print("Current clipboard offers formats: " + str(clipboard.wait_for_targets()))

非常感谢提供的有用信息(我曾担心答案会包含C代码的数行)。现在我只想知道为什么从Firefox复制的text/html数据(UTF-8网页)要使用UTF-16LE编码。 - mykhal
有一个后续问题:http://askubuntu.com/questions/427704/how-can-i-edit-the-source-of-html-in-the-clipboard。有没有关于如何从剪贴板中获取富文本的实际尝试的提示?我太懒了,不想弄清楚如何创建缓冲区。 - Adam Monsen
我无法让当前的代码工作。这个可以。我还将输出分成多行,以便更易读。请随意在您的答案中使用它 :) - Hi-Angel
4
我写了一个小工具,可以检索所有可用格式,然后以文本形式打印它们的内容。https://github.com/Hi-Angel/scripts/blob/master/print_clipboard_content.py - Hi-Angel
3
使用 xclip 列出目标(格式)的一行代码:xclip -selection clipboard -target TARGETS -out - Vladimir Panteleev

4

由于PyGTK的API更改,Havoc P的回答中显示当前剪贴板格式的代码已经过时。以下是更新后的一行代码:

python -c 'import gi; gi.require_version("Gtk", "3.0"); from gi.repository import Gtk, Gdk; print(*Gtk.Clipboard.get(Gdk.atom_intern("CLIPBOARD", True)).wait_for_targets()[1], sep = "\n")'

在Arch Linux中,您可以使用sudo pacman -S pygtk安装PyGTK。

以下是一些示例。

来自Chrome的文本:

TIMESTAMP
TARGETS
SAVE_TARGETS
MULTIPLE
STRING
UTF8_STRING
TEXT
text/html
text/plain

来自Gnome终端的文本:

TIMESTAMP
TARGETS
MULTIPLE
SAVE_TARGETS
UTF8_STRING
COMPOUND_TEXT
TEXT
STRING
text/plain;charset=utf-8
text/plain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接