You need to enable JavaScript to run this app. X11平台参考CopyQ源码实现剪贴板内容粘贴到活动窗口问题求助
优惠活动
大模型
产品
解决方案
定价
更多

X11平台参考CopyQ源码实现剪贴板内容粘贴到活动窗口问题求助

X11剪贴板自动粘贴异常排查与修复方案

1 修复代码硬错误

现有代码存在几个明显的逻辑错误,是导致大部分窗口无法响应的核心原因:

  • 移除sendKeyPress()函数中无意义的waitMs(5000)调用:5秒的超长等待会导致大量窗口的焦点状态超时失效,替换为10~50ms的短等待即可。
  • 修复按键事件掩码错误:释放按键时错误传递了KeyPressMask,大部分应用无法识别该非法事件,修改如下:
// 原错误代码
event.type = KeyRelease;
XSendEvent(display, window, True, KeyPressMask, xev);
// 修复后代码
event.type = KeyRelease;
XSendEvent(display, window, False, KeyReleaseMask, xev);
  • 验证XSetInputFocus调用结果:X11提供XGetInputFocus接口可以直接查询当前焦点窗口,确认是否设置成功:
// 焦点验证示例,放在XSetInputFocus调用之后
Window focused_win;
int revert_to;
XGetInputFocus(display, &focused_win, &revert_to);
if (focused_win != m_window) {
    qDebug() << "焦点设置失败,当前焦点窗口ID:" << focused_win;
}

2 优化焦点激活逻辑

现代窗口管理器对窗口主动激活请求有严格的权限限制,调整以下逻辑提升激活成功率:

  • 修改_NET_ACTIVE_WINDOW请求优先级:将e.xclient.data.l[0]的值从2改为0,标记为用户主动触发的激活请求,窗口管理器放行概率更高。
  • 激活前查找顶层窗口:你传入的lastWindow可能是输入控件类的子窗口,部分场景下直接激活子窗口会被拦截,需要递归查找父窗口直到找到顶层窗口再激活。
  • 隐藏自身窗口后增加短等待:this->hide()调用后加10~30ms的等待,确保窗口管理器处理完你的窗口隐藏事件,再激活目标窗口避免焦点被抢。

3 提升粘贴兼容性

不同应用支持的粘贴快捷键不一致,补充两种常用粘贴快捷键的发送逻辑:

void X11PlatformWindow::pasteClipboard()
{
    sendKeyPress(XK_Control_L, XK_v);
    sendKeyPress(XK_Shift_L, XK_Insert);
}

4 高兼容备选方案:使用XTest扩展

大部分应用会拦截XSendEvent发送的伪造事件,改用XTest扩展模拟全局硬件按键,兼容性更强:

// 替换原有simulateKeyPress实现
void simulateKeyPress(Display *display, unsigned int modifiers, unsigned int key)
{
    KeyCode keycode = XKeysymToKeycode(display, key);
    // 按下修饰键
    if (modifiers & ControlMask) 
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Control_L), True, 0);
    if (modifiers & ShiftMask) 
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Shift_L), True, 0);
    // 按下+释放目标键
    XTestFakeKeyEvent(display, keycode, True, 0);
    XTestFakeKeyEvent(display, keycode, False, 0);
    // 释放修饰键
    if (modifiers & ShiftMask) 
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Shift_L), False, 0);
    if (modifiers & ControlMask) 
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Control_L), False, 0);
    XSync(display, False);
}

使用该方案需要在编译参数中加入-lXtst,同时开启HAS_X11TEST宏定义。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 04:12:09