rust - xcb:在 EnterNotify 之后立即收到 LeaveNotify

标签 rust x11 window-managers xcb

我正在使用 xcb 在 Rust 中编写一个窗口管理器以用于学习目的。图书馆。我的代码和几个测试窗口(xterm 实例)都在 Xephyr session 中运行。我将根窗口上的事件掩码设置为

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
并且所有子窗口都有一个事件掩码
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
当我将鼠标移到非根窗口上时,我使用 EnterNotify事件以在该窗口上抓取鼠标按钮,用于点击聚焦,并在 LeaveNotify 上取消抓取.事件的顺序是:
  • 鼠标在根窗口
  • 将鼠标移至非根窗口
  • 接收EnterNotify对于非根窗口
  • 非根窗口上的抓取按钮
  • 立即收到LeaveNotify ,而鼠标仍在非根窗口
  • 由于 LeaveNotify 而取消抓取按钮
  • 尝试单击非根窗口
  • 接收第二个 LeaveNotify对于非根窗口
  • 接收 EnterNotify对于根窗口,然后在根窗口上捕获鼠标按钮
  • ButtonPress为根窗口发送,尽管光标位于非根窗口

  • 我真的不确定这可能是什么原因。使用谷歌之类的东西没有任何用处。

    对于以后可能偶然发现此问题的任何人,部分解决方案是:
  • 仅监听窗口输入事件以抓取窗口上的按钮
  • 掩码根为 SUBSTRUCTURE_REDIRECT | SUBSTRUCTURE_NOTIFY | BUTTON_PRESS仅限
  • 不要蒙面LEAVE_WINDOW到非根窗口,并且不处理这些事件

  • 我不想将此添加为答案,因为:
  • 我不确定这是正确的做法。
  • 我没有彻底测试过。
  • 它没有回答我的主要问题“为什么会收到这样的事件?”
  • 最佳答案

    查看协议(protocol)引用手册。它描述了(以及许多其他内容)生成进入和离开事件的确切算法:https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html#events:pointer_window
    在您的具体情况下,我希望 LeaveNotify事件有mode: Grab ,这意味着窗口不再具有“正常”指针焦点,因为某些东西(您的程序)抓取了输入。
    如果这不是答案,我建议您在 xtrace / x11trace 下运行 WM (在基于 Debian 的发行版中以软件包 xtrace 的形式提供)。该程序打印所有“通过”的 X11 流量。这可能有助于弄清楚发生了什么。

    关于rust - xcb:在 EnterNotify 之后立即收到 LeaveNotify,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63621575/

    相关文章:

    enums - 我可以匹配所有具有相同值形状的枚举变体吗?

    rust - 如何使用 glibc 而不是 musl 使用 rustc 创建静态可执行文件?

    c++ - 相当于 X11 中的 "Invalidate Rect"/"WM_PAINT"

    android - View.OnSystemUiVisibilityChangeListener 在 android 服务中不起作用

    linux - Qt 是否需要在 Linux 上预装窗口管理器?

    rust - 默认情况下,Rust 闭包是堆栈分配还是堆分配?

    closures - 使用闭包创建回调系统

    linux - X11 - 设置光标位置不起作用

    ssh - 在SSH X11转发上Shift运行X窗口(显示环境)

    c++ - 为什么很多窗口管理器不支持面向对象?