x11: fix cursor grab mode tracking on error

Fixes #4064.
This commit is contained in:
Kirill Chibisov 2024-12-31 05:52:12 +03:00 committed by GitHub
parent 5ea81efc74
commit 927deb030f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 33 deletions

View file

@ -202,3 +202,4 @@ changelog entry.
- On macOS, fixed the scancode conversion for `IntlBackslash`. - On macOS, fixed the scancode conversion for `IntlBackslash`.
- On macOS, fixed redundant `SurfaceResized` event at window creation. - On macOS, fixed redundant `SurfaceResized` event at window creation.
- On Windows, fixed the event loop not waking on accessibility requests. - On Windows, fixed the event loop not waking on accessibility requests.
- On X11, fixed cursor grab mode state tracking on error.

View file

@ -1827,6 +1827,11 @@ impl UnownedWindow {
#[inline] #[inline]
pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> {
// We don't support the locked cursor yet, so ignore it early on.
if mode == CursorGrabMode::Locked {
return Err(NotSupportedError::new("locked cursor is not implemented on X11").into());
}
let mut grabbed_lock = self.cursor_grabbed_mode.lock().unwrap(); let mut grabbed_lock = self.cursor_grabbed_mode.lock().unwrap();
if mode == *grabbed_lock { if mode == *grabbed_lock {
return Ok(()); return Ok(());
@ -1838,6 +1843,7 @@ impl UnownedWindow {
.xcb_connection() .xcb_connection()
.ungrab_pointer(x11rb::CURRENT_TIME) .ungrab_pointer(x11rb::CURRENT_TIME)
.expect_then_ignore_error("Failed to call `xcb_ungrab_pointer`"); .expect_then_ignore_error("Failed to call `xcb_ungrab_pointer`");
*grabbed_lock = CursorGrabMode::None;
let result = match mode { let result = match mode {
CursorGrabMode::None => self CursorGrabMode::None => self
@ -1845,34 +1851,33 @@ impl UnownedWindow {
.flush_requests() .flush_requests()
.map_err(|err| RequestError::Os(os_error!(X11Error::Xlib(err)))), .map_err(|err| RequestError::Os(os_error!(X11Error::Xlib(err)))),
CursorGrabMode::Confined => { CursorGrabMode::Confined => {
let result = { let result = self
self.xconn .xconn
.xcb_connection() .xcb_connection()
.grab_pointer( .grab_pointer(
true as _, true as _,
self.xwindow, self.xwindow,
xproto::EventMask::BUTTON_PRESS xproto::EventMask::BUTTON_PRESS
| xproto::EventMask::BUTTON_RELEASE | xproto::EventMask::BUTTON_RELEASE
| xproto::EventMask::ENTER_WINDOW | xproto::EventMask::ENTER_WINDOW
| xproto::EventMask::LEAVE_WINDOW | xproto::EventMask::LEAVE_WINDOW
| xproto::EventMask::POINTER_MOTION | xproto::EventMask::POINTER_MOTION
| xproto::EventMask::POINTER_MOTION_HINT | xproto::EventMask::POINTER_MOTION_HINT
| xproto::EventMask::BUTTON1_MOTION | xproto::EventMask::BUTTON1_MOTION
| xproto::EventMask::BUTTON2_MOTION | xproto::EventMask::BUTTON2_MOTION
| xproto::EventMask::BUTTON3_MOTION | xproto::EventMask::BUTTON3_MOTION
| xproto::EventMask::BUTTON4_MOTION | xproto::EventMask::BUTTON4_MOTION
| xproto::EventMask::BUTTON5_MOTION | xproto::EventMask::BUTTON5_MOTION
| xproto::EventMask::KEYMAP_STATE, | xproto::EventMask::KEYMAP_STATE,
xproto::GrabMode::ASYNC, xproto::GrabMode::ASYNC,
xproto::GrabMode::ASYNC, xproto::GrabMode::ASYNC,
self.xwindow, self.xwindow,
0u32, 0u32,
x11rb::CURRENT_TIME, x11rb::CURRENT_TIME,
) )
.expect("Failed to call `grab_pointer`") .expect("Failed to call `grab_pointer`")
.reply() .reply()
.expect("Failed to receive reply from `grab_pointer`") .expect("Failed to receive reply from `grab_pointer`");
};
match result.status { match result.status {
xproto::GrabStatus::SUCCESS => Ok(()), xproto::GrabStatus::SUCCESS => Ok(()),
@ -1892,11 +1897,7 @@ impl UnownedWindow {
} }
.map_err(|err| RequestError::Os(os_error!(err))) .map_err(|err| RequestError::Os(os_error!(err)))
}, },
CursorGrabMode::Locked => { CursorGrabMode::Locked => return Ok(()),
return Err(
NotSupportedError::new("locked cursor is not implemented on X11").into()
);
},
}; };
if result.is_ok() { if result.is_ok() {