import QtQuick import Quickshell import Quickshell.Wayland import "." as M PanelWindow { id: root required property var screen color: "transparent" WlrLayershell.layer: WlrLayer.Background WlrLayershell.exclusiveZone: -1 WlrLayershell.namespace: "nova-overview-backdrop" mask: Region {} anchors.top: true anchors.left: true anchors.right: true anchors.bottom: true // Solid dark background Rectangle { anchors.fill: parent color: M.Theme.base01 } ShaderEffect { id: fx anchors.fill: parent fragmentShader: "hex_wave.frag.qsb" // Uniforms property size uResolution: Qt.size(width, height) property real uSize: 50.0 property real uWavePhase: -200 property vector3d uC0: Qt.vector3d(M.Theme.base0C.r, M.Theme.base0C.g, M.Theme.base0C.b) property vector3d uC1: Qt.vector3d(M.Theme.base0E.r, M.Theme.base0E.g, M.Theme.base0E.b) property vector3d uC2: Qt.vector3d(M.Theme.base09.r, M.Theme.base09.g, M.Theme.base09.b) // 12 spinner uniforms property vector4d uSpinners0: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners1: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners2: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners3: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners4: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners5: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners6: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners7: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners8: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners9: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners10: Qt.vector4d(0, 0, 0, 0) property vector4d uSpinners11: Qt.vector4d(0, 0, 0, 0) // Spinner angle properties (animated individually) property real _a0: 0 property real _a1: 0 property real _a2: 0 property real _a3: 0 property real _a4: 0 property real _a5: 0 property real _a6: 0 property real _a7: 0 property real _a8: 0 property real _a9: 0 property real _a10: 0 property real _a11: 0 // Spinner center coordinates (set once at startup) property var _centers: [] // Pack angle into spinner vec4 on_A0Changed: uSpinners0 = Qt.vector4d(_centers[0]?.x ?? 0, _centers[0]?.y ?? 0, _a0, 0) on_A1Changed: uSpinners1 = Qt.vector4d(_centers[1]?.x ?? 0, _centers[1]?.y ?? 0, _a1, 0) on_A2Changed: uSpinners2 = Qt.vector4d(_centers[2]?.x ?? 0, _centers[2]?.y ?? 0, _a2, 0) on_A3Changed: uSpinners3 = Qt.vector4d(_centers[3]?.x ?? 0, _centers[3]?.y ?? 0, _a3, 0) on_A4Changed: uSpinners4 = Qt.vector4d(_centers[4]?.x ?? 0, _centers[4]?.y ?? 0, _a4, 0) on_A5Changed: uSpinners5 = Qt.vector4d(_centers[5]?.x ?? 0, _centers[5]?.y ?? 0, _a5, 0) on_A6Changed: uSpinners6 = Qt.vector4d(_centers[6]?.x ?? 0, _centers[6]?.y ?? 0, _a6, 0) on_A7Changed: uSpinners7 = Qt.vector4d(_centers[7]?.x ?? 0, _centers[7]?.y ?? 0, _a7, 0) on_A8Changed: uSpinners8 = Qt.vector4d(_centers[8]?.x ?? 0, _centers[8]?.y ?? 0, _a8, 0) on_A9Changed: uSpinners9 = Qt.vector4d(_centers[9]?.x ?? 0, _centers[9]?.y ?? 0, _a9, 0) on_A10Changed: uSpinners10 = Qt.vector4d(_centers[10]?.x ?? 0, _centers[10]?.y ?? 0, _a10, 0) on_A11Changed: uSpinners11 = Qt.vector4d(_centers[11]?.x ?? 0, _centers[11]?.y ?? 0, _a11, 0) // Wave animation: 6s sweep + 8s pause SequentialAnimation on uWavePhase { loops: Animation.Infinite running: true NumberAnimation { from: -200 to: fx.width + 200 duration: 6000 easing.type: Easing.InOutSine } PauseAnimation { duration: 8000 } } // Initialize spinner centers Component.onCompleted: { const dx = uSize * 1.5; const dy = uSize * Math.sqrt(3); const used = {}; const centers = []; for (let i = 0; i < 12; i++) { let col, row, key; do { col = Math.floor(Math.random() * (width / dx)); row = Math.floor(Math.random() * (height / dy)); key = col + "," + row; } while (used[key]) used[key] = true; const cx = col * dx; const cy = row * dy + ((col % 2) ? dy / 2 : 0); centers.push({ x: cx, y: cy }); } _centers = centers; // Initialize all spinner vec4s with center coords for (let i = 0; i < 12; i++) { const prop = "uSpinners" + i; fx[prop] = Qt.vector4d(centers[i].x, centers[i].y, 0, 0); } } // 12 independent spinner animations Repeater { model: 12 Item { required property int index SequentialAnimation { loops: Animation.Infinite running: true PauseAnimation { id: _pause duration: 3000 + Math.random() * 12000 } NumberAnimation { id: _spin target: fx property: "_a" + parent.index from: 0 to: 2 * Math.PI duration: 1000 + Math.random() * 2000 easing.type: Easing.InOutCubic } ScriptAction { script: { _pause.duration = 3000 + Math.random() * 12000; _spin.duration = 1000 + Math.random() * 2000; } } } } } } }