linux - 处理接收 X11 SelectionNotify 事件,xev 不显示该事件;为什么会这样?

标签 linux clipboard x11

在一个终端中,我正在启动一个看起来像这样的过程......

        // ...
        while(true) {
            XNextEvent(xw.dpy, &ev);
            if(XFilterEvent(&ev, None))
                continue;
            printf("type: %d\n", ev.type);
            if(handler[ev.type])
                (handler[ev.type])(&ev);
        }
       // ...

然后我用xev来监控这个过程

xev -i <window>

然后我打开 Chrome,复制一些文本,然后聚焦第一个进程并执行 Shift+Insert。这导致文本被粘贴到第一个进程中,我们看到它打印“31”(/usr/include/X11/X.h),表示 SelectionNotify。另一方面,xev 不显示 SelectionNotify 事件,但它确实显示了第一个进程未显示的 PropertyNotify 事件。 PropertyNotify 事件更新 PRIMARY 属性。

复制/粘贴算法应该是这样工作的:http://en.wikipedia.org/wiki/X_Window_selection#Selections

想法?

最佳答案

来自 xev 联机帮助页,“Xev ... 要求 X 服务器在窗口发生任何事情时向其发送事件(例如移动、调整大小、输入、单击等)。您还可以附加它到现有窗口。这对于查看导致事件发生的原因并显示它们包含的信息很有用;“

显然 xev 没有得到它附加到的窗口正在得到的实际事件。

xev 代码看起来像这样

case 'i':           /* -id */
    if (++i >= argc) usage ();
        sscanf(argv[i], "0x%lx", &w);
    if (!w)
        sscanf(argv[i], "%lu", &w);
    if (!w)
        usage ();
    continue;

// ...

if (w) {
    XGetWindowAttributes(dpy, w, &wattr);
    if (wattr.all_event_masks & ButtonPressMask)
        attr.event_mask &= ~ButtonPressMask;
    attr.event_mask &= ~SubstructureRedirectMask;
    XSelectInput(dpy, w, attr.event_mask);
} else {
    // ...
}

//...

for (done = 0; !done; ) {
    XEvent event;
    XNextEvent (dpy, &event);

    switch (event.type) {
    // ...
    }
}

大概 XSelectInput 和 XNextEvent 在进程“附加”到某个窗口并且该窗口获得 SelectionNotify 事件时正在做一些奇怪的事情。

“不幸的是,如果你要求 xev 跟踪它不拥有的窗口上的事件(-id 模式),xev 并不是万无一失的。它通过使用 Xlib 的 XSelectInput() 函数请求它们来接收这些事件。这种技术有三个主要限制:
1. 抓取 - 如果一个客户端激活服务器、指针或键盘抓取,那么向所有其他客户端的事件报告将受到影响。 xev 将无法报告某些(或全部)事件,即使激活抓取的客户端可能正在接收它们。
2. 不可屏蔽事件 - X 协议(protocol)不允许将某些事件报告给创建事件窗口的客户端以外的客户端。这些事件中的大多数都与选择有关。
3.重定向事件——X协议(protocol)只允许一个客户端请求某些事件。如果另一个客户端正在接收它们,xev 将无法接收它们。这些事件包括窗口管理器重定向事件(例如,根窗口上的子结构通知)和隐式被动抓取事件(例如,鼠标按钮按下)。”( http://www.rahul.net/kenton/events.html#LimitationsOf )

关于linux - 处理接收 X11 SelectionNotify 事件,xev 不显示该事件;为什么会这样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28578220/

相关文章:

c# - Mono 和 Array.Sort

java - JBoss 配置

macos - 在 OS X 中从剪贴板获取文件路径

linux - 如何使用 Xlib 恢复窗口?

c++ - 如何使用 shell 脚本运行一个进程两次?

java - 在具有 maven 依赖项的 linux 命令中运行 java 文件

C++:如何将多个对象复制到剪贴板并在之后提取它们?

javascript - 单击 JS 复制到剪贴板

linux - 在 Linux Mint LMDE 上安装 Chez Scheme 9.4

ssh - 转发 X11 失败 : Network error: Connection refused