From 393d4f309ba238f81d100aae409a784f82d88c15 Mon Sep 17 00:00:00 2001 From: Ben Bridle <ben@derelict.engineering> Date: Mon, 16 Dec 2024 14:22:33 +1300 Subject: Only send Event::CursorExit when all mouse buttons are released This is to allow a user to drag an element inside the program window and for the mouse cursor to move in and out of the window during the drag operation. This is the intuitive and expected behaviour. --- src/phosphor.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src/phosphor.rs') diff --git a/src/phosphor.rs b/src/phosphor.rs index ab13cb0..08c71da 100644 --- a/src/phosphor.rs +++ b/src/phosphor.rs @@ -134,10 +134,16 @@ impl PhosphorApplication { } } WindowEvent::CursorEntered { .. } => { + window.pointer_state = PointerState::In; handle!(Event::CursorEnter); } WindowEvent::CursorLeft { .. } => { - handle!(Event::CursorExit); + if window.mouse_buttons.iter().all(|b| !b) { + window.pointer_state = PointerState::Out; + handle!(Event::CursorExit); + } else { + window.pointer_state = PointerState::PendingOut; + } } WindowEvent::MouseWheel { delta, .. } => match delta { MouseScrollDelta::LineDelta(x, y) => { @@ -159,6 +165,20 @@ impl PhosphorApplication { WinitMouseButton::Forward => handle!(Event::MouseButton { button: MouseButton::Forward, action }), _ => (), } + // Keep track of mouse button hold states, and mark cursor as out when all are released. + let button_index = match button { + WinitMouseButton::Left => 0, + WinitMouseButton::Middle => 1, + WinitMouseButton::Right => 2, + WinitMouseButton::Back => 3, + WinitMouseButton::Forward => 4, + _ => return, + }; + window.mouse_buttons[button_index] = action.is_pressed(); + if window.pointer_state == PointerState::PendingOut && window.mouse_buttons.iter().all(|b| !b) { + window.pointer_state = PointerState::Out; + handle!(Event::CursorExit); + } } WindowEvent::RedrawRequested => { window.redraw(); -- cgit v1.2.3-70-g09d2