import Quickshell import QtQuick import QtQuick.Shapes import "../components" PopupWindow { id: self property string popupName: "" property string activePopup: "" visible: false color: "transparent" default property alias content: contentSlot.data readonly property int bw: Theme.borderWidth readonly property real r: Theme.radius readonly property bool _open: activePopup === popupName on_OpenChanged: { if (_open) { hideTimer.stop(); self.visible = true; fade.opacity = 1.0; } else { fade.opacity = 0.0; hideTimer.start(); } } Timer { id: hideTimer interval: 200 onTriggered: self.visible = false } Item { id: fade anchors.fill: parent opacity: 0.0 Behavior on opacity { NumberAnimation { duration: 180 easing.type: Easing.InOutCubic } } // Background + border in one Shape so fill matches stroke exactly Shape { id: pbs anchors.fill: parent ShapePath { strokeWidth: self.bw strokeColor: Theme.border fillColor: Theme.bg // Start flush at top-left, hidden under bar startX: 0 startY: self.r // Left side down to bottom-left corner PathLine { x: 0 y: pbs.height - self.r } // Bottom-left corner — Counterclockwise for outward curve PathArc { x: self.r y: pbs.height radiusX: self.r radiusY: self.r direction: PathArc.Counterclockwise } // Bottom edge PathLine { x: pbs.width - self.r y: pbs.height } // Bottom-right corner — Counterclockwise for outward curve PathArc { x: pbs.width y: pbs.height - self.r radiusX: self.r radiusY: self.r direction: PathArc.Counterclockwise } // Right side up, flush to top, hidden under bar PathLine { x: pbs.width y: self.r } } } // // Top-left concave corner // Shape { // x: 0 // y: 0 // width: self.r // height: self.r // ShapePath { // fillColor: Theme.bg // strokeColor: "transparent" // startX: 0 // startY: 0 // PathLine { // x: self.r // y: 0 // } // PathArc { // x: 0 // y: self.r // radiusX: self.r // radiusY: self.r // direction: PathArc.Clockwise // } // } // } // // // Top-right concave corner // Shape { // x: parent.width - self.r // y: 0 // width: self.r // height: self.r // ShapePath { // fillColor: Theme.bg // strokeColor: "transparent" // startX: self.r // startY: 0 // PathLine { // x: 0 // y: 0 // } // PathArc { // x: self.r // y: self.r // radiusX: self.r // radiusY: self.r // direction: PathArc.Counterclockwise // } // } // } Item { id: contentSlot anchors { top: parent.top topMargin: self.r + self.bw left: parent.left leftMargin: self.bw right: parent.right rightMargin: self.bw } } } }