Skip to content

Commit 346a9e8

Browse files
committed
Drag&Drop: don't keep all the touch area that cross the mouse with has-hover
Before this patch, if you drag from somewhere and go over some TouchAreas, they all would be marked as has-hover and they like that untill we go over them again without a drag. There is still an issue that if we release the drag over a TouchArea, it won't be marked as hovered.
1 parent 729f83d commit 346a9e8

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

internal/core/items/input_items.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ impl Item for TouchArea {
8484
}
8585
return InputEventFilterResult::ForwardAndIgnore;
8686
}
87+
if matches!(event, MouseEvent::DragMove(..) | MouseEvent::Drop(..)) {
88+
// Someone else has the grab, don't handle hover
89+
return InputEventFilterResult::ForwardAndIgnore;
90+
}
8791
if let Some(pos) = event.position() {
8892
Self::FIELD_OFFSETS.mouse_x.apply_pin(self).set(pos.x_length());
8993
Self::FIELD_OFFSETS.mouse_y.apply_pin(self).set(pos.y_length());

tests/cases/elements/dragarea_droparea.slint

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export component TestCase inherits Window {
66
height: 200px;
77
in-out property <string> result;
88
out property <bool> contains-drag <=> da.contains-drag;
9+
out property <bool> inner_touch_area_has_hover <=> inner_touch_area.has-hover;
910
VerticalLayout {
1011
Rectangle {
1112
background: inner_touch_area.has-hover ? yellow : red;
@@ -31,6 +32,8 @@ export component TestCase inherits Window {
3132
result += "D[" + event.data + "];";
3233
debug("dropped", event);
3334
}
35+
36+
TouchArea {}
3437
}
3538
}
3639
}
@@ -65,36 +68,75 @@ slint_testing::mock_elapsed_time(20);
6568
assert_eq!(instance.get_result(), "D[Hello World];");
6669
assert_eq!(instance.get_contains_drag(), false);
6770
71+
// Test a click on a touch area (without dragging)
6872
instance.set_result("".into());
73+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
6974
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(51.0, 50.0), button: PointerEventButton::Left });
75+
assert!(instance.get_inner_touch_area_has_hover());
7076
slint_testing::mock_elapsed_time(20);
7177
assert_eq!(instance.get_contains_drag(), false);
7278
assert_eq!(instance.get_result(), "");
79+
assert_eq!(instance.get_inner_touch_area_has_hover(), true);
7380
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(52.0, 50.0) });
81+
assert_eq!(instance.get_inner_touch_area_has_hover(), true);
7482
slint_testing::mock_elapsed_time(20);
7583
assert_eq!(instance.get_contains_drag(), false);
7684
assert_eq!(instance.get_result(), "");
85+
assert_eq!(instance.get_inner_touch_area_has_hover(), true);
7786
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(52.0, 50.0), button: PointerEventButton::Left });
7887
slint_testing::mock_elapsed_time(20);
7988
assert_eq!(instance.get_result(), "InnerClicked;");
8089
assert_eq!(instance.get_contains_drag(), false);
90+
assert_eq!(instance.get_inner_touch_area_has_hover(), true);
8191
92+
// Dragging from the touch area should not result in a click
8293
instance.set_result("".into());
8394
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(51.0, 15.0), button: PointerEventButton::Left });
95+
assert_eq!(instance.get_inner_touch_area_has_hover(), true);
8496
slint_testing::mock_elapsed_time(20);
8597
assert_eq!(instance.get_contains_drag(), false);
8698
assert_eq!(instance.get_result(), "");
8799
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(58.0, 40.0) });
88100
slint_testing::mock_elapsed_time(20);
89101
assert_eq!(instance.get_contains_drag(), false);
90102
assert_eq!(instance.get_result(), "");
103+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
91104
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(58.0, 120.0) });
92105
assert_eq!(instance.get_contains_drag(), true);
93106
assert_eq!(instance.get_result(), "");
107+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
94108
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(58.0, 20.0), button: PointerEventButton::Left });
109+
assert_eq!(instance.get_inner_touch_area_has_hover(), false); // FIXME: should be true without the need to make a move as well
95110
slint_testing::mock_elapsed_time(20);
111+
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(58.0, 20.0) });
112+
assert_eq!(instance.get_inner_touch_area_has_hover(), true);
113+
assert_eq!(instance.get_contains_drag(), false);
114+
assert_eq!(instance.get_result(), "");
115+
116+
117+
// Dragging over the touch area shouldn't result in has-hover being true (only after it is released)
118+
instance.set_result("".into());
119+
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(11.0, 15.0) });
120+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
121+
assert_eq!(instance.get_contains_drag(), false);
122+
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(11.0, 15.0), button: PointerEventButton::Left });
123+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
96124
assert_eq!(instance.get_contains_drag(), false);
97125
assert_eq!(instance.get_result(), "");
126+
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(25.0, 35.0) });
127+
slint_testing::mock_elapsed_time(20);
128+
assert_eq!(instance.get_contains_drag(), false);
129+
assert_eq!(instance.get_result(), "");
130+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
131+
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(125.0, 28.0) });
132+
assert_eq!(instance.get_contains_drag(), false);
133+
assert_eq!(instance.get_result(), "");
134+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
135+
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(18.0, 20.0), button: PointerEventButton::Left });
136+
assert_eq!(instance.get_inner_touch_area_has_hover(), false);
137+
assert_eq!(instance.get_contains_drag(), false);
138+
assert_eq!(instance.get_result(), "");
139+
98140
```
99141
100142
*/

0 commit comments

Comments
 (0)