Return the action the drag offered, not the one this row prefers
Slint negotiates a drag action between source and target, and the runtime clamps whatever `can-drop` returns against the set the source allowed: an action outside it becomes `none`. Both drop targets here named a constant instead of echoing what was on offer, and each named the wrong one for half its traffic. A collection row takes two kinds of payload. Photographs come from a DragArea allowing `copy`; a collection being nested comes from one allowing `move`. The row asked for `copy` unconditionally, so images filed correctly and every collection dropped on a collection was refused — nesting by drag has never worked. The trash had the same fault mirrored: it insisted on `move` while the grid's cells allow only `copy`, so it refused every photograph dragged to it. Neither failure had anything to see. A clamped action is delivered as a refusal, which looks exactly like a target that declined on purpose, so the drag simply did nothing and left no error to search for. `decide_drop`'s Reparent branch was tested and passing throughout. It tests the decision, not the negotiation, and nothing was reaching it.
This commit is contained in:
@@ -127,12 +127,23 @@ component TreeRow inherits Rectangle {
|
||||
if (!root.drop-allowed) {
|
||||
return DragAction.none;
|
||||
}
|
||||
return DragAction.copy;
|
||||
// The action the *source* offered, echoed back, rather than a
|
||||
// constant. Two different things are dropped on this row — a
|
||||
// selection of photographs, whose DragArea allows only `copy`, and
|
||||
// a collection being nested, whose DragArea allows only `move` —
|
||||
// and the runtime clamps whatever is returned here against the
|
||||
// source's allowed set, treating anything outside it as `none`.
|
||||
//
|
||||
// So a hard-coded `copy` accepted images and *silently refused
|
||||
// every collection*: nesting by drag could not work at all, and it
|
||||
// failed with nothing to see, because an action clamped to `none`
|
||||
// is indistinguishable from a target that simply said no.
|
||||
return ev.proposed-action;
|
||||
}
|
||||
|
||||
dropped(ev) => {
|
||||
root.dropped();
|
||||
return DragAction.copy;
|
||||
return ev.proposed-action;
|
||||
}
|
||||
|
||||
// Dwelling over a collapsed parent springs it open. Reported rather
|
||||
@@ -642,13 +653,19 @@ export component CollectionsPanel inherits Rectangle {
|
||||
trash-drop := DropArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// Deliberately `move`, where a collection drop is `copy`: this
|
||||
// one really does take the photograph out of the library, and
|
||||
// the cursor should say so.
|
||||
can-drop(ev) => { return DragAction.move; }
|
||||
// Echoed from the source, like the row above: the grid's
|
||||
// cells allow `copy` alone, so the `move` this used to insist
|
||||
// on was clamped to `none` and the trash refused every
|
||||
// photograph dragged onto it.
|
||||
//
|
||||
// What this row does is destructive whatever the negotiated
|
||||
// action is called — `dropped-on-trash` moves the file — so
|
||||
// the name was never what made it so, and naming it cost the
|
||||
// feature.
|
||||
can-drop(ev) => { return ev.proposed-action; }
|
||||
dropped(ev) => {
|
||||
root.dropped-on-trash();
|
||||
return DragAction.move;
|
||||
return ev.proposed-action;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user