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

X11剪贴板开发:调用XSetSelectionOwner后target原子是否恒为TARGETS?

X11剪贴板:调用XSetSelectionOwner后收到的XSelectionRequestEvent的target原子是否始终为"TARGETS"?

我正在X11应用中实现剪贴板处理逻辑,复制操作的第一步是调用XSetSelectionOwner函数,代码如下:

Atom clipboardAtom = XInternAtom(display, "CLIPBOARD", False);
XSetSelectionOwner(display, clipboardAtom, clipboardWin, CurrentTime);

执行该操作后,我收到了XSelectionRequestEvent事件,该事件包含target原子。请问调用XSetSelectionOwner后,该事件的target原子是否始终为"TARGETS"原子?相关处理代码示例如下:

Atom targetsAtom = XInternAtom(display, "TARGETS", False);
//handling XSelectionRequestEvent after calling XSetSelectionOwner
if(event.xselectionrequest.target == targetsAtom)
{
}

答案:不是始终为"TARGETS"原子

当你的应用通过XSetSelectionOwner成为剪贴板所有者后,其他应用(比如发起粘贴操作的程序)会向你发送XSelectionRequestEvent,请求的target原子完全取决于对方的需求:

  • 有些应用会先请求"TARGETS",目的是获取你的应用支持的所有剪贴板数据格式列表;
  • 但也有应用会直接请求特定格式,比如文本格式"TEXT"、图片格式"IMAGE/png"等,这时候事件的target就是对应格式的原子。

因此你的处理逻辑不能只针对"TARGETS"做判断,需要覆盖多种场景:

  1. 若target是"TARGETS":返回你应用支持的所有格式原子数组;
  2. 若target是你支持的具体格式:返回对应格式的剪贴板数据;
  3. 若target是你不支持的格式:将对应的property设为None或者返回空数据。

修正后的处理代码示例

Atom targetsAtom = XInternAtom(display, "TARGETS", False);
Atom textAtom = XInternAtom(display, "TEXT", False);
// 定义支持的格式数组
Atom supportedAtoms[] = {targetsAtom, textAtom};

// 处理XSelectionRequestEvent
switch(event.xselectionrequest.target) {
    case targetsAtom:
        // 返回支持的格式列表
        XChangeProperty(display, event.xselectionrequest.requestor,
                        event.xselectionrequest.property, XA_ATOM, 32,
                        PropModeReplace, (unsigned char*)supportedAtoms, 2);
        break;
    case textAtom:
        // 返回文本形式的剪贴板数据
        const char* clipText = "示例剪贴板文本";
        XChangeProperty(display, event.xselectionrequest.requestor,
                        event.xselectionrequest.property, textAtom, 8,
                        PropModeReplace, (unsigned char*)clipText, strlen(clipText));
        break;
    default:
        // 不支持的格式,清空对应property
        XChangeProperty(display, event.xselectionrequest.requestor,
                        event.xselectionrequest.property, None, 0,
                        PropModeReplace, NULL, 0);
        break;
}

// 发送回复事件给请求方
XSendEvent(display, event.xselectionrequest.requestor, False, 0,
           (XEvent*)&event.xselectionrequest);
XFlush(display);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:25:26