mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Add mouse event capturing when click-dragging out of a win32 window (#292)
* Add mouse event capturing when click-dragging out of a win32 window * Remove git merge conflict comments * Add changelog entry
This commit is contained in:
parent
4abcc164cd
commit
7daf27f389
|
@ -1,5 +1,9 @@
|
|||
# Unreleased
|
||||
|
||||
- Implement `MonitorId::get_dimensions` for Android.
|
||||
- Fixed windows not receiving mouse events when click-dragging the mouse outside the client area of a window, on Windows platforms.
|
||||
|
||||
=======
|
||||
# Version 0.11.0 (2018-02-09)
|
||||
|
||||
- Implement `MonitorId::get_dimensions` for Android.
|
||||
|
|
|
@ -102,7 +102,8 @@ impl EventsLoop {
|
|||
*context_stash.borrow_mut() = Some(ThreadLocalData {
|
||||
sender: tx,
|
||||
windows: HashMap::with_capacity(4),
|
||||
win32_block_loop: win32_block_loop_child
|
||||
win32_block_loop: win32_block_loop_child,
|
||||
mouse_buttons_down: 0
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -296,7 +297,8 @@ thread_local!(static CONTEXT_STASH: RefCell<Option<ThreadLocalData>> = RefCell::
|
|||
struct ThreadLocalData {
|
||||
sender: mpsc::Sender<Event>,
|
||||
windows: HashMap<HWND, Arc<Mutex<WindowState>>>,
|
||||
win32_block_loop: Arc<(Mutex<bool>, Condvar)>
|
||||
win32_block_loop: Arc<(Mutex<bool>, Condvar)>,
|
||||
mouse_buttons_down: u32
|
||||
}
|
||||
|
||||
// Utility function that dispatches an event on the current thread.
|
||||
|
@ -308,6 +310,32 @@ fn send_event(event: Event) {
|
|||
});
|
||||
}
|
||||
|
||||
/// Capture mouse input, allowing `window` to receive mouse events when the cursor is outside of
|
||||
/// the window.
|
||||
unsafe fn capture_mouse(window: HWND) {
|
||||
CONTEXT_STASH.with(|context_stash| {
|
||||
let mut context_stash = context_stash.borrow_mut();
|
||||
if let Some(context_stash) = context_stash.as_mut() {
|
||||
context_stash.mouse_buttons_down += 1;
|
||||
winuser::SetCapture(window);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Release mouse input, stopping windows on this thread from receiving mouse input when the cursor
|
||||
/// is outside the window.
|
||||
unsafe fn release_mouse() {
|
||||
CONTEXT_STASH.with(|context_stash| {
|
||||
let mut context_stash = context_stash.borrow_mut();
|
||||
if let Some(context_stash) = context_stash.as_mut() {
|
||||
context_stash.mouse_buttons_down = context_stash.mouse_buttons_down.saturating_sub(1);
|
||||
if context_stash.mouse_buttons_down == 0 {
|
||||
winuser::ReleaseCapture();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Any window whose callback is configured to this function will have its events propagated
|
||||
/// through the events loop of the thread the window was created in.
|
||||
//
|
||||
|
@ -550,6 +578,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::WindowEvent::MouseInput;
|
||||
use events::MouseButton::Left;
|
||||
use events::ElementState::Pressed;
|
||||
|
||||
capture_mouse(window);
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Left, modifiers: event::get_key_mods() }
|
||||
|
@ -561,6 +592,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::WindowEvent::MouseInput;
|
||||
use events::MouseButton::Left;
|
||||
use events::ElementState::Released;
|
||||
|
||||
release_mouse();
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Left, modifiers: event::get_key_mods() }
|
||||
|
@ -572,6 +606,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::WindowEvent::MouseInput;
|
||||
use events::MouseButton::Right;
|
||||
use events::ElementState::Pressed;
|
||||
|
||||
capture_mouse(window);
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Right, modifiers: event::get_key_mods() }
|
||||
|
@ -583,6 +620,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::WindowEvent::MouseInput;
|
||||
use events::MouseButton::Right;
|
||||
use events::ElementState::Released;
|
||||
|
||||
release_mouse();
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Right, modifiers: event::get_key_mods() }
|
||||
|
@ -594,6 +634,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::WindowEvent::MouseInput;
|
||||
use events::MouseButton::Middle;
|
||||
use events::ElementState::Pressed;
|
||||
|
||||
capture_mouse(window);
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Middle, modifiers: event::get_key_mods() }
|
||||
|
@ -605,6 +648,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::WindowEvent::MouseInput;
|
||||
use events::MouseButton::Middle;
|
||||
use events::ElementState::Released;
|
||||
|
||||
release_mouse();
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Middle, modifiers: event::get_key_mods() }
|
||||
|
@ -617,6 +663,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::MouseButton::Other;
|
||||
use events::ElementState::Pressed;
|
||||
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);
|
||||
|
||||
capture_mouse(window);
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Other(xbutton as u8), modifiers: event::get_key_mods() }
|
||||
|
@ -629,6 +678,9 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT,
|
|||
use events::MouseButton::Other;
|
||||
use events::ElementState::Released;
|
||||
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);
|
||||
|
||||
release_mouse();
|
||||
|
||||
send_event(Event::WindowEvent {
|
||||
window_id: SuperWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Other(xbutton as u8), modifiers: event::get_key_mods() }
|
||||
|
|
Loading…
Reference in a new issue