diff options
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/phosphor.rs | 22 | ||||
-rw-r--r-- | src/window.rs | 12 |
3 files changed, 34 insertions, 2 deletions
@@ -5,7 +5,7 @@ mod window_program; mod phosphor; pub use events::{Request, Event, Action, Axis, MouseButton, SizeBounds}; -pub(crate) use window::PhosphorWindow; +pub(crate) use window::{PhosphorWindow, PointerState}; pub use window_builder::WindowBuilder; pub use window_program::WindowProgram; 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(); diff --git a/src/window.rs b/src/window.rs index 70c9c02..f031af5 100644 --- a/src/window.rs +++ b/src/window.rs @@ -18,11 +18,21 @@ fn to_physical_size(dimensions: Dimensions, scale: u32) -> PhysicalSize<u32> { } +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum PointerState { + In, + Out, + PendingOut, +} + + pub(crate) struct PhosphorWindow { pub winit: Rc<Window>, pub program: Box<dyn WindowProgram>, pub requests: EventQueue<Request>, pub pointer: Option<Position>, + pub pointer_state: PointerState, + pub mouse_buttons: [bool; 5], pub marked_for_destruction: bool, pub size_bounds: SizeBounds, // logical dimensions @@ -79,6 +89,8 @@ impl PhosphorWindow { program: builder.program, requests: EventQueue::new(), pointer: None, + pointer_state: PointerState::Out, + mouse_buttons: [false; 5], marked_for_destruction: false, size_bounds, |