You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vala中向Gtk.Clipboard插入URI:粘贴重复调用get_func问题

解决Gtk.Clipboard粘贴时重复调用get_func覆盖数据的问题

你踩了Gtk.Clipboard.set_with_owner的一个常见坑——这个方法的get_func是按需提供数据的,而非一次性把数据写入剪贴板存储。也就是说,每次有程序请求剪贴板内容(比如按Ctrl+V),系统都会调用你的get_func来获取数据,而你原来的代码里每次都实时调用w.get_selected_file(),这就导致粘贴时拿到的是当前选中的文件,而非复制时选中的那个。

核心问题分析

你的get_func依赖的是窗口的实时选中状态,而不是复制时刻的状态。剪贴板本身不会保存你的数据,它只是在需要的时候向你索要,所以必须在复制操作发生时,把要复制的URI保存下来,后续get_func直接复用这个预存的数据即可。

修正后的实现步骤

  1. 先在你的Window类里添加一个成员变量,用来保存复制时刻的URI:
private string[]? copied_uris = null;
  1. 修改Ctrl+C的处理逻辑,复制时先保存当前选中的文件URI,再设置剪贴板:
// 处理Ctrl+C复制操作
copied_uris = { this.get_selected_file().get_uri() }; // 保存复制时刻的URI

// 定义剪贴板目标
var clipboard_targets = [
    new Gtk.TargetEntry("text/uri-list", 0, (int)ClipboardProtocol.TEXT_URI_LIST)
];

clipboard.set_with_owner(
    clipboard_targets,
    // get_func:当剪贴板需要数据时调用
    (clipboard, selection_data, info, user_data_or_owner) => {
        print("clipboard get_func called\n");
        if (copied_uris == null) return;
        
        switch (info) {
            case (int)ClipboardProtocol.TEXT_URI_LIST:
                print("Providing saved URIs: ");
                foreach (var uri in copied_uris) {
                    print(uri + "\n");
                }
                selection_data.set_uris(copied_uris);
                break;
        }
    },
    // owner_destroy_func:当剪贴板失去所有权时调用(可选)
    (clipboard, user_data_or_owner) => {
        // 清空保存的URI,避免无效数据残留
        copied_uris = null;
    },
    this // 将当前Window作为owner传递
);
  1. 粘贴逻辑可以保持不变,加个空值判断会更健壮:
// 处理Ctrl+V粘贴操作
print("\nCTRL V pressed\n");
clipboard.request_uris((clipboard, uris) => {
    if (uris == null) {
        print("No URIs available in clipboard\n");
        return;
    }
    foreach (string content in uris) {
        print("Try Pasting: ");
        print(content);
        print("\n");
    }
});

为什么这样能解决问题

现在get_func使用的是复制时刻保存的copied_uris,而非实时获取当前选中的文件。无论什么时候调用get_func(比如粘贴),都会返回你复制时的那个URI,不会被后续的选中状态改变覆盖。

另外,owner_destroy_func会在剪贴板失去所有权时(比如其他程序复制了内容)清空copied_uris,避免保存无效的旧数据。

内容的提问来源于stack exchange,提问作者Marcel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:27:54