// One global place to set windows aside. Empty, it is a quiet drop target; // populated, it expands into a compact row of restorable window cards. import QtQuick import qs.config Item { id: root required property var workspace property int refreshToken: 0 signal windowDropped(var toplevel) signal restoreRequested(var toplevel) signal closeRequested(var toplevel) readonly property var windows: root.workspace?.toplevels?.values ?? [] readonly property bool populated: root.windows.length > 0 implicitHeight: root.populated ? 112 : 42 Rectangle { id: surface anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom width: root.populated ? Math.min(parent.width, Math.max(360, root.windows.length * 198 + 28)) : 292 height: root.populated ? 112 : 42 radius: root.populated ? Theme.popoverRadius : Theme.pillRadius border.width: 1 border.color: dropArea.containsDrag ? Theme.ok : Theme.alpha(Theme.fg, root.populated ? 0.1 : 0.08) color: Theme.alpha(Theme.bgPopover, root.populated ? 0.76 : 0.42) Behavior on width { NumberAnimation { duration: Theme.durNormal; easing.type: Easing.OutCubic } } Behavior on height { NumberAnimation { duration: Theme.durNormal; easing.type: Easing.OutCubic } } Behavior on border.color { ColorAnimation { duration: Theme.durFast } } Row { anchors.centerIn: parent visible: !root.populated spacing: 8 Text { anchors.verticalCenter: parent.verticalCenter text: dropArea.containsDrag ? "\u{F04E7}" : "\u{F02D4}" color: dropArea.containsDrag ? Theme.ok : Theme.fgDim font.family: Theme.fontMono font.pixelSize: 15 } Text { anchors.verticalCenter: parent.verticalCenter text: dropArea.containsDrag ? "Release to set aside" : "Drop to Scratchpad" color: dropArea.containsDrag ? Theme.fg : Theme.fgDim font.family: Theme.fontFamily font.pixelSize: Theme.fontSize font.weight: Font.Medium } } Text { id: heading anchors.left: parent.left anchors.leftMargin: 14 anchors.top: parent.top anchors.topMargin: 9 visible: root.populated text: "Scratchpad ยท " + root.windows.length color: Theme.fgDim font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall font.weight: Font.DemiBold } Flickable { id: windowStrip anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.leftMargin: 12 anchors.rightMargin: 12 anchors.bottomMargin: 8 height: 76 visible: root.populated clip: true contentWidth: Math.max(width, cards.implicitWidth) contentHeight: height boundsBehavior: Flickable.StopAtBounds Row { id: cards spacing: Theme.itemSpacing Repeater { model: root.windows WindowThumbnail { required property var modelData toplevel: modelData refreshToken: root.refreshToken width: 190 height: 76 onActivated: root.restoreRequested(modelData) onCloseRequested: root.closeRequested(modelData) } } } } DropArea { id: dropArea anchors.fill: parent z: 5 onDropped: drop => { if (!drop.source?.toplevel) return; root.windowDropped(drop.source.toplevel); drop.acceptProposedAction(); } } } }