diff options
author | Jonathan Schwender <55576758+jschwe@users.noreply.github.com> | 2025-04-15 11:59:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-15 09:59:30 +0000 |
commit | 1ea80c4335f7858f0550832e92635e3682ac5b0e (patch) | |
tree | 2453df9dca49b450b98b49eaf71060d1c383fb4a | |
parent | fe4306fc301b3651ed08017fff2178bfbde50ce6 (diff) | |
download | servo-1ea80c4335f7858f0550832e92635e3682ac5b0e.tar.gz servo-1ea80c4335f7858f0550832e92635e3682ac5b0e.zip |
touch: Fix panic with -Zconvert-mouse-to-touch (#36531)
- We previously converted all mouse move events to touch events, but we
should only be doing that while a mouse button is pressed (a finger
always does touch-down -> move -> up / cancel)
- Only consider Left mouse button for mouse-to-touch. We currently
already hardcode TouchId 0, which we would need to change in order to
properly support Multi-touch. Since we don't have any Multi-touch
gestures at the moment, we leave this unimplemented and simply only
evaluate the left mouse button.
Testing: Manual testing. We don't have servodriver support yet.
Fixes: #36526
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
-rw-r--r-- | components/compositing/touch.rs | 4 | ||||
-rw-r--r-- | components/compositing/webview.rs | 60 |
2 files changed, 47 insertions, 17 deletions
diff --git a/components/compositing/touch.rs b/components/compositing/touch.rs index 19df220a469..76d87732b32 100644 --- a/components/compositing/touch.rs +++ b/components/compositing/touch.rs @@ -282,6 +282,10 @@ impl TouchHandler { debug_assert!(old.is_some(), "Sequence already removed?"); } + pub fn try_get_current_touch_sequence(&self) -> Option<&TouchSequenceInfo> { + self.touch_sequence_map.get(&self.current_sequence_id) + } + pub fn get_current_touch_sequence_mut(&mut self) -> &mut TouchSequenceInfo { self.touch_sequence_map .get_mut(&self.current_sequence_id) diff --git a/components/compositing/webview.rs b/components/compositing/webview.rs index a845080a099..cc6b030a05e 100644 --- a/components/compositing/webview.rs +++ b/components/compositing/webview.rs @@ -338,27 +338,53 @@ impl WebView { if self.global.borrow().convert_mouse_to_touch { match event { InputEvent::MouseButton(event) => { - match event.action { - MouseButtonAction::Click => {}, - MouseButtonAction::Down => self.on_touch_down(TouchEvent::new( - TouchEventType::Down, - TouchId(0), - event.point, - )), - MouseButtonAction::Up => self.on_touch_up(TouchEvent::new( - TouchEventType::Up, - TouchId(0), - event.point, - )), + match (event.button, event.action) { + (MouseButton::Left, MouseButtonAction::Down) => self.on_touch_down( + TouchEvent::new(TouchEventType::Down, TouchId(0), event.point), + ), + (MouseButton::Left, MouseButtonAction::Up) => self.on_touch_up( + TouchEvent::new(TouchEventType::Up, TouchId(0), event.point), + ), + _ => {}, } return; }, InputEvent::MouseMove(event) => { - self.on_touch_move(TouchEvent::new( - TouchEventType::Move, - TouchId(0), - event.point, - )); + if let Some(state) = self.touch_handler.try_get_current_touch_sequence() { + // We assume that the debug option `-Z convert-mouse-to-touch` will only + // be used on devices without native touch input, so we can directly + // reuse the touch handler for tracking the state of pressed buttons. + match state.state { + TouchSequenceState::Touching | TouchSequenceState::Panning { .. } => { + self.on_touch_move(TouchEvent::new( + TouchEventType::Move, + TouchId(0), + event.point, + )); + }, + TouchSequenceState::MultiTouch => { + // Multitouch simulation currently is not implemented. + // Since we only get one mouse move event, we would need to + // dispatch one mouse move event per currently pressed mouse button. + }, + TouchSequenceState::Pinching => { + // We only have one mouse button, so Pinching should be impossible. + #[cfg(debug_assertions)] + log::error!( + "Touch handler is in Pinching state, which should be unreachable with \ + -Z convert-mouse-to-touch debug option." + ); + }, + TouchSequenceState::PendingFling { .. } | + TouchSequenceState::Flinging { .. } | + TouchSequenceState::PendingClick(_) | + TouchSequenceState::Finished => { + // Mouse movement without a button being pressed is not + // translated to touch events. + }, + } + } + // We don't want to (directly) dispatch mouse events when simulating touch input. return; }, _ => {}, |