fix: end a drag the compositor never took over
This commit is contained in:
1 parent
7998efd3c2
commit
1b5d44c0a9
2 files changed
+26
No files matched your search
+15
@@ -56,6 +56,14 @@ pub enum AfterDrag {
|
|||||||
SlideOut,
|
SlideOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// During a real drag the compositor owns the pointer and the origin gets
|
||||||
|
/// no button events. A release that reaches the dragged thumbnail means the
|
||||||
|
/// compositor never took the drag over (e.g. a flick released before the
|
||||||
|
/// drag started), so valw has to end it itself.
|
||||||
|
pub fn release_ends_drag(dragged: Option<u64>, released_on: u64) -> bool {
|
||||||
|
dragged == Some(released_on)
|
||||||
|
}
|
||||||
|
|
||||||
/// `expired`: the thumbnail's timer fired while it was being dragged.
|
/// `expired`: the thumbnail's timer fired while it was being dragged.
|
||||||
pub fn after_drag(outcome: Outcome, expired: bool) -> AfterDrag {
|
pub fn after_drag(outcome: Outcome, expired: bool) -> AfterDrag {
|
||||||
match (outcome, expired) {
|
match (outcome, expired) {
|
||||||
@@ -142,6 +150,13 @@ mod tests {
|
|||||||
assert!(through_pipe("text/html", Path::new("/tmp/a.png")).is_err());
|
assert!(through_pipe("text/html", Path::new("/tmp/a.png")).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_release_on_the_dragged_thumbnail_ends_the_drag() {
|
||||||
|
assert!(release_ends_drag(Some(3), 3));
|
||||||
|
assert!(!release_ends_drag(Some(3), 4), "another thumbnail");
|
||||||
|
assert!(!release_ends_drag(None, 3), "no drag going on");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn after_drag_decisions() {
|
fn after_drag_decisions() {
|
||||||
assert_eq!(after_drag(Outcome::Dropped, false), AfterDrag::Close);
|
assert_eq!(after_drag(Outcome::Dropped, false), AfterDrag::Close);
|
||||||
|
|||||||
+11
@@ -302,6 +302,10 @@ impl Host {
|
|||||||
let Some(drag) = self.drag.take_if(|d| d.source.inner() == source) else {
|
let Some(drag) = self.drag.take_if(|d| d.source.inner() == source) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
self.finish_drag(drag, outcome, qh);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_drag(&mut self, drag: Drag, outcome: Outcome, qh: &QueueHandle<State>) {
|
||||||
tracing::info!("drag-out {outcome:?}");
|
tracing::info!("drag-out {outcome:?}");
|
||||||
drag.icon_viewport.destroy();
|
drag.icon_viewport.destroy();
|
||||||
drag.icon.destroy();
|
drag.icon.destroy();
|
||||||
@@ -361,6 +365,13 @@ pub fn pointer(state: &mut State, events: &[PointerEvent], qh: &QueueHandle<Stat
|
|||||||
PointerEventKind::Release {
|
PointerEventKind::Release {
|
||||||
button: BTN_LEFT, ..
|
button: BTN_LEFT, ..
|
||||||
} => {
|
} => {
|
||||||
|
let dragged = host.drag.as_ref().map(|d| d.thumb);
|
||||||
|
if dnd::release_ends_drag(dragged, host.thumbs[i].id) {
|
||||||
|
tracing::info!("the compositor never took the drag over");
|
||||||
|
let drag = host.drag.take().expect("checked above");
|
||||||
|
host.finish_drag(drag, Outcome::Cancelled, qh);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let t = &mut host.thumbs[i];
|
let t = &mut host.thumbs[i];
|
||||||
if t.release(x, y, qh) == Some(Action::OpenEditor) {
|
if t.release(x, y, qh) == Some(Action::OpenEditor) {
|
||||||
open_editor(&t.path);
|
open_editor(&t.path);
|
||||||
|
|||||||
Reference in new issue
Block a user