diff --git a/ui/qml/OutlineView.qml b/ui/qml/OutlineView.qml index 1e4e7f3..8cd4ed7 100644 --- a/ui/qml/OutlineView.qml +++ b/ui/qml/OutlineView.qml @@ -520,33 +520,49 @@ ListView { // Drag grip: drag a section (and its subtree) to restructure. // A live indicator shows the resolved drop target; releasing // commits a refile. Horizontal position chooses the depth, - // vertical position chooses the gap. + // vertical position chooses the gap. A DragHandler is used + // (not a MouseArea) so the enclosing ListView cannot steal the + // drag for flicking. Label { + id: gripLabel text: "⠿" color: theme.placeholderTextColor + // A slightly larger hit target than the bare glyph. + Layout.preferredWidth: outline.baseFontSize + 6 + horizontalAlignment: Text.AlignHCenter font.pointSize: outline.baseFontSize - 1 - opacity: gripMouse.containsMouse || outline.dragRow === del.index ? 1.0 : 0.3 + opacity: gripHover.hovered || outline.dragRow === del.index ? 1.0 : 0.3 - MouseArea { - id: gripMouse - anchors.fill: parent - hoverEnabled: true + HoverHandler { + id: gripHover cursorShape: Qt.SizeAllCursor - preventStealing: true - onPressed: { - outline.dragRow = del.index + } + + DragHandler { + id: gripDrag + target: null // we track, we don't move the item + dragThreshold: 3 + // Take the grab and refuse to yield it to the ListView + // (a Flickable), which would otherwise steal the drag. + grabPermissions: PointerHandler.CanTakeOverFromItems + | PointerHandler.CanTakeOverFromHandlersOfDifferentType + + onActiveChanged: { + if (active) { + outline.dragRow = del.index + } else { + outline.commitDrop() + } } - onPositionChanged: (mouse) => { - if (outline.dragRow < 0) return - // Map the pointer to ListView content coordinates. - var p = mapToItem(outline.contentItem, mouse.x, mouse.y) + onCentroidChanged: { + if (!active || outline.dragRow < 0) return + // Map the scene pointer position to ListView content + // coordinates and resolve the drop. + var p = outline.contentItem.mapFromScene( + centroid.scenePosition.x, + centroid.scenePosition.y) outline.updateDrop(p.x, p.y) } - onReleased: outline.commitDrop() - onCanceled: { - outline.dragRow = -1 - outline.dropInfo = null - } } }