As requested I am providing both an example for writing URIs to clipboard and getting URIs from clipboard. These examples are basically command line programs that get / set the clipboard immediately. In an actual GUI application you would probably react to a button press or, to catch CtrlC / CtrlV events, use Gtk.Widget.add_events()
and get / set the clipboard when handling the Gtk.Widget.event
signal.
获取剪贴板
您可以使用以下命令从 X11 剪贴板请求 URIGtk.Clipboard.request_uris ()
。此函数采用回调,一旦 URI 可用,就会调用该回调。
Example:
public void main (string[] args) {
Gtk.init (ref args);
Gdk.Display display = Gdk.Display.get_default ();
Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);
clipboard.request_uris (recieved_func);
Gtk.main ();
}
/* Gtk.ClipboardURIRecievedFunc */
private void recieved_func (Gtk.Clipboard clipboard, string[] uris) {
foreach (var uri in uris) {
print (uri + "\n");
}
Gtk.main_quit ();
}
编译用valac clipget.vala --pkg=gtk+-3.0
设置剪贴板
Theory:
来自Qt4 文档 http://doc.qt.io/archives/qt-4.8/qclipboard.html:
由于没有标准方法可以在之间复制和粘贴文件
X11 上的应用程序,目前有各种 MIME 类型和约定
正在使用。例如,Nautilus 希望提供的文件带有
x-special/gnome-copied-files MIME 类型,数据以
剪切/复制操作、换行符和文件的 URL。
Gtk.Clipboard
不预先实现设置剪贴板以复制/剪切文件。正如你所说,没有这样的Gtk.Clipboard.set_uris()
.
相反,您应该通过提供回调来设置剪贴板,X11 在收到请求后即可获取剪贴板内容。
这些是所需的步骤:
创建一堆Gtk.TargetEntry
指定您的应用程序可以处理哪些剪贴板协议。你需要处理协议text/uri-list
, x-special/gnome-copied-files
and UTF8_STRING
. Each TargetEntry
由其标识info
字段,因此该数字应该是唯一的(请参阅enum ClipboardProtocol
在下面的例子中)
实现该类型的方法Gtk.ClipboardGetFunc
。此方法应填充Gtk.SelectionData
与要复制/剪切的文件路径一起传递的对象。检查是否有info
参数根据指定的协议设置 SelectionData 参数。
使用以下命令注册回调和 X11 实现的协议Gtk.Clipboard.set_with_owner
or Gtk.Clipboard.set_with_data
Example:
enum ClipboardProtocol {
TEXT_URI_LIST,
GNOME_COPIED_FILES,
UTF8_STRING
}
public void main (string[] args) {
Gtk.init (ref args);
Gdk.Display display = Gdk.Display.get_default ();
Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);
var clipboard_targets = new Gtk.TargetEntry[3];
Gtk.TargetEntry target_entry = { "text/uri-list", 0, ClipboardProtocol.TEXT_URI_LIST };
clipboard_targets[0] = target_entry;
target_entry = { "x-special/gnome-copied-files", 0, ClipboardProtocol.GNOME_COPIED_FILES };
clipboard_targets[1] = target_entry;
target_entry = { "UTF8_STRING", 0, ClipboardProtocol.UTF8_STRING };
clipboard_targets[2] = target_entry;
var owner = new Object ();
var rc = clipboard.set_with_owner (
clipboard_targets,
get_func,
clear_func,
owner
);
assert (rc);
clipboard.store ();
Gtk.main ();
}
/* Gtk.ClipboardGetFunc */
private void get_func (
Gtk.Clipboard clipboard,
Gtk.SelectionData selection_data,
uint info,
void* user_data_or_owner
) {
print ("GET FUNC!\n");
File my_file = File.new_for_path ("/home/lukas/tmp/test.txt");
File my_2nd_file = File.new_for_path ("/home/lukas/tmp/test2.txt");
File[] files = { my_file, my_2nd_file };
switch (info) {
case ClipboardProtocol.TEXT_URI_LIST:
string[] uris = {};
foreach (var file in files) {
uris += file.get_uri ();
}
selection_data.set_uris (uris);
break;
case ClipboardProtocol.GNOME_COPIED_FILES:
var prefix = "copy\n";
//var prefix = "cut\n";
/* use one of the above */
var builder = new StringBuilder (prefix);
for (int i = 0; i < files.length; i++) {
builder.append (files[i].get_uri ());
/* dont put the newline if this is the last file */
if (i != files.length - 1)
builder.append_c ('\n');
}
selection_data.set (
selection_data.get_target (),
8,
builder.data
);
break;
case ClipboardProtocol.UTF8_STRING:
var builder = new StringBuilder ();
foreach (var file in files) {
builder.append (file.get_parse_name ());
}
builder.append_c ('\n');
selection_data.set_text (builder.str, -1);
break;
default:
assert_not_reached ();
}
Gtk.main_quit ();
}
/* Gtk.ClipboardClearFunc */
private void clear_func (Gtk.Clipboard clipboard, void* data) {
;
}
编译用valac clipset.vala --pkg=gtk+-3.0
一些注意事项:
在我的例子中,我只能测试x-special/gnome-copied-files
因为我目前只安装了 Nautilus。我改编了 Thunar 源代码中的所有协议(请参阅下面的源代码),但它们可能仍然需要故障排除*
如果您不想自己实现这一点,您也可以使用 xclip 命令行工具:https://askubuntu.com/a/210428/345569 https://askubuntu.com/a/210428/345569然而,恕我直言,你自己实现这个会更优雅一些。
Sources:
- 来自 Ubuntu 论坛的文章:https://ubuntuforums.org/archive/index.php/t-2135919.html https://ubuntuforums.org/archive/index.php/t-2135919.html
- Thunar 源代码(特别是 thunar/thunar/thunar-clipboard-manager.c):https://github.com/xfce-mirror/thunar/blob/3de231d2dec33ca48b73391386d442231baace3e/thunar/thunar-clipboard-manager.c https://github.com/xfce-mirror/thunar/blob/3de231d2dec33ca48b73391386d442231baace3e/thunar/thunar-clipboard-manager.c
- Qt4文档:http://doc.qt.io/archives/qt-4.8/qclipboard.html http://doc.qt.io/archives/qt-4.8/qclipboard.html