I'm working on a simple window manager using XCB, and I need to be notified when the user clicks on the screen to obtain the ID of the window where the pointer was located.
I attempted to enable XCB_EVENT_MASK_BUTTON_RELEASE for each new client using the following code:
let cookie = xcb::change_window_attributes_checked(
conn,
self.wid,
&[(xcb::CW_EVENT_MASK, xcb::EVENT_MASK_BUTTON_RELEASE)],
);
if let Err(cookie) = cookie.request_check() {
panic!("error {:?}", cookie.to_string());
}
However, this approach doesn't seem to work, as even though the cookie is not in an error state, no BUTTON_RELEASE event is triggered.
I also experimented with xcb_grab_button, which successfully sends the event. However, the BUTTON_RELEASE event always contains the root window's ID, not the ID of the "focused" window. Additionally, this method blocks all clients from receiving mouse events:
xcb::grab_button(
&self.conn,
false,
util::get_screen(&self.conn).root(),
xcb::EVENT_MASK_BUTTON_PRESS as u16 | xcb::EVENT_MASK_BUTTON_RELEASE as u16,
xcb::GRAB_MODE_ASYNC as u8,
xcb::GRAB_MODE_ASYNC as u8,
xcb::NONE,
xcb::NONE,
1,
xcb::MOD_MASK_ANY as u16,
);
Please note that the XCB_EVENT_MASK_ENTER_WINDOW and XCB_EVENT_MASK_LEAVE_WINDOW masks work fine. Additionally, XCB_EVENT_MASK_BUTTON_RELEASE functions properly when set on the root window.