From a6d180cefbc1b5046e324e033c93f529f416fdda Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sat, 11 Jan 2020 11:45:52 +0300 Subject: [PATCH] On Wayland, fix coordinates in mouse events when scale factor isn't 1 (#1385) * On Wayland, fix coordinates in mouse events when scale factor isn't 1 * Refactor mouse_focus to be a surface instead of WindowId --- CHANGELOG.md | 1 + src/platform_impl/linux/wayland/pointer.rs | 28 +++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dec9f155..029bf121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - On X11, fix deadlock on window state when handling certain window events. - `WindowBuilder` now implements `Default`. - **Breaking:** `WindowEvent::CursorMoved` changed to `f64` units, preserving high-precision data supplied by most backends +- On Wayland, fix coordinates in mouse events when scale factor isn't 1 # 0.20.0 (2020-01-05) diff --git a/src/platform_impl/linux/wayland/pointer.rs b/src/platform_impl/linux/wayland/pointer.rs index f84264c3..2ba6c934 100644 --- a/src/platform_impl/linux/wayland/pointer.rs +++ b/src/platform_impl/linux/wayland/pointer.rs @@ -7,10 +7,13 @@ use crate::event::{ use super::{ event_loop::{CursorManager, EventsSink}, + make_wid, window::WindowStore, DeviceId, }; +use smithay_client_toolkit::surface; + use smithay_client_toolkit::reexports::client::protocol::{ wl_pointer::{self, Event as PtrEvent, WlPointer}, wl_seat, @@ -36,6 +39,7 @@ pub fn implement_pointer( cursor_manager: Arc>, ) -> WlPointer { seat.get_pointer(|pointer| { + // Currently focused winit surface let mut mouse_focus = None; let mut axis_buffer = None; let mut axis_discrete_buffer = None; @@ -53,8 +57,10 @@ pub fn implement_pointer( .. } => { let wid = store.find_wid(&surface); + if let Some(wid) = wid { - mouse_focus = Some(wid); + let scale_factor = surface::get_dpi_factor(&surface) as f64; + mouse_focus = Some(surface); // Reload cursor style only when we enter winit's surface. Calling // this function every time on `PtrEvent::Enter` could interfere with @@ -75,7 +81,8 @@ pub fn implement_pointer( device_id: crate::event::DeviceId( crate::platform_impl::DeviceId::Wayland(DeviceId), ), - position: (surface_x, surface_y).into(), + position: (surface_x * scale_factor, surface_y * scale_factor) + .into(), modifiers: modifiers_tracker.lock().unwrap().clone(), }, wid, @@ -101,13 +108,16 @@ pub fn implement_pointer( surface_y, .. } => { - if let Some(wid) = mouse_focus { + if let Some(surface) = mouse_focus.as_ref() { + let scale_factor = surface::get_dpi_factor(&surface) as f64; + let wid = make_wid(surface); sink.send_window_event( WindowEvent::CursorMoved { device_id: crate::event::DeviceId( crate::platform_impl::DeviceId::Wayland(DeviceId), ), - position: (surface_x, surface_y).into(), + position: (surface_x * scale_factor, surface_y * scale_factor) + .into(), modifiers: modifiers_tracker.lock().unwrap().clone(), }, wid, @@ -115,7 +125,7 @@ pub fn implement_pointer( } } PtrEvent::Button { button, state, .. } => { - if let Some(wid) = mouse_focus { + if let Some(surface) = mouse_focus.as_ref() { let state = match state { wl_pointer::ButtonState::Pressed => ElementState::Pressed, wl_pointer::ButtonState::Released => ElementState::Released, @@ -137,12 +147,13 @@ pub fn implement_pointer( button, modifiers: modifiers_tracker.lock().unwrap().clone(), }, - wid, + make_wid(surface), ); } } PtrEvent::Axis { axis, value, .. } => { - if let Some(wid) = mouse_focus { + if let Some(surface) = mouse_focus.as_ref() { + let wid = make_wid(surface); if pointer.as_ref().version() < 5 { let (mut x, mut y) = (0.0, 0.0); // old seat compatibility @@ -184,7 +195,8 @@ pub fn implement_pointer( PtrEvent::Frame => { let axis_buffer = axis_buffer.take(); let axis_discrete_buffer = axis_discrete_buffer.take(); - if let Some(wid) = mouse_focus { + if let Some(surface) = mouse_focus.as_ref() { + let wid = make_wid(surface); if let Some((x, y)) = axis_discrete_buffer { sink.send_window_event( WindowEvent::MouseWheel {