I am in the process of writing a window manager in Rust for learning purposes, using the xcb library. My code and several test windows (xterm
instances) are all running inside of a Xephyr session. I set my event mask on the root window as
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
and all child windows have an event mask of
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
When I move the mouse over a non-root window, I use the EnterNotify
event to grab mouse buttons on that window, for click-to-focus purposes, and ungrab on LeaveNotify
. The sequence of events is:
- Mouse on root window
- Move mouse over non-root window
- Receive
EnterNotify
for non-root window - Grab buttons on the non-root window
- Immediately receive
LeaveNotify
, while the mouse is still over the non-root window - Ungrab buttons due to
LeaveNotify
- Attempt clicking on the non-root window
- Receive a second
LeaveNotify
for the non-root window - Receive an
EnterNotify
for the root window, and grab mouse buttons on the root window ButtonPress
is sent for the root window, despite the cursor being over a non-root window
I'm genuinely unsure what the cause of this might be; using Google and the like has turned up nothing useful.
For anyone who might stumble across this later, a partial solution is:
- Only listen on window enter events to grab buttons on a window
- Mask root to be
SUBSTRUCTURE_REDIRECT | SUBSTRUCTURE_NOTIFY | BUTTON_PRESS
only - Don't mask
LEAVE_WINDOW
onto non-root windows, and don't handle those events
I don't want to add this as an answer because:
- I'm unsure it's the correct way of doing it.
- I've not tested this thoroughly.
- It doesn't answer my primary question of "why are events received like this?"