From b9d2686286628f8839198dfc549f9426572eb7df Mon Sep 17 00:00:00 2001 From: George Atkinson Date: Sat, 19 Dec 2020 21:28:22 +0000 Subject: [PATCH 1/4] Added mouse capture/release to windows backend --- src/win/window.rs | 26 ++++++++++++++++++++++++++ src/window.rs | 15 +++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/win/window.rs b/src/win/window.rs index b7574d62..f6aa450b 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -13,6 +13,7 @@ use winapi::um::winuser::{ WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP, WM_INPUTLANGCHANGE, GET_XBUTTON_WPARAM, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2, + SetCapture, GetCapture, ReleaseCapture, IsWindow }; use std::cell::RefCell; @@ -103,9 +104,11 @@ unsafe extern "system" fn wnd_proc( if let Some(button) = button { let event = match msg { WM_LBUTTONDOWN | WM_MBUTTONDOWN | WM_RBUTTONDOWN | WM_XBUTTONDOWN => { + window.set_mouse_capture(); MouseEvent::ButtonPressed(button) } WM_LBUTTONUP | WM_MBUTTONUP | WM_RBUTTONUP | WM_XBUTTONUP => { + window.release_mouse_capture(); MouseEvent::ButtonReleased(button) } _ => { @@ -306,6 +309,29 @@ impl Window { } } } + + // Captures the mouse cursor for this window + pub fn set_mouse_capture(&self) { + unsafe { + if IsWindow(self.hwnd) != 0 { + SetCapture(self.hwnd); + } + } + } + + // Returns true if this window has captured the mouse + pub fn get_mouse_capture(&self) -> bool { + unsafe { + GetCapture() == self.hwnd + } + } + + // Releases the mouse capture from all windows + pub fn release_mouse_capture(&self) { + unsafe { + ReleaseCapture(); + } + } } unsafe impl HasRawWindowHandle for Window { diff --git a/src/window.rs b/src/window.rs index a88af7bd..0ead40ba 100644 --- a/src/window.rs +++ b/src/window.rs @@ -31,6 +31,21 @@ impl<'a> Window<'a> { { platform::Window::open::(options, build) } + + // Captures the mouse cursor for this window + pub fn set_mouse_capture(&self) { + platform::Window::set_mouse_capture(self.0); + } + + // Returns true if this window has captured the mouse + pub fn get_mouse_capture(&self) -> bool { + platform::Window::get_mouse_capture(self.0) + } + + // Releases the mouse capture from all windows + pub fn release_mouse_capture(&self) { + platform::Window::release_mouse_capture(self.0) + } } unsafe impl<'a> HasRawWindowHandle for Window<'a> { From f7ae717313bf1d8258f203193e474ce5e9ce26b1 Mon Sep 17 00:00:00 2001 From: George Atkinson Date: Sat, 19 Dec 2020 21:40:27 +0000 Subject: [PATCH 2/4] Mouse capture now automatic only Removed manual ability to trigger mouse capture and release. --- src/win/window.rs | 4 ++-- src/window.rs | 15 --------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/win/window.rs b/src/win/window.rs index f6aa450b..051f01d2 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -104,11 +104,11 @@ unsafe extern "system" fn wnd_proc( if let Some(button) = button { let event = match msg { WM_LBUTTONDOWN | WM_MBUTTONDOWN | WM_RBUTTONDOWN | WM_XBUTTONDOWN => { - window.set_mouse_capture(); + window.0.set_mouse_capture(); MouseEvent::ButtonPressed(button) } WM_LBUTTONUP | WM_MBUTTONUP | WM_RBUTTONUP | WM_XBUTTONUP => { - window.release_mouse_capture(); + window.0.release_mouse_capture(); MouseEvent::ButtonReleased(button) } _ => { diff --git a/src/window.rs b/src/window.rs index 0ead40ba..a88af7bd 100644 --- a/src/window.rs +++ b/src/window.rs @@ -31,21 +31,6 @@ impl<'a> Window<'a> { { platform::Window::open::(options, build) } - - // Captures the mouse cursor for this window - pub fn set_mouse_capture(&self) { - platform::Window::set_mouse_capture(self.0); - } - - // Returns true if this window has captured the mouse - pub fn get_mouse_capture(&self) -> bool { - platform::Window::get_mouse_capture(self.0) - } - - // Releases the mouse capture from all windows - pub fn release_mouse_capture(&self) { - platform::Window::release_mouse_capture(self.0) - } } unsafe impl<'a> HasRawWindowHandle for Window<'a> { From 0f6fd255b90c2f5fe31ca22ed8d7f0423b2aabf0 Mon Sep 17 00:00:00 2001 From: George Atkinson Date: Sat, 19 Dec 2020 22:22:25 +0000 Subject: [PATCH 3/4] Added refcount for mouse button event Added refcount to prevent the mouse capture from releasing before all mouse buttons have been released. --- src/win/window.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/win/window.rs b/src/win/window.rs index 051f01d2..21bc9785 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -68,6 +68,8 @@ unsafe extern "system" fn wnd_proc( let mut window = Window { hwnd }; let mut window = crate::Window(&mut window); + let mut mouse_button_counter = window_state.borrow().mouse_button_counter; + match msg { WM_MOUSEMOVE => { let x = (lparam & 0xFFFF) as i32; @@ -104,11 +106,16 @@ unsafe extern "system" fn wnd_proc( if let Some(button) = button { let event = match msg { WM_LBUTTONDOWN | WM_MBUTTONDOWN | WM_RBUTTONDOWN | WM_XBUTTONDOWN => { + mouse_button_counter = mouse_button_counter.saturating_add(1); window.0.set_mouse_capture(); MouseEvent::ButtonPressed(button) } WM_LBUTTONUP | WM_MBUTTONUP | WM_RBUTTONUP | WM_XBUTTONUP => { - window.0.release_mouse_capture(); + mouse_button_counter = mouse_button_counter.saturating_sub(1); + if mouse_button_counter == 0 { + window.0.release_mouse_capture(); + } + MouseEvent::ButtonReleased(button) } _ => { @@ -158,6 +165,8 @@ unsafe extern "system" fn wnd_proc( } _ => {} } + + window_state.borrow_mut().mouse_button_counter = mouse_button_counter; } return DefWindowProcA(hwnd, msg, wparam, lparam); @@ -191,6 +200,7 @@ struct WindowState { window_class: ATOM, window_info: WindowInfo, keyboard_state: KeyboardState, + mouse_button_counter: usize, handler: Box, } @@ -296,6 +306,7 @@ impl Window { window_class, window_info, keyboard_state: KeyboardState::new(), + mouse_button_counter: 0, handler, })); From fa504fd86333910b97a19f137cdaff8ed95e4f82 Mon Sep 17 00:00:00 2001 From: George Atkinson Date: Sat, 19 Dec 2020 23:32:03 +0000 Subject: [PATCH 4/4] Removed unnecessary function from window --- src/win/window.rs | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/src/win/window.rs b/src/win/window.rs index 21bc9785..b06e657b 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -106,14 +106,16 @@ unsafe extern "system" fn wnd_proc( if let Some(button) = button { let event = match msg { WM_LBUTTONDOWN | WM_MBUTTONDOWN | WM_RBUTTONDOWN | WM_XBUTTONDOWN => { + // Capture the mouse cursor on button down mouse_button_counter = mouse_button_counter.saturating_add(1); - window.0.set_mouse_capture(); + SetCapture(hwnd); MouseEvent::ButtonPressed(button) } WM_LBUTTONUP | WM_MBUTTONUP | WM_RBUTTONUP | WM_XBUTTONUP => { + // Release the mouse cursor capture when all buttons are released mouse_button_counter = mouse_button_counter.saturating_sub(1); if mouse_button_counter == 0 { - window.0.release_mouse_capture(); + ReleaseCapture(); } MouseEvent::ButtonReleased(button) @@ -320,29 +322,6 @@ impl Window { } } } - - // Captures the mouse cursor for this window - pub fn set_mouse_capture(&self) { - unsafe { - if IsWindow(self.hwnd) != 0 { - SetCapture(self.hwnd); - } - } - } - - // Returns true if this window has captured the mouse - pub fn get_mouse_capture(&self) -> bool { - unsafe { - GetCapture() == self.hwnd - } - } - - // Releases the mouse capture from all windows - pub fn release_mouse_capture(&self) { - unsafe { - ReleaseCapture(); - } - } } unsafe impl HasRawWindowHandle for Window {