From 5213d1fd6ee05ef8d43f8840710bc2ee72f53732 Mon Sep 17 00:00:00 2001 From: Simon Heath Date: Tue, 26 Nov 2019 10:29:07 -0500 Subject: [PATCH] Add positions to mouse click events. For the sake of argument. And catharsis. --- src/event.rs | 1 + src/platform_impl/linux/wayland/pointer.rs | 8 +++++-- .../linux/x11/event_processor.rs | 12 ++++++++++ .../web/event_loop/window_target.rs | 6 +++-- src/platform_impl/web/stdweb/canvas.rs | 6 +++-- src/platform_impl/web/web_sys/canvas.rs | 6 +++-- src/platform_impl/windows/event_loop.rs | 23 +++++++++++++++++++ 7 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/event.rs b/src/event.rs index ff94aa84e4..c0f79bdc9e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -165,6 +165,7 @@ pub enum WindowEvent { state: ElementState, button: MouseButton, modifiers: ModifiersState, + position: LogicalPosition, }, /// Touchpad pressure event. diff --git a/src/platform_impl/linux/wayland/pointer.rs b/src/platform_impl/linux/wayland/pointer.rs index cad299e470..4ac3a6d43c 100644 --- a/src/platform_impl/linux/wayland/pointer.rs +++ b/src/platform_impl/linux/wayland/pointer.rs @@ -46,6 +46,7 @@ pub fn implement_pointer( let mut sink = sink.lock().unwrap(); let store = store.lock().unwrap(); let mut cursor_manager = cursor_manager.lock().unwrap(); + let mut cursor_pos = (0.0, 0.0).into(); match evt { PtrEvent::Enter { surface, @@ -53,6 +54,7 @@ pub fn implement_pointer( surface_y, .. } => { + cursor_pos = (surface_x, surface_y).into(); let wid = store.find_wid(&surface); if let Some(wid) = wid { mouse_focus = Some(wid); @@ -69,7 +71,7 @@ pub fn implement_pointer( device_id: crate::event::DeviceId( crate::platform_impl::DeviceId::Wayland(DeviceId), ), - position: (surface_x, surface_y).into(), + position: cursor_pos, modifiers: modifiers_tracker.lock().unwrap().clone(), }, wid, @@ -97,13 +99,14 @@ pub fn implement_pointer( surface_y, .. } => { + cursor_pos = (surface_x, surface_y).into(); if let Some(wid) = mouse_focus { sink.send_window_event( WindowEvent::CursorMoved { device_id: crate::event::DeviceId( crate::platform_impl::DeviceId::Wayland(DeviceId), ), - position: (surface_x, surface_y).into(), + position: cursor_pos, modifiers: modifiers_tracker.lock().unwrap().clone(), }, wid, @@ -131,6 +134,7 @@ pub fn implement_pointer( ), state, button, + position: cursor_pos, modifiers: modifiers_tracker.lock().unwrap().clone(), }, wid, diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 2758aa3581..0bb682b816 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -651,6 +651,14 @@ impl EventProcessor { } else { Released }; + + let dpi_factor = self + .with_window(xev.event, |window| window.hidpi_factor()) + .unwrap_or(1.0); + let position = LogicalPosition::from_physical( + (xev.event_x as f64, xev.event_y as f64), + dpi_factor, + ); match xev.detail as u32 { ffi::Button1 => callback(Event::WindowEvent { window_id, @@ -659,6 +667,7 @@ impl EventProcessor { state, button: Left, modifiers, + position, }, }), ffi::Button2 => callback(Event::WindowEvent { @@ -668,6 +677,7 @@ impl EventProcessor { state, button: Middle, modifiers, + position, }, }), ffi::Button3 => callback(Event::WindowEvent { @@ -677,6 +687,7 @@ impl EventProcessor { state, button: Right, modifiers, + position, }, }), @@ -710,6 +721,7 @@ impl EventProcessor { state, button: Other(x as u8), modifiers, + position, }, }), } diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index d302edb87b..ce4bc663f1 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -128,7 +128,7 @@ impl WindowTarget { }); let runner = self.runner.clone(); - canvas.on_mouse_press(move |pointer_id, button, modifiers| { + canvas.on_mouse_press(move |pointer_id, button, modifiers, position| { runner.send_event(Event::WindowEvent { window_id: WindowId(id), event: WindowEvent::MouseInput { @@ -136,12 +136,13 @@ impl WindowTarget { state: ElementState::Pressed, button, modifiers, + position, }, }); }); let runner = self.runner.clone(); - canvas.on_mouse_release(move |pointer_id, button, modifiers| { + canvas.on_mouse_release(move |pointer_id, button, modifiers, position| { runner.send_event(Event::WindowEvent { window_id: WindowId(id), event: WindowEvent::MouseInput { @@ -149,6 +150,7 @@ impl WindowTarget { state: ElementState::Released, button, modifiers, + position, }, }); }); diff --git a/src/platform_impl/web/stdweb/canvas.rs b/src/platform_impl/web/stdweb/canvas.rs index a0ff5af2e8..8162e37769 100644 --- a/src/platform_impl/web/stdweb/canvas.rs +++ b/src/platform_impl/web/stdweb/canvas.rs @@ -183,26 +183,28 @@ impl Canvas { pub fn on_mouse_release(&mut self, mut handler: F) where - F: 'static + FnMut(i32, MouseButton, ModifiersState), + F: 'static + FnMut(i32, MouseButton, ModifiersState, LogicalPosition), { self.on_mouse_release = Some(self.add_user_event(move |event: PointerUpEvent| { handler( event.pointer_id(), event::mouse_button(&event), event::mouse_modifiers(&event), + event::mouse_position(&event), ); })); } pub fn on_mouse_press(&mut self, mut handler: F) where - F: 'static + FnMut(i32, MouseButton, ModifiersState), + F: 'static + FnMut(i32, MouseButton, ModifiersState, LogicalPosition), { self.on_mouse_press = Some(self.add_user_event(move |event: PointerDownEvent| { handler( event.pointer_id(), event::mouse_button(&event), event::mouse_modifiers(&event), + event::mouse_position(&event), ); })); } diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 0543055eb6..3b32c1610d 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -186,7 +186,7 @@ impl Canvas { pub fn on_mouse_release(&mut self, mut handler: F) where - F: 'static + FnMut(i32, MouseButton, ModifiersState), + F: 'static + FnMut(i32, MouseButton, ModifiersState, LogicalPosition), { self.on_mouse_release = Some(self.add_user_event( "pointerup", @@ -195,6 +195,7 @@ impl Canvas { event.pointer_id(), event::mouse_button(&event), event::mouse_modifiers(&event), + event::mouse_position(&event), ); }, )); @@ -202,7 +203,7 @@ impl Canvas { pub fn on_mouse_press(&mut self, mut handler: F) where - F: 'static + FnMut(i32, MouseButton, ModifiersState), + F: 'static + FnMut(i32, MouseButton, ModifiersState, LogicalPosition), { self.on_mouse_press = Some(self.add_user_event( "pointerdown", @@ -211,6 +212,7 @@ impl Canvas { event.pointer_id(), event::mouse_button(&event), event::mouse_modifiers(&event), + event::mouse_position(&event), ); }, )); diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 20c1dd0666..264298d082 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -907,6 +907,13 @@ fn normalize_pointer_pressure(pressure: u32) -> Option { } } +fn event_position(window: HWND, lparam: LPARAM) -> LogicalPosition { + let x = windowsx::GET_X_LPARAM(lparam) as f64; + let y = windowsx::GET_Y_LPARAM(lparam) as f64; + let dpi_factor = hwnd_scale_factor(window); + LogicalPosition::from_physical((x, y), dpi_factor) +} + /// 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. // @@ -1321,6 +1328,7 @@ unsafe extern "system" fn public_window_callback( use crate::event::{ElementState::Pressed, MouseButton::Left, WindowEvent::MouseInput}; capture_mouse(window, &mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1329,6 +1337,7 @@ unsafe extern "system" fn public_window_callback( state: Pressed, button: Left, modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1340,6 +1349,7 @@ unsafe extern "system" fn public_window_callback( }; release_mouse(&mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1348,6 +1358,7 @@ unsafe extern "system" fn public_window_callback( state: Released, button: Left, modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1359,6 +1370,7 @@ unsafe extern "system" fn public_window_callback( }; capture_mouse(window, &mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1367,6 +1379,7 @@ unsafe extern "system" fn public_window_callback( state: Pressed, button: Right, modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1378,6 +1391,7 @@ unsafe extern "system" fn public_window_callback( }; release_mouse(&mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1386,6 +1400,7 @@ unsafe extern "system" fn public_window_callback( state: Released, button: Right, modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1397,6 +1412,7 @@ unsafe extern "system" fn public_window_callback( }; capture_mouse(window, &mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1405,6 +1421,7 @@ unsafe extern "system" fn public_window_callback( state: Pressed, button: Middle, modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1416,6 +1433,7 @@ unsafe extern "system" fn public_window_callback( }; release_mouse(&mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1424,6 +1442,7 @@ unsafe extern "system" fn public_window_callback( state: Released, button: Middle, modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1436,6 +1455,7 @@ unsafe extern "system" fn public_window_callback( let xbutton = winuser::GET_XBUTTON_WPARAM(wparam); capture_mouse(window, &mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1444,6 +1464,7 @@ unsafe extern "system" fn public_window_callback( state: Pressed, button: Other(xbutton as u8), modifiers: event::get_key_mods(), + position, }, }); 0 @@ -1456,6 +1477,7 @@ unsafe extern "system" fn public_window_callback( let xbutton = winuser::GET_XBUTTON_WPARAM(wparam); release_mouse(&mut *subclass_input.window_state.lock()); + let position = event_position(window, lparam); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1464,6 +1486,7 @@ unsafe extern "system" fn public_window_callback( state: Released, button: Other(xbutton as u8), modifiers: event::get_key_mods(), + position, }, }); 0