问题 X11:我如何真正抓住鼠标指针?


我在Xlib中实现了一个水平分割器小部件。当用户点击并拖动分割条时,我试图抓住鼠标(这样用户就可以动态移动分割,从而调整分割条两侧的窗口大小)。

我用过 XGrabPointer() 在收到左键单击后,希望所有未来的鼠标移动(拖动)都将转移到拆分器窗口,直到释放左键。

不幸的是,它似乎并没有像那样工作。如果用户拖得太快并且鼠标指针进入分割两侧的一个窗口,则MotionEvent消息将转移到该(子)窗口而不是分割器窗口。

我做错了什么?我的 XGrabPointer() 电话如下:

::XGrabPointer(mDisplay, window, True,
               ButtonPressMask |
                 ButtonReleaseMask |
                 PointerMotionMask |
                 FocusChangeMask |
                 EnterWindowMask |
                  LeaveWindowMask,
               GrabModeAsync,
               GrabModeAsync,
               RootWindow(mDisplay, DefaultScreen(mDisplay)),
               None,
               CurrentTime);

10565
2018-05-08 04:43


起源



答案:


我几乎不好意思承认这一点,但答案结果就像将第三个参数(owner_events)从True更改为False一样简单。

来自 tronche.com上的Xlib教程/参考

如果owner_events为False,则会针对grab_window报告所有生成的指针事件,并且仅在event_mask选择时报告。如果owner_events为True,并且通常会将生成的指针事件报告给此客户端,则会照常报告。否则,将报告有关grab_window的事件,并且仅在event_mask选择时报告。

我仍然不确定我是否完全理解True案例的行为,但我的解释是,如果为True,其他X程序(即由其他进程创建的窗口)被禁止接收XEvents,但是那些会触及任何窗口的XEvents由您的流程创建的正常交付。在错误的情况下,将根据您选择的特定窗口报告所有事件。这就是我追求的行为。


13
2018-05-08 10:10



我讨厌接受我自己的答案,但只是为了结束松散的目的...... - Drew Hall


答案:


我几乎不好意思承认这一点,但答案结果就像将第三个参数(owner_events)从True更改为False一样简单。

来自 tronche.com上的Xlib教程/参考

如果owner_events为False,则会针对grab_window报告所有生成的指针事件,并且仅在event_mask选择时报告。如果owner_events为True,并且通常会将生成的指针事件报告给此客户端,则会照常报告。否则,将报告有关grab_window的事件,并且仅在event_mask选择时报告。

我仍然不确定我是否完全理解True案例的行为,但我的解释是,如果为True,其他X程序(即由其他进程创建的窗口)被禁止接收XEvents,但是那些会触及任何窗口的XEvents由您的流程创建的正常交付。在错误的情况下,将根据您选择的特定窗口报告所有事件。这就是我追求的行为。


13
2018-05-08 10:10



我讨厌接受我自己的答案,但只是为了结束松散的目的...... - Drew Hall