xcb:在 EnterNotify 之后立即收到 LeaveNotify
xcb: LeaveNotify received immediately after EnterNotify
我正在使用 xcb 库以学习为目的用 Rust 编写一个 window 管理器。我的代码和几个测试 windows(xterm
实例)都在 Xephyr 会话中 运行。我将根 window 上的事件掩码设置为
xproto::EVENT_MASK_SUBSTRUCTURE_REDIRECT
| xproto::EVENT_MASK_SUBSTRUCTURE_NOTIFY
| xproto::EVENT_MASK_POINTER_MOTION
| xproto::EVENT_MASK_LEAVE_WINDOW
| xproto::EVENT_MASK_ENTER_WINDOW
| xproto::EVENT_MASK_BUTTON_PRESS
| xproto::EVENT_MASK_PROPERTY_CHANGE
| xproto::EVENT_MASK_FOCUS_CHANGE
并且所有 child windows 的事件掩码为
xproto::EVENT_MASK_ENTER_WINDOW
| xproto::EVENT_MASK_LEAVE_WINDOW
| xproto::EVENT_MASK_BUTTON_PRESS
| xproto::EVENT_MASK_PROPERTY_CHANGE
| xproto::EVENT_MASK_POINTER_MOTION
| xproto::EVENT_MASK_FOCUS_CHANGE
| xproto::EVENT_MASK_STRUCTURE_NOTIFY
| xproto::EVENT_MASK_EXPOSURE
当我将鼠标移到 non-root window 上时,我使用 EnterNotify
事件在 window 上抓取鼠标按钮,对于 click-to-focus目的,并在 LeaveNotify
上取消抓取。事件顺序是:
- 鼠标位于根目录 window
- 将鼠标移到 non-root window
- 收到
EnterNotify
non-root window
- non-root window
上的抓取按钮
- 立即接收
LeaveNotify
,鼠标还在non-rootwindow
- 由于
LeaveNotify
而取消抓取按钮
- 尝试点击 non-root window
- 为 non-root window
接收第二个 LeaveNotify
- 收到根 window 的
EnterNotify
,并在根 window 上抓取鼠标按钮
ButtonPress
为根 window 发送,尽管光标在 non-root window 上
我真的不确定这可能是什么原因;使用 Google 等没有任何用处。
对于以后可能偶然发现此问题的任何人,部分解决方案是:
- 仅在 window 上监听输入事件以在 window
上抓取按钮
- 掩码根仅
SUBSTRUCTURE_REDIRECT | SUBSTRUCTURE_NOTIFY | BUTTON_PRESS
- 不要将
LEAVE_WINDOW
屏蔽到 non-root windows,也不要处理这些事件
我不想将此添加为答案,因为:
- 我不确定这样做是否正确。
- 我还没有彻底测试过。
- 它没有回答我的主要问题“为什么会收到这样的事件?”
看看协议参考手册。它描述了(除其他外)生成进入和离开事件的确切算法:https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html#events:pointer_window
在您的特定情况下,我希望 LeaveNotify
事件具有 mode: Grab
,这意味着 window 不再具有“正常”指针焦点,因为某些东西(你的程序)抓住了输入。
如果这不是答案,我可以在 xtrace / x11trace 下推荐 运行 您的 WM(在 Debian-based 发行版中作为软件包 xtrace
提供)。该程序打印“通过”的所有 X11 流量。这可能有助于弄清楚发生了什么。
我正在使用 xcb 库以学习为目的用 Rust 编写一个 window 管理器。我的代码和几个测试 windows(xterm
实例)都在 Xephyr 会话中 运行。我将根 window 上的事件掩码设置为
xproto::EVENT_MASK_SUBSTRUCTURE_REDIRECT
| xproto::EVENT_MASK_SUBSTRUCTURE_NOTIFY
| xproto::EVENT_MASK_POINTER_MOTION
| xproto::EVENT_MASK_LEAVE_WINDOW
| xproto::EVENT_MASK_ENTER_WINDOW
| xproto::EVENT_MASK_BUTTON_PRESS
| xproto::EVENT_MASK_PROPERTY_CHANGE
| xproto::EVENT_MASK_FOCUS_CHANGE
并且所有 child windows 的事件掩码为
xproto::EVENT_MASK_ENTER_WINDOW
| xproto::EVENT_MASK_LEAVE_WINDOW
| xproto::EVENT_MASK_BUTTON_PRESS
| xproto::EVENT_MASK_PROPERTY_CHANGE
| xproto::EVENT_MASK_POINTER_MOTION
| xproto::EVENT_MASK_FOCUS_CHANGE
| xproto::EVENT_MASK_STRUCTURE_NOTIFY
| xproto::EVENT_MASK_EXPOSURE
当我将鼠标移到 non-root window 上时,我使用 EnterNotify
事件在 window 上抓取鼠标按钮,对于 click-to-focus目的,并在 LeaveNotify
上取消抓取。事件顺序是:
- 鼠标位于根目录 window
- 将鼠标移到 non-root window
- 收到
EnterNotify
non-root window - non-root window 上的抓取按钮
- 立即接收
LeaveNotify
,鼠标还在non-rootwindow - 由于
LeaveNotify
而取消抓取按钮
- 尝试点击 non-root window
- 为 non-root window 接收第二个
- 收到根 window 的
EnterNotify
,并在根 window 上抓取鼠标按钮
ButtonPress
为根 window 发送,尽管光标在 non-root window 上
LeaveNotify
我真的不确定这可能是什么原因;使用 Google 等没有任何用处。
对于以后可能偶然发现此问题的任何人,部分解决方案是:
- 仅在 window 上监听输入事件以在 window 上抓取按钮
- 掩码根仅
SUBSTRUCTURE_REDIRECT | SUBSTRUCTURE_NOTIFY | BUTTON_PRESS
- 不要将
LEAVE_WINDOW
屏蔽到 non-root windows,也不要处理这些事件
我不想将此添加为答案,因为:
- 我不确定这样做是否正确。
- 我还没有彻底测试过。
- 它没有回答我的主要问题“为什么会收到这样的事件?”
看看协议参考手册。它描述了(除其他外)生成进入和离开事件的确切算法:https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html#events:pointer_window
在您的特定情况下,我希望 LeaveNotify
事件具有 mode: Grab
,这意味着 window 不再具有“正常”指针焦点,因为某些东西(你的程序)抓住了输入。
如果这不是答案,我可以在 xtrace / x11trace 下推荐 运行 您的 WM(在 Debian-based 发行版中作为软件包 xtrace
提供)。该程序打印“通过”的所有 X11 流量。这可能有助于弄清楚发生了什么。