Skip to content

Commit 2faae11

Browse files
committed
SwipeGestureHandler: better support of embedded SwipeGestureHandler's
- When checking the threshold, make sure that the change in the interrested dirrection is much more significant that the delta in the orthogonal direction (hence the `/ 2`) - Accept all mouse move event as we otherwise don't get them further if the event was delayed by another SwipeGestureHandler or flickable
1 parent 568d90d commit 2faae11

File tree

2 files changed

+31
-32
lines changed

2 files changed

+31
-32
lines changed

internal/core/items/input_items.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -521,20 +521,10 @@ impl Item for SwipeGestureHandler {
521521
InputEventFilterResult::Intercept
522522
} else if !self.pressed.get() {
523523
InputEventFilterResult::ForwardEvent
524+
} else if self.is_over_threshold(position) {
525+
InputEventFilterResult::Intercept
524526
} else {
525-
let pressed_pos = self.pressed_position();
526-
let dx = position.x - pressed_pos.x as Coord;
527-
let dy = position.y - pressed_pos.y as Coord;
528-
let threshold = super::flickable::DISTANCE_THRESHOLD.get();
529-
if (self.handle_swipe_down() && dy > threshold)
530-
|| (self.handle_swipe_up() && dy < -threshold)
531-
|| (self.handle_swipe_left() && dx < -threshold)
532-
|| (self.handle_swipe_right() && dx > threshold)
533-
{
534-
InputEventFilterResult::Intercept
535-
} else {
536-
InputEventFilterResult::ForwardAndInterceptGrab
537-
}
527+
InputEventFilterResult::ForwardAndInterceptGrab
538528
}
539529
}
540530
MouseEvent::Wheel { .. } => InputEventFilterResult::ForwardAndIgnore,
@@ -576,25 +566,20 @@ impl Item for SwipeGestureHandler {
576566
}
577567
MouseEvent::Moved { position } => {
578568
if !self.pressed.get() {
579-
return InputEventResult::EventIgnored;
569+
return InputEventResult::EventAccepted;
580570
}
581571
self.current_position.set(crate::lengths::logical_position_to_api(*position));
582-
if !self.swiping() {
583-
let pressed_pos = self.pressed_position();
584-
let dx = position.x - pressed_pos.x as Coord;
585-
let dy = position.y - pressed_pos.y as Coord;
586-
let threshold = super::flickable::DISTANCE_THRESHOLD.get();
587-
let start_swipe = (self.handle_swipe_down() && dy > threshold)
588-
|| (self.handle_swipe_up() && dy < -threshold)
589-
|| (self.handle_swipe_left() && dx < -threshold)
590-
|| (self.handle_swipe_right() && dx > threshold);
591-
592-
if start_swipe {
593-
Self::FIELD_OFFSETS.swiping.apply_pin(self).set(true);
594-
}
572+
let mut swiping = self.swiping();
573+
if !swiping && self.is_over_threshold(position) {
574+
Self::FIELD_OFFSETS.swiping.apply_pin(self).set(true);
575+
swiping = true;
595576
}
596577
Self::FIELD_OFFSETS.moved.apply_pin(self).call(&());
597-
InputEventResult::GrabMouse
578+
if swiping {
579+
InputEventResult::GrabMouse
580+
} else {
581+
InputEventResult::EventAccepted
582+
}
598583
}
599584
MouseEvent::Wheel { .. } => InputEventResult::EventIgnored,
600585
MouseEvent::DragMove(..) | MouseEvent::Drop(..) => InputEventResult::EventIgnored,
@@ -672,6 +657,17 @@ impl SwipeGestureHandler {
672657
Self::FIELD_OFFSETS.cancelled.apply_pin(self).call(&());
673658
}
674659
}
660+
661+
fn is_over_threshold(self: Pin<&Self>, position: &LogicalPoint) -> bool {
662+
let pressed_pos = self.pressed_position();
663+
let dx = position.x - pressed_pos.x as Coord;
664+
let dy = position.y - pressed_pos.y as Coord;
665+
let threshold = super::flickable::DISTANCE_THRESHOLD.get();
666+
(self.handle_swipe_down() && dy > threshold && dy > dx.abs() / 2 as Coord)
667+
|| (self.handle_swipe_up() && dy < -threshold && dy < -dx.abs() / 2 as Coord)
668+
|| (self.handle_swipe_left() && dx < -threshold && dx < -dy.abs() / 2 as Coord)
669+
|| (self.handle_swipe_right() && dx > threshold && dx > dy.abs() / 2 as Coord)
670+
}
675671
}
676672

677673
#[cfg(feature = "ffi")]

tests/cases/elements/swipegesturehandler.slint

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ assert_eq!(instance.get_left_swiping(), false);
139139
assert_eq!(instance.get_right_swiping(), false);
140140
instance.set_r("".into());
141141
142-
// FIXME: this shouldn'g be necessary, but otherwise we don't send exit event to the toucharea
142+
// FIXME: this shouldn't be necessary, but otherwise we don't send exit event to the toucharea
143143
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(316.0, 463.0) });
144144
145145
// Left
@@ -150,20 +150,23 @@ assert_eq!(instance.get_left_swiping(), false);
150150
assert_eq!(instance.get_right_swiping(), false);
151151
slint_testing::mock_elapsed_time(20);
152152
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(100.0, 100.0), button: PointerEventButton::Left });
153-
slint_testing::mock_elapsed_time(120); // FIXME: it should also work with smaller delay, but now the top swipe catches it
153+
slint_testing::mock_elapsed_time(20);
154154
assert_eq!(instance.get_ta_hover(), false);
155155
assert_eq!(instance.get_down_swiping(), false);
156156
assert_eq!(instance.get_left_swiping(), false);
157157
assert_eq!(instance.get_right_swiping(), false);
158158
assert_eq!(instance.get_r(), "");
159+
slint_testing::mock_elapsed_time(20);
159160
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(80.0, 100.0) });
161+
slint_testing::mock_elapsed_time(80);
162+
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(65.0, 112.0) });
160163
assert_eq!(instance.get_ta_hover(), false);
161164
assert_eq!(instance.get_down_swiping(), false);
162165
assert_eq!(instance.get_right_swiping(), false);
163166
assert_eq!(instance.get_left_swiping(), true);
164-
assert_eq!(instance.get_r(), "M2(20)");
167+
assert_eq!(instance.get_r(), "M2(37)");
165168
instance.window().dispatch_event(WindowEvent::PointerExited);
166-
assert_eq!(instance.get_r(), "M2(20)C2(20)");
169+
assert_eq!(instance.get_r(), "M2(37)C2(37)");
167170
assert_eq!(instance.get_down_swiping(), false);
168171
assert_eq!(instance.get_left_swiping(), false);
169172
assert_eq!(instance.get_right_swiping(), false);

0 commit comments

Comments
 (0)