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

发布于 2024-09-01 07:12:13 字数 745 浏览 3 评论 0原文

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

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

不幸的是,它似乎并不是这样工作的。如果用户拖动速度太快并且鼠标指针进入拆分任一侧的窗口之一,则 MotionEvent 消息将转移到该(子)窗口而不是拆分窗口。

我做错了什么?我的 XGrabPointer() 调用如下:

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

I've implemented a horizontal splitter widget in Xlib. I'm trying to grab the mouse when the user clicks & drags on the splitter bar (so that the user can dynamically move the split & thus resize the windows on either side of the splitter bar).

I've used XGrabPointer() after receiving a left click, in hopes that all future mouse motion (dragging) will be diverted to the splitter window until the left button is released.

Unfortuntately, it doesn't seem to work like that. If the user drags too quickly and the mouse pointer enters one of the windows on either side of the split, the MotionEvent messages are diverted to that (child) window rather than the splitter window.

What have I done wrong? My XGrabPointer() call is as follows:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没结果 2024-09-08 07:12:13

我几乎不好意思承认这一点,但答案其实很简单,只需将第三个参数 (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,但那些会击中任何窗口的程序由您的流程创建的内容将正常交付。在错误的情况下,将报告与您选择的特定窗口相关的所有事件。这就是我所追求的行为。

I'm almost embarrassed to admit this, but the answer turned out to be as simple as changing that third parameter (owner_events) from True to False.

From the Xlib tutorial/reference at tronche.com:

If owner_events is False, all generated pointer events are reported with respect to grab_window and are reported only if selected by event_mask. If owner_events is True and if a generated pointer event would normally be reported to this client, it is reported as usual. Otherwise, the event is reported with respect to the grab_window and is reported only if selected by event_mask.

I'm still not sure I completely understand the behavior of the True case, but my interpretation is that if True, other X programs (that is, windows created by other processes) are barred from receiving XEvents, but those that would hit any window created by your process are delivered as normal. In the false case, all events are reported with respect to the specific window you have selected. This was the behavior I was after.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文