From d48ae42824b7061c435e78f147356be47784e56b Mon Sep 17 00:00:00 2001 From: Demonthos <66571940+Demonthos@users.noreply.github.com> Date: Mon, 23 May 2022 01:43:48 -0500 Subject: [PATCH] handle mouse up event for right and middle buttons (#665) --- src/event/source/windows.rs | 19 ++++++++++++-- src/event/sys/windows/parse.rs | 48 +++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/event/source/windows.rs b/src/event/source/windows.rs index f53a392..669272d 100644 --- a/src/event/source/windows.rs +++ b/src/event/source/windows.rs @@ -2,7 +2,10 @@ use std::time::Duration; use crossterm_winapi::{Console, Handle, InputRecord}; -use crate::event::{sys::windows::poll::WinApiPoll, Event}; +use crate::event::{ + sys::windows::{parse::MouseButtonsPressed, poll::WinApiPoll}, + Event, +}; #[cfg(feature = "event-stream")] use super::super::sys::Waker; @@ -17,6 +20,7 @@ pub(crate) struct WindowsEventSource { console: Console, poll: WinApiPoll, surrogate_buffer: Option, + mouse_buttons_pressed: MouseButtonsPressed, } impl WindowsEventSource { @@ -31,6 +35,7 @@ impl WindowsEventSource { poll: WinApiPoll::new()?, surrogate_buffer: None, + mouse_buttons_pressed: MouseButtonsPressed::default(), }) } } @@ -47,7 +52,17 @@ impl EventSource for WindowsEventSource { InputRecord::KeyEvent(record) => { handle_key_event(record, &mut self.surrogate_buffer) } - InputRecord::MouseEvent(record) => handle_mouse_event(record), + InputRecord::MouseEvent(record) => { + let mouse_event = + handle_mouse_event(record, &self.mouse_buttons_pressed); + self.mouse_buttons_pressed = MouseButtonsPressed { + left: record.button_state.left_button(), + right: record.button_state.right_button(), + middle: record.button_state.middle_button(), + }; + + mouse_event + } InputRecord::WindowBufferSizeEvent(record) => { Some(Event::Resize(record.size.x as u16, record.size.y as u16)) } diff --git a/src/event/sys/windows/parse.rs b/src/event/sys/windows/parse.rs index b5c8cf7..697a49a 100644 --- a/src/event/sys/windows/parse.rs +++ b/src/event/sys/windows/parse.rs @@ -17,8 +17,18 @@ use crate::{ Result, }; -pub(crate) fn handle_mouse_event(mouse_event: MouseEvent) -> Option { - if let Ok(Some(event)) = parse_mouse_event_record(&mouse_event) { +#[derive(Default)] +pub struct MouseButtonsPressed { + pub(crate) left: bool, + pub(crate) right: bool, + pub(crate) middle: bool, +} + +pub(crate) fn handle_mouse_event( + mouse_event: MouseEvent, + buttons_pressed: &MouseButtonsPressed, +) -> Option { + if let Ok(Some(event)) = parse_mouse_event_record(&mouse_event, buttons_pressed) { return Some(Event::Mouse(event)); } @@ -287,31 +297,43 @@ pub fn parse_relative_y(y: i16) -> Result { Ok(y - window_size.top) } -fn parse_mouse_event_record(event: &MouseEvent) -> Result> { +fn parse_mouse_event_record( + event: &MouseEvent, + buttons_pressed: &MouseButtonsPressed, +) -> Result> { let modifiers = KeyModifiers::from(&event.control_key_state); let xpos = event.mouse_position.x as u16; let ypos = parse_relative_y(event.mouse_position.y)? as u16; let button_state = event.button_state; - let button = if button_state.right_button() { - MouseButton::Right - } else if button_state.middle_button() { - MouseButton::Middle - } else { - MouseButton::Left - }; let kind = match event.event_flags { EventFlags::PressOrRelease => { - if button_state.release_button() { - // in order to read the up button type, we have to check the last down input record. + if button_state.left_button() && !buttons_pressed.left { + Some(MouseEventKind::Down(MouseButton::Left)) + } else if !button_state.left_button() && buttons_pressed.left { Some(MouseEventKind::Up(MouseButton::Left)) + } else if button_state.right_button() && !buttons_pressed.right { + Some(MouseEventKind::Down(MouseButton::Right)) + } else if !button_state.right_button() && buttons_pressed.right { + Some(MouseEventKind::Up(MouseButton::Right)) + } else if button_state.middle_button() && !buttons_pressed.middle { + Some(MouseEventKind::Down(MouseButton::Middle)) + } else if !button_state.middle_button() && buttons_pressed.middle { + Some(MouseEventKind::Up(MouseButton::Middle)) } else { - Some(MouseEventKind::Down(button)) + None } } EventFlags::MouseMoved => { + let button = if button_state.right_button() { + MouseButton::Right + } else if button_state.middle_button() { + MouseButton::Middle + } else { + MouseButton::Left + }; if button_state.release_button() { Some(MouseEventKind::Moved) } else {