Skip to content

Commit

Permalink
On Wayland, fix hiding cursors on GNOME
Browse files Browse the repository at this point in the history
`wl_pointer::set_cursor` expects a serial number of the last
`wl_pointer::enter` event. However other calls expect latest
observed pointer serial, so this commit tracks both and
use them as required by specification.

Fixes rust-windowing#2273.
  • Loading branch information
TobTobXX authored May 1, 2022
1 parent ea09d1d commit 0728105
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
6 changes: 5 additions & 1 deletion src/platform_impl/linux/wayland/seat/pointer/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ pub(super) struct PointerData {

pub confined_pointer: Rc<RefCell<Option<ZwpConfinedPointerV1>>>,

/// A latest event serial.
/// Latest observed serial in pointer events.
pub latest_serial: Rc<Cell<u32>>,

/// Latest observed serial in pointer enter events.
pub latest_enter_serial: Rc<Cell<u32>>,

/// The currently accumulated axis data on a pointer.
pub axis_data: AxisData,
}
Expand All @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions src/platform_impl/linux/wayland/seat/pointer/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 10 additions & 2 deletions src/platform_impl/linux/wayland/seat/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ pub struct WinitPointer {
confined_pointer: Weak<RefCell<Option<ZwpConfinedPointerV1>>>,

/// Latest observed serial in pointer events.
/// used by Window::start_interactive_move()
latest_serial: Rc<Cell<u32>>,
/// Latest observed serial in pointer enter events.
/// used by Window::set_cursor()
latest_enter_serial: Rc<Cell<u32>>,

/// Seat.
seat: WlSeat,
Expand All @@ -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;
}
};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -151,6 +157,8 @@ impl WinitPointer {
}

pub fn drag_window(&self, window: &Window<FallbackFrame>) {
// 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());
}
}
Expand Down

0 comments on commit 0728105

Please sign in to comment.