进程接收X11 SelectionNotify事件,xev不显示事件;为什么会这样?

时间:2015-02-18 07:28:26

标签: 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

思想?

1 个答案:

答案 0 :(得分:2)

在xev手册页中,&#34; Xev ...要求X服务器在窗口发生任何事情时发送事件(例如它被移动,调整大小,输入,点击等)。您还可以将其附加到现有窗口。它有助于查看导致事件发生的原因并显示它们包含的信息; &#34;

显然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) {
    // ...
    }
}

当一个进程附加&#39;时,假设XSelectInput和XNextEvent正在做一些奇怪的事情。某个窗口,该窗口获取SelectionNotify事件。

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