diff --git a/CHANGELOG.md b/CHANGELOG.md index 22a97fae6e..589642daa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased +- On Wayland, fix bug where the cursor wouldn't hide in GNOME. - On macOS, Windows, and Wayland, add `set_cursor_hittest` to let the window ignore mouse events. - On Windows, added `WindowExtWindows::set_skip_taskbar` and `WindowBuilderExtWindows::with_skip_taskbar`. - On Windows, added `EventLoopBuilderExtWindows::with_msg_hook`. diff --git a/src/platform_impl/linux/wayland/seat/pointer/data.rs b/src/platform_impl/linux/wayland/seat/pointer/data.rs index 1da60d3526..310e692b43 100644 --- a/src/platform_impl/linux/wayland/seat/pointer/data.rs +++ b/src/platform_impl/linux/wayland/seat/pointer/data.rs @@ -26,9 +26,12 @@ pub(super) struct PointerData { pub confined_pointer: Rc>>, - /// A latest event serial. + /// Latest observed serial in pointer events. pub latest_serial: Rc>, + /// Latest observed serial in pointer enter events. + pub latest_enter_serial: Rc>, + /// The currently accumulated axis data on a pointer. pub axis_data: AxisData, } @@ -42,6 +45,7 @@ impl PointerData { Self { surface: None, latest_serial: Rc::new(Cell::new(0)), + latest_enter_serial: Rc::new(Cell::new(0)), confined_pointer, modifiers_state, pointer_constraints, diff --git a/src/platform_impl/linux/wayland/seat/pointer/handlers.rs b/src/platform_impl/linux/wayland/seat/pointer/handlers.rs index c5e605fe59..1967861dd0 100644 --- a/src/platform_impl/linux/wayland/seat/pointer/handlers.rs +++ b/src/platform_impl/linux/wayland/seat/pointer/handlers.rs @@ -42,6 +42,7 @@ pub(super) fn handle_pointer( .. } => { pointer_data.latest_serial.replace(serial); + pointer_data.latest_enter_serial.replace(serial); let window_id = wayland::make_wid(&surface); if !winit_state.window_map.contains_key(&window_id) { @@ -61,6 +62,7 @@ pub(super) fn handle_pointer( confined_pointer: Rc::downgrade(&pointer_data.confined_pointer), pointer_constraints: pointer_data.pointer_constraints.clone(), latest_serial: pointer_data.latest_serial.clone(), + latest_enter_serial: pointer_data.latest_enter_serial.clone(), seat, }; window_handle.pointer_entered(winit_pointer); @@ -104,6 +106,7 @@ pub(super) fn handle_pointer( confined_pointer: Rc::downgrade(&pointer_data.confined_pointer), pointer_constraints: pointer_data.pointer_constraints.clone(), latest_serial: pointer_data.latest_serial.clone(), + latest_enter_serial: pointer_data.latest_enter_serial.clone(), seat, }; window_handle.pointer_left(winit_pointer); diff --git a/src/platform_impl/linux/wayland/seat/pointer/mod.rs b/src/platform_impl/linux/wayland/seat/pointer/mod.rs index c6726224c0..0542ba2f8b 100644 --- a/src/platform_impl/linux/wayland/seat/pointer/mod.rs +++ b/src/platform_impl/linux/wayland/seat/pointer/mod.rs @@ -35,7 +35,11 @@ pub struct WinitPointer { confined_pointer: Weak>>, /// Latest observed serial in pointer events. + /// used by Window::start_interactive_move() latest_serial: Rc>, + /// Latest observed serial in pointer enter events. + /// used by Window::set_cursor() + latest_enter_serial: Rc>, /// Seat. seat: WlSeat, @@ -58,7 +62,9 @@ impl WinitPointer { Some(cursor_icon) => cursor_icon, None => { // Hide the cursor. - (*self.pointer).set_cursor(self.latest_serial.get(), None, 0, 0); + // WlPointer::set_cursor() expects the serial of the last *enter* + // event (compare to to start_interactive_move()). + (*self.pointer).set_cursor(self.latest_enter_serial.get(), None, 0, 0); return; } }; @@ -106,7 +112,7 @@ impl WinitPointer { CursorIcon::ZoomOut => &["zoom-out"], }; - let serial = Some(self.latest_serial.get()); + let serial = Some(self.latest_enter_serial.get()); for cursor in cursors { if self.pointer.set_cursor(cursor, serial).is_ok() { return; @@ -151,6 +157,8 @@ impl WinitPointer { } pub fn drag_window(&self, window: &Window) { + // WlPointer::setart_interactive_move() expects the last serial of *any* + // pointer event (compare to set_cursor()). window.start_interactive_move(&self.seat, self.latest_serial.get()); } }