diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index ef2e6478..f87cf934 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -198,51 +198,65 @@ impl EventLoopWindowTarget { prevent_default, ); - let runner = self.runner.clone(); - let modifiers = self.modifiers.clone(); - let has_focus_clone = has_focus.clone(); - canvas.on_cursor_leave(move |pointer_id, active_modifiers| { - let modifiers_changed = (has_focus_clone.get() && modifiers.get() != active_modifiers) - .then(|| { - modifiers.set(active_modifiers); - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::ModifiersChanged(active_modifiers.into()), + canvas.on_cursor_leave( + { + let runner = self.runner.clone(); + let has_focus = has_focus.clone(); + let modifiers = self.modifiers.clone(); + + move |active_modifiers| { + if has_focus.get() && modifiers.get() != active_modifiers { + modifiers.set(active_modifiers); + runner.send_event(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::ModifiersChanged(active_modifiers.into()), + }); } - }); + } + }, + { + let runner = self.runner.clone(); - runner.send_events(modifiers_changed.into_iter().chain(iter::once( - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::CursorLeft { - device_id: RootDeviceId(DeviceId(pointer_id)), - }, - }, - ))); - }); - - let runner = self.runner.clone(); - let modifiers = self.modifiers.clone(); - let has_focus_clone = has_focus.clone(); - canvas.on_cursor_enter(move |pointer_id, active_modifiers| { - let modifiers_changed = (has_focus_clone.get() && modifiers.get() != active_modifiers) - .then(|| { - modifiers.set(active_modifiers); - Event::WindowEvent { + move |pointer_id| { + runner.send_event(Event::WindowEvent { window_id: RootWindowId(id), - event: WindowEvent::ModifiersChanged(active_modifiers.into()), - } - }); + event: WindowEvent::CursorLeft { + device_id: RootDeviceId(DeviceId(pointer_id)), + }, + }); + } + }, + ); - runner.send_events(modifiers_changed.into_iter().chain(iter::once( - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::CursorEntered { - device_id: RootDeviceId(DeviceId(pointer_id)), - }, - }, - ))); - }); + canvas.on_cursor_enter( + { + let runner = self.runner.clone(); + let has_focus = has_focus.clone(); + let modifiers = self.modifiers.clone(); + + move |active_modifiers| { + if has_focus.get() && modifiers.get() != active_modifiers { + modifiers.set(active_modifiers); + runner.send_event(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::ModifiersChanged(active_modifiers.into()), + }); + } + } + }, + { + let runner = self.runner.clone(); + + move |pointer_id| { + runner.send_event(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::CursorEntered { + device_id: RootDeviceId(DeviceId(pointer_id)), + }, + }); + } + }, + ); canvas.on_cursor_move( { @@ -350,35 +364,43 @@ impl EventLoopWindowTarget { let runner = self.runner.clone(); let modifiers = self.modifiers.clone(); - move |pointer_id, position, button, active_modifiers| { - let modifiers_changed = (modifiers.get() != active_modifiers).then(|| { + move |active_modifiers| { + if modifiers.get() != active_modifiers { modifiers.set(active_modifiers); - Event::WindowEvent { + runner.send_event(Event::WindowEvent { window_id: RootWindowId(id), event: WindowEvent::ModifiersChanged(active_modifiers.into()), - } - }); + }) + } + } + }, + { + let runner = self.runner.clone(); + move |pointer_id, position, button| { // A mouse down event may come in without any prior CursorMoved events, // therefore we should send a CursorMoved event to make sure that the // user code has the correct cursor position. - runner.send_events(modifiers_changed.into_iter().chain([ - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::CursorMoved { - device_id: RootDeviceId(DeviceId(pointer_id)), - position, + runner.send_events( + [ + Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::CursorMoved { + device_id: RootDeviceId(DeviceId(pointer_id)), + position, + }, }, - }, - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::MouseInput { - device_id: RootDeviceId(DeviceId(pointer_id)), - state: ElementState::Pressed, - button, + Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::MouseInput { + device_id: RootDeviceId(DeviceId(pointer_id)), + state: ElementState::Pressed, + button, + }, }, - }, - ])); + ] + .into_iter(), + ); } }, { @@ -403,39 +425,46 @@ impl EventLoopWindowTarget { canvas.on_mouse_release( { let runner = self.runner.clone(); - let modifiers = self.modifiers.clone(); let has_focus = has_focus.clone(); + let modifiers = self.modifiers.clone(); - move |pointer_id, position, button, active_modifiers| { - let modifiers_changed = - (has_focus.get() && modifiers.get() != active_modifiers).then(|| { - modifiers.set(active_modifiers); - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::ModifiersChanged(active_modifiers.into()), - } + move |active_modifiers| { + if has_focus.get() && modifiers.get() != active_modifiers { + modifiers.set(active_modifiers); + runner.send_event(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::ModifiersChanged(active_modifiers.into()), }); + } + } + }, + { + let runner = self.runner.clone(); + move |pointer_id, position, button| { // A mouse up event may come in without any prior CursorMoved events, // therefore we should send a CursorMoved event to make sure that the // user code has the correct cursor position. - runner.send_events(modifiers_changed.into_iter().chain([ - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::CursorMoved { - device_id: RootDeviceId(DeviceId(pointer_id)), - position, + runner.send_events( + [ + Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::CursorMoved { + device_id: RootDeviceId(DeviceId(pointer_id)), + position, + }, }, - }, - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::MouseInput { - device_id: RootDeviceId(DeviceId(pointer_id)), - state: ElementState::Released, - button, + Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::MouseInput { + device_id: RootDeviceId(DeviceId(pointer_id)), + state: ElementState::Released, + button, + }, }, - }, - ])); + ] + .into_iter(), + ); } }, { diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 8ba5c24e..a7faeea4 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -212,40 +212,56 @@ impl Canvas { )); } - pub fn on_cursor_leave(&mut self, handler: F) + pub fn on_cursor_leave(&mut self, modifier_handler: MOD, mouse_handler: M) where - F: 'static + FnMut(i32, ModifiersState), - { - self.pointer_handler.on_cursor_leave(&self.common, handler) - } - - pub fn on_cursor_enter(&mut self, handler: F) - where - F: 'static + FnMut(i32, ModifiersState), - { - self.pointer_handler.on_cursor_enter(&self.common, handler) - } - - pub fn on_mouse_release(&mut self, mouse_handler: M, touch_handler: T) - where - M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), - T: 'static + FnMut(i32, PhysicalPosition, Force), + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32), { self.pointer_handler - .on_mouse_release(&self.common, mouse_handler, touch_handler) + .on_cursor_leave(&self.common, modifier_handler, mouse_handler) } - pub fn on_mouse_press( + pub fn on_cursor_enter(&mut self, modifier_handler: MOD, mouse_handler: M) + where + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32), + { + self.pointer_handler + .on_cursor_enter(&self.common, modifier_handler, mouse_handler) + } + + pub fn on_mouse_release( &mut self, + modifier_handler: MOD, + mouse_handler: M, + touch_handler: T, + ) where + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32, PhysicalPosition, MouseButton), + T: 'static + FnMut(i32, PhysicalPosition, Force), + { + self.pointer_handler.on_mouse_release( + &self.common, + modifier_handler, + mouse_handler, + touch_handler, + ) + } + + pub fn on_mouse_press( + &mut self, + modifier_handler: MOD, mouse_handler: M, touch_handler: T, prevent_default: bool, ) where - M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32, PhysicalPosition, MouseButton), T: 'static + FnMut(i32, PhysicalPosition, Force), { self.pointer_handler.on_mouse_press( &self.common, + modifier_handler, mouse_handler, touch_handler, prevent_default, diff --git a/src/platform_impl/web/web_sys/pointer.rs b/src/platform_impl/web/web_sys/pointer.rs index bb0c786f..c21fa4c3 100644 --- a/src/platform_impl/web/web_sys/pointer.rs +++ b/src/platform_impl/web/web_sys/pointer.rs @@ -32,13 +32,20 @@ impl PointerHandler { } } - pub fn on_cursor_leave(&mut self, canvas_common: &Common, mut handler: F) - where - F: 'static + FnMut(i32, ModifiersState), + pub fn on_cursor_leave( + &mut self, + canvas_common: &Common, + mut modifier_handler: MOD, + mut mouse_handler: M, + ) where + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32), { self.on_cursor_leave = Some(canvas_common.add_event( "pointerout", move |event: PointerEvent| { + modifier_handler(event::mouse_modifiers(&event)); + // touch events are handled separately // handling them here would produce duplicate mouse events, inconsistent with // other platforms. @@ -46,18 +53,25 @@ impl PointerHandler { return; } - handler(event.pointer_id(), event::mouse_modifiers(&event)); + mouse_handler(event.pointer_id()); }, )); } - pub fn on_cursor_enter(&mut self, canvas_common: &Common, mut handler: F) - where - F: 'static + FnMut(i32, ModifiersState), + pub fn on_cursor_enter( + &mut self, + canvas_common: &Common, + mut modifier_handler: MOD, + mut mouse_handler: M, + ) where + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32), { self.on_cursor_enter = Some(canvas_common.add_event( "pointerover", move |event: PointerEvent| { + modifier_handler(event::mouse_modifiers(&event)); + // touch events are handled separately // handling them here would produce duplicate mouse events, inconsistent with // other platforms. @@ -65,48 +79,55 @@ impl PointerHandler { return; } - handler(event.pointer_id(), event::mouse_modifiers(&event)); + mouse_handler(event.pointer_id()); }, )); } - pub fn on_mouse_release( + pub fn on_mouse_release( &mut self, canvas_common: &Common, + mut modifier_handler: MOD, mut mouse_handler: M, mut touch_handler: T, ) where - M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32, PhysicalPosition, MouseButton), T: 'static + FnMut(i32, PhysicalPosition, Force), { 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::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), - ), - _ => (), + move |event: PointerEvent| { + modifier_handler(event::mouse_modifiers(&event)); + + 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"), + ), + _ => (), + } }, )); } - pub fn on_mouse_press( + pub fn on_mouse_press( &mut self, canvas_common: &Common, + mut modifier_handler: MOD, mut mouse_handler: M, mut touch_handler: T, prevent_default: bool, ) where - M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), + MOD: 'static + FnMut(ModifiersState), + M: 'static + FnMut(i32, PhysicalPosition, MouseButton), T: 'static + FnMut(i32, PhysicalPosition, Force), { let canvas = canvas_common.raw.clone(); @@ -120,6 +141,8 @@ impl PointerHandler { let _ = canvas.focus(); } + modifier_handler(event::mouse_modifiers(&event)); + match event.pointer_type().as_str() { "touch" => { touch_handler( @@ -134,7 +157,6 @@ impl PointerHandler { event.pointer_id(), event::mouse_position(&event).to_physical(super::scale_factor()), event::mouse_button(&event).expect("no mouse button pressed"), - event::mouse_modifiers(&event), ); // Error is swallowed here since the error would occur every time the mouse is