diff --git a/CHANGELOG.md b/CHANGELOG.md index deb0d492..0b58731d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ And please only add new entries to the top of this list, right below the `# Unre - On Web, fix pen treated as mouse input. - On Web, send mouse position on button release as well. - On Web, fix touch input not gaining or loosing focus. +- **Breaking:** On Web, dropped support for Safari versions below 13. # 0.28.6 diff --git a/Cargo.toml b/Cargo.toml index 44f1d153..537ab4a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,7 +132,6 @@ package = "web-sys" version = "0.3.22" features = [ 'console', - "AddEventListenerOptions", 'CssStyleDeclaration', 'BeforeUnloadEvent', 'Document', @@ -147,7 +146,6 @@ features = [ 'KeyboardEvent', 'MediaQueryList', 'MediaQueryListEvent', - 'MouseEvent', 'Node', 'PointerEvent', 'Window', diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 3e52e63f..da35477c 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -352,11 +352,10 @@ impl EventLoopWindowTarget { let has_focus = has_focus.clone(); move |pointer_id, position, button, active_modifiers| { - let focus_changed = - (!has_focus.replace(true)).then_some(Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::Focused(true), - }); + let focus_changed = (!has_focus.replace(true)).then_some(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::Focused(true), + }); let modifiers_changed = (modifiers.get() != active_modifiers).then(|| { modifiers.set(active_modifiers); @@ -393,11 +392,10 @@ impl EventLoopWindowTarget { let has_focus = has_focus.clone(); move |device_id, location, force| { - let focus_changed = - (!has_focus.replace(true)).then_some(Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::Focused(true), - }); + let focus_changed = (!has_focus.replace(true)).then_some(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::Focused(true), + }); runner.send_events(focus_changed.into_iter().chain(iter::once( Event::WindowEvent { diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 2b676434..0e8d4b97 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -1,5 +1,6 @@ use super::event_handle::EventListenerHandle; use super::media_query_handle::MediaQueryListHandle; +use super::pointer::PointerHandler; use super::{event, ButtonsState}; use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize}; use crate::error::OsError as RootOE; @@ -16,13 +17,9 @@ use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::{closure::Closure, JsCast, JsValue}; use wasm_bindgen_futures::JsFuture; use web_sys::{ - AddEventListenerOptions, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, - MediaQueryListEvent, MouseEvent, WheelEvent, + Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, MediaQueryListEvent, WheelEvent, }; -mod mouse_handler; -mod pointer_handler; - #[allow(dead_code)] pub struct Canvas { common: Common, @@ -35,12 +32,12 @@ pub struct Canvas { on_mouse_wheel: Option>, on_fullscreen_change: Option>, on_dark_mode: Option, - mouse_state: MouseState, + pointer_handler: PointerHandler, } -struct Common { +pub struct Common { /// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained. - raw: HtmlCanvasElement, + pub raw: HtmlCanvasElement, wants_fullscreen: Rc>, } @@ -74,12 +71,6 @@ impl Canvas { .map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?; } - let mouse_state = if has_pointer_event() { - MouseState::HasPointerEvent(pointer_handler::PointerHandler::new()) - } else { - MouseState::NoPointerEvent(mouse_handler::MouseHandler::new()) - }; - Ok(Canvas { common: Common { raw: canvas, @@ -94,7 +85,7 @@ impl Canvas { on_mouse_wheel: None, on_fullscreen_change: None, on_dark_mode: None, - mouse_state, + pointer_handler: PointerHandler::new(), }) } @@ -225,20 +216,14 @@ impl Canvas { where F: 'static + FnMut(i32, ModifiersState), { - match &mut self.mouse_state { - MouseState::HasPointerEvent(h) => h.on_cursor_leave(&self.common, handler), - MouseState::NoPointerEvent(h) => h.on_cursor_leave(&self.common, handler), - } + self.pointer_handler.on_cursor_leave(&self.common, handler) } pub fn on_cursor_enter(&mut self, handler: F) where F: 'static + FnMut(i32, ModifiersState), { - match &mut self.mouse_state { - MouseState::HasPointerEvent(h) => h.on_cursor_enter(&self.common, handler), - MouseState::NoPointerEvent(h) => h.on_cursor_enter(&self.common, handler), - } + self.pointer_handler.on_cursor_enter(&self.common, handler) } pub fn on_mouse_release(&mut self, mouse_handler: M, touch_handler: T) @@ -246,12 +231,8 @@ impl Canvas { M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), T: 'static + FnMut(i32, PhysicalPosition, Force), { - match &mut self.mouse_state { - MouseState::HasPointerEvent(h) => { - h.on_mouse_release(&self.common, mouse_handler, touch_handler) - } - MouseState::NoPointerEvent(h) => h.on_mouse_release(&self.common, mouse_handler), - } + self.pointer_handler + .on_mouse_release(&self.common, mouse_handler, touch_handler) } pub fn on_mouse_press(&mut self, mouse_handler: M, touch_handler: T) @@ -259,12 +240,8 @@ impl Canvas { M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), T: 'static + FnMut(i32, PhysicalPosition, Force), { - match &mut self.mouse_state { - MouseState::HasPointerEvent(h) => { - h.on_mouse_press(&self.common, mouse_handler, touch_handler) - } - MouseState::NoPointerEvent(h) => h.on_mouse_press(&self.common, mouse_handler), - } + self.pointer_handler + .on_mouse_press(&self.common, mouse_handler, touch_handler) } pub fn on_cursor_move( @@ -280,28 +257,21 @@ impl Canvas { T: 'static + FnMut(i32, PhysicalPosition, Force), B: 'static + FnMut(i32, PhysicalPosition, ButtonsState, MouseButton), { - match &mut self.mouse_state { - MouseState::HasPointerEvent(h) => h.on_cursor_move( - &self.common, - modifier_handler, - mouse_handler, - touch_handler, - button_handler, - prevent_default, - ), - MouseState::NoPointerEvent(h) => { - h.on_cursor_move(&self.common, modifier_handler, mouse_handler) - } - } + self.pointer_handler.on_cursor_move( + &self.common, + modifier_handler, + mouse_handler, + touch_handler, + button_handler, + prevent_default, + ) } pub fn on_touch_cancel(&mut self, handler: F) where F: 'static + FnMut(i32, PhysicalPosition, Force), { - if let MouseState::HasPointerEvent(h) = &mut self.mouse_state { - h.on_touch_cancel(&self.common, handler) - } + self.pointer_handler.on_touch_cancel(&self.common, handler) } pub fn on_mouse_wheel(&mut self, mut handler: F, prevent_default: bool) @@ -358,15 +328,12 @@ impl Canvas { self.on_mouse_wheel = None; self.on_fullscreen_change = None; self.on_dark_mode = None; - match &mut self.mouse_state { - MouseState::HasPointerEvent(h) => h.remove_listeners(), - MouseState::NoPointerEvent(h) => h.remove_listeners(), - } + self.pointer_handler.remove_listeners() } } impl Common { - fn add_event( + pub fn add_event( &self, event_name: &'static str, mut handler: F, @@ -391,7 +358,7 @@ impl Common { // The difference between add_event and add_user_event is that the latter has a special meaning // for browser security. A user event is a deliberate action by the user (like a mouse or key // press) and is the only time things like a fullscreen request may be successfully completed.) - fn add_user_event( + pub fn add_user_event( &self, event_name: &'static str, mut handler: F, @@ -415,43 +382,6 @@ impl Common { }) } - // This function is used exclusively for mouse events (not pointer events). - // Due to the need for mouse capturing, the mouse event handlers are added - // to the window instead of the canvas element, which requires special - // handling to control event propagation. - fn add_window_mouse_event( - &self, - event_name: &'static str, - mut handler: F, - ) -> EventListenerHandle - where - F: 'static + FnMut(MouseEvent), - { - let wants_fullscreen = self.wants_fullscreen.clone(); - let canvas = self.raw.clone(); - let window = web_sys::window().expect("Failed to obtain window"); - - let closure = Closure::wrap(Box::new(move |event: MouseEvent| { - handler(event); - - if *wants_fullscreen.borrow() { - canvas - .request_fullscreen() - .expect("Failed to enter fullscreen"); - *wants_fullscreen.borrow_mut() = false; - } - }) as Box); - - let listener = EventListenerHandle::with_options( - &window, - event_name, - closure, - AddEventListenerOptions::new().capture(true), - ); - - listener - } - pub fn request_fullscreen(&self) { #[wasm_bindgen] extern "C" { @@ -483,21 +413,3 @@ impl Common { super::is_fullscreen(&self.raw) } } - -/// Pointer events are supported or not. -enum MouseState { - HasPointerEvent(pointer_handler::PointerHandler), - NoPointerEvent(mouse_handler::MouseHandler), -} - -/// Returns whether pointer events are supported. -/// Used to decide whether to use pointer events -/// or plain mouse events. Note that Safari -/// doesn't support pointer events now. -fn has_pointer_event() -> bool { - if let Some(window) = web_sys::window() { - window.get("PointerEvent").is_some() - } else { - false - } -} diff --git a/src/platform_impl/web/web_sys/canvas/mouse_handler.rs b/src/platform_impl/web/web_sys/canvas/mouse_handler.rs deleted file mode 100644 index 73213963..00000000 --- a/src/platform_impl/web/web_sys/canvas/mouse_handler.rs +++ /dev/null @@ -1,234 +0,0 @@ -use super::event; -use super::EventListenerHandle; -use crate::dpi::PhysicalPosition; -use crate::event::MouseButton; -use crate::keyboard::ModifiersState; - -use std::cell::RefCell; -use std::rc::Rc; - -use web_sys::{EventTarget, MouseEvent}; - -type MouseLeaveHandler = Rc>>>; - -#[allow(dead_code)] -pub(super) struct MouseHandler { - on_mouse_leave: Option>, - on_mouse_enter: Option>, - on_mouse_move: Option>, - on_mouse_press: Option>, - on_mouse_release: Option>, - on_mouse_leave_handler: MouseLeaveHandler, - mouse_capture_state: Rc>, -} - -#[derive(PartialEq, Eq)] -pub(super) enum MouseCaptureState { - NotCaptured, - Captured, - OtherElement, -} - -impl MouseHandler { - pub fn new() -> Self { - Self { - on_mouse_leave: None, - on_mouse_enter: None, - on_mouse_move: None, - on_mouse_press: None, - on_mouse_release: None, - on_mouse_leave_handler: Rc::new(RefCell::new(None)), - mouse_capture_state: Rc::new(RefCell::new(MouseCaptureState::NotCaptured)), - } - } - pub fn on_cursor_leave(&mut self, canvas_common: &super::Common, handler: F) - where - F: 'static + FnMut(i32, ModifiersState), - { - *self.on_mouse_leave_handler.borrow_mut() = Some(Box::new(handler)); - let on_mouse_leave_handler = self.on_mouse_leave_handler.clone(); - let mouse_capture_state = self.mouse_capture_state.clone(); - self.on_mouse_leave = Some(canvas_common.add_event( - "mouseout", - move |event: MouseEvent| { - // If the mouse is being captured, it is always considered - // to be "within" the the canvas, until the capture has been - // released, therefore we don't send cursor leave events. - if *mouse_capture_state.borrow() != MouseCaptureState::Captured { - if let Some(handler) = on_mouse_leave_handler.borrow_mut().as_mut() { - let modifiers = event::mouse_modifiers(&event); - handler(0, modifiers); - } - } - }, - )); - } - - pub fn on_cursor_enter(&mut self, canvas_common: &super::Common, mut handler: F) - where - F: 'static + FnMut(i32, ModifiersState), - { - let mouse_capture_state = self.mouse_capture_state.clone(); - self.on_mouse_enter = Some(canvas_common.add_event( - "mouseover", - move |event: MouseEvent| { - // We don't send cursor leave events when the mouse is being - // captured, therefore we do the same with cursor enter events. - if *mouse_capture_state.borrow() != MouseCaptureState::Captured { - let modifiers = event::mouse_modifiers(&event); - handler(0, modifiers); - } - }, - )); - } - - pub fn on_mouse_release(&mut self, canvas_common: &super::Common, mut handler: F) - where - F: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), - { - let on_mouse_leave_handler = self.on_mouse_leave_handler.clone(); - let mouse_capture_state = self.mouse_capture_state.clone(); - let canvas = canvas_common.raw.clone(); - self.on_mouse_release = Some(canvas_common.add_window_mouse_event( - "mouseup", - move |event: MouseEvent| { - let canvas = canvas.clone(); - let mut mouse_capture_state = mouse_capture_state.borrow_mut(); - match &*mouse_capture_state { - // Shouldn't happen but we'll just ignore it. - MouseCaptureState::NotCaptured => return, - MouseCaptureState::OtherElement => { - if event.buttons() == 0 { - // No buttons are pressed anymore so reset - // the capturing state. - *mouse_capture_state = MouseCaptureState::NotCaptured; - } - return; - } - MouseCaptureState::Captured => {} - } - event.stop_propagation(); - handler( - 0, - event::mouse_position(&event).to_physical(super::super::scale_factor()), - event::mouse_button(&event).expect("no mouse button released"), - event::mouse_modifiers(&event), - ); - if event - .target() - .map_or(false, |target| target != EventTarget::from(canvas)) - { - // Since we do not send cursor leave events while the - // cursor is being captured, we instead send it after - // the capture has been released. - if let Some(handler) = on_mouse_leave_handler.borrow_mut().as_mut() { - let modifiers = event::mouse_modifiers(&event); - handler(0, modifiers); - } - } - if event.buttons() == 0 { - // No buttons are pressed anymore so reset - // the capturing state. - *mouse_capture_state = MouseCaptureState::NotCaptured; - } - }, - )); - } - - pub fn on_mouse_press(&mut self, canvas_common: &super::Common, mut handler: F) - where - F: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), - { - let mouse_capture_state = self.mouse_capture_state.clone(); - let canvas = canvas_common.raw.clone(); - self.on_mouse_press = Some(canvas_common.add_window_mouse_event( - "mousedown", - move |event: MouseEvent| { - let canvas = canvas.clone(); - let mut mouse_capture_state = mouse_capture_state.borrow_mut(); - match &*mouse_capture_state { - MouseCaptureState::NotCaptured - if event - .target() - .map_or(false, |target| target != EventTarget::from(canvas)) => - { - // The target isn't our canvas which means the - // mouse is pressed outside of it. - *mouse_capture_state = MouseCaptureState::OtherElement; - return; - } - MouseCaptureState::OtherElement => return, - _ => {} - } - *mouse_capture_state = MouseCaptureState::Captured; - event.stop_propagation(); - handler( - 0, - event::mouse_position(&event).to_physical(super::super::scale_factor()), - event::mouse_button(&event).expect("no mouse button pressed"), - event::mouse_modifiers(&event), - ); - }, - )); - } - - pub fn on_cursor_move( - &mut self, - canvas_common: &super::Common, - mut modifier_handler: MOD, - mut mouse_handler: M, - ) where - MOD: 'static + FnMut(ModifiersState), - M: 'static + FnMut(i32, PhysicalPosition, PhysicalPosition), - { - let mouse_capture_state = self.mouse_capture_state.clone(); - let canvas = canvas_common.raw.clone(); - self.on_mouse_move = Some(canvas_common.add_window_mouse_event( - "mousemove", - move |event: MouseEvent| { - modifier_handler(event::mouse_modifiers(&event)); - - let canvas = canvas.clone(); - let mouse_capture_state = mouse_capture_state.borrow(); - let is_over_canvas = event - .target() - .map_or(false, |target| target == EventTarget::from(canvas.clone())); - match &*mouse_capture_state { - // Don't handle hover events outside of canvas. - MouseCaptureState::NotCaptured | MouseCaptureState::OtherElement - if !is_over_canvas => {} - // If hovering over the canvas, just send the cursor move event. - MouseCaptureState::NotCaptured - | MouseCaptureState::OtherElement - | MouseCaptureState::Captured => { - if *mouse_capture_state == MouseCaptureState::Captured { - event.stop_propagation(); - } - let mouse_pos = if is_over_canvas { - event::mouse_position(&event) - } else { - // Since the mouse is not on the canvas, we cannot - // use `offsetX`/`offsetY`. - event::mouse_position_by_client(&event, &canvas) - }; - let mouse_delta = event::mouse_delta(&event); - mouse_handler( - 0, - mouse_pos.to_physical(super::super::scale_factor()), - mouse_delta.to_physical(super::super::scale_factor()), - ); - } - } - }, - )); - } - - pub fn remove_listeners(&mut self) { - self.on_mouse_leave = None; - self.on_mouse_enter = None; - self.on_mouse_move = None; - self.on_mouse_press = None; - self.on_mouse_release = None; - *self.on_mouse_leave_handler.borrow_mut() = None; - } -} diff --git a/src/platform_impl/web/web_sys/event_handle.rs b/src/platform_impl/web/web_sys/event_handle.rs index 5a0a3531..9f9be48a 100644 --- a/src/platform_impl/web/web_sys/event_handle.rs +++ b/src/platform_impl/web/web_sys/event_handle.rs @@ -1,7 +1,7 @@ use wasm_bindgen::{prelude::Closure, JsCast}; -use web_sys::{AddEventListenerOptions, EventListenerOptions, EventTarget}; +use web_sys::{EventListenerOptions, EventTarget}; -pub(super) struct EventListenerHandle { +pub struct EventListenerHandle { target: EventTarget, event_type: &'static str, listener: Closure, @@ -24,31 +24,6 @@ impl EventListenerHandle { options: EventListenerOptions::new(), } } - - pub fn with_options( - target: &U, - event_type: &'static str, - listener: Closure, - options: &AddEventListenerOptions, - ) -> Self - where - U: Clone + Into, - { - let target = target.clone().into(); - target - .add_event_listener_with_callback_and_add_event_listener_options( - event_type, - listener.as_ref().unchecked_ref(), - options, - ) - .expect("Failed to add event listener"); - EventListenerHandle { - target, - event_type, - listener, - options: options.clone().unchecked_into(), - } - } } impl Drop for EventListenerHandle { diff --git a/src/platform_impl/web/web_sys/mod.rs b/src/platform_impl/web/web_sys/mod.rs index 454204c7..6a1f556e 100644 --- a/src/platform_impl/web/web_sys/mod.rs +++ b/src/platform_impl/web/web_sys/mod.rs @@ -2,6 +2,7 @@ mod canvas; mod event; mod event_handle; mod media_query_handle; +mod pointer; mod scaling; mod timeout; diff --git a/src/platform_impl/web/web_sys/canvas/pointer_handler.rs b/src/platform_impl/web/web_sys/pointer.rs similarity index 84% rename from src/platform_impl/web/web_sys/canvas/pointer_handler.rs rename to src/platform_impl/web/web_sys/pointer.rs index 105f645b..ff1aadb7 100644 --- a/src/platform_impl/web/web_sys/canvas/pointer_handler.rs +++ b/src/platform_impl/web/web_sys/pointer.rs @@ -1,5 +1,6 @@ +use super::canvas::Common; use super::event; -use super::EventListenerHandle; +use super::event_handle::EventListenerHandle; use crate::dpi::PhysicalPosition; use crate::event::{Force, MouseButton}; use crate::keyboard::ModifiersState; @@ -31,7 +32,7 @@ impl PointerHandler { } } - pub fn on_cursor_leave(&mut self, canvas_common: &super::Common, mut handler: F) + pub fn on_cursor_leave(&mut self, canvas_common: &Common, mut handler: F) where F: 'static + FnMut(i32, ModifiersState), { @@ -50,7 +51,7 @@ impl PointerHandler { )); } - pub fn on_cursor_enter(&mut self, canvas_common: &super::Common, mut handler: F) + pub fn on_cursor_enter(&mut self, canvas_common: &Common, mut handler: F) where F: 'static + FnMut(i32, ModifiersState), { @@ -71,7 +72,7 @@ impl PointerHandler { pub fn on_mouse_release( &mut self, - canvas_common: &super::Common, + canvas_common: &Common, mut mouse_handler: M, mut touch_handler: T, ) where @@ -81,29 +82,26 @@ impl PointerHandler { let canvas = canvas_common.raw.clone(); self.on_pointer_release = Some(canvas_common.add_user_event( "pointerup", - move |event: PointerEvent| { - match event.pointer_type().as_str() { - "touch" => touch_handler( - event.pointer_id(), - event::touch_position(&event, &canvas) - .to_physical(super::super::scale_factor()), - Force::Normalized(event.pressure() as f64), - ), - "mouse" => mouse_handler( - event.pointer_id(), - event::mouse_position(&event).to_physical(super::super::scale_factor()), - event::mouse_button(&event).expect("no mouse button released"), - event::mouse_modifiers(&event), - ), - _ => (), - } + move |event: PointerEvent| match event.pointer_type().as_str() { + "touch" => touch_handler( + event.pointer_id(), + event::touch_position(&event, &canvas).to_physical(super::scale_factor()), + Force::Normalized(event.pressure() as f64), + ), + "mouse" => mouse_handler( + event.pointer_id(), + event::mouse_position(&event).to_physical(super::scale_factor()), + event::mouse_button(&event).expect("no mouse button released"), + event::mouse_modifiers(&event), + ), + _ => (), }, )); } pub fn on_mouse_press( &mut self, - canvas_common: &super::Common, + canvas_common: &Common, mut mouse_handler: M, mut touch_handler: T, ) where @@ -119,14 +117,14 @@ impl PointerHandler { touch_handler( event.pointer_id(), event::touch_position(&event, &canvas) - .to_physical(super::super::scale_factor()), + .to_physical(super::scale_factor()), Force::Normalized(event.pressure() as f64), ); } "mouse" => { mouse_handler( event.pointer_id(), - event::mouse_position(&event).to_physical(super::super::scale_factor()), + event::mouse_position(&event).to_physical(super::scale_factor()), event::mouse_button(&event).expect("no mouse button pressed"), event::mouse_modifiers(&event), ); @@ -144,7 +142,7 @@ impl PointerHandler { pub fn on_cursor_move( &mut self, - canvas_common: &super::Common, + canvas_common: &Common, mut modifier_handler: MOD, mut mouse_handler: M, mut touch_handler: T, @@ -196,7 +194,7 @@ impl PointerHandler { button_handler( id, - event::mouse_position(&event).to_physical(super::super::scale_factor()), + event::mouse_position(&event).to_physical(super::scale_factor()), event::mouse_buttons(&event), button, ); @@ -227,13 +225,13 @@ impl PointerHandler { match pointer_type.as_str() { "mouse" => mouse_handler( id, - event::mouse_position(&event).to_physical(super::super::scale_factor()), - event::mouse_delta(&event).to_physical(super::super::scale_factor()), + event::mouse_position(&event).to_physical(super::scale_factor()), + event::mouse_delta(&event).to_physical(super::scale_factor()), ), "touch" => touch_handler( id, event::touch_position(&event, &canvas) - .to_physical(super::super::scale_factor()), + .to_physical(super::scale_factor()), Force::Normalized(event.pressure() as f64), ), _ => unreachable!("didn't return early before"), @@ -243,7 +241,7 @@ impl PointerHandler { )); } - pub fn on_touch_cancel(&mut self, canvas_common: &super::Common, mut handler: F) + pub fn on_touch_cancel(&mut self, canvas_common: &Common, mut handler: F) where F: 'static + FnMut(i32, PhysicalPosition, Force), { @@ -254,8 +252,7 @@ impl PointerHandler { if event.pointer_type() == "touch" { handler( event.pointer_id(), - event::touch_position(&event, &canvas) - .to_physical(super::super::scale_factor()), + event::touch_position(&event, &canvas).to_physical(super::scale_factor()), Force::Normalized(event.pressure() as f64), ); }