import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.Wayland import "." as M PanelWindow { id: bar required property var screen color: "transparent" WlrLayershell.layer: WlrLayer.Bottom anchors { top: true left: true right: true } implicitHeight: M.Theme.barHeight exclusiveZone: implicitHeight Rectangle { anchors.fill: parent color: M.Theme.base00 opacity: M.Theme.barOpacity } Canvas { anchors.fill: parent onPaint: { const ctx = getContext("2d"); const w = width; const h = height; const r = M.Theme.screenRadius; const lw = 3; const hw = lw / 2; ctx.clearRect(0, 0, w, h); // Glow wash behind the border const glowGrad = ctx.createLinearGradient(0, 0, w, 0); glowGrad.addColorStop(0, M.Theme.base0C.toString()); glowGrad.addColorStop(1, M.Theme.base09.toString()); ctx.globalAlpha = 0.25; ctx.fillStyle = glowGrad; ctx.fillRect(0, 0, w, h); // Erase glow towards bottom ctx.globalAlpha = 1; ctx.globalCompositeOperation = "destination-out"; const glowFade = ctx.createLinearGradient(0, 0, 0, h); glowFade.addColorStop(0, "transparent"); glowFade.addColorStop(1, "black"); ctx.fillStyle = glowFade; ctx.fillRect(0, 0, w, h); ctx.globalCompositeOperation = "source-over"; // Horizontal gradient for the border const grad = ctx.createLinearGradient(0, 0, w, 0); grad.addColorStop(0, M.Theme.base0C.toString()); grad.addColorStop(1, M.Theme.base09.toString()); ctx.strokeStyle = grad; ctx.lineWidth = lw; // Stroke: top + left side + right side (open bottom) // Left side down, curve, across top, curve, right side down ctx.beginPath(); if (r > lw) { ctx.moveTo(hw, h); ctx.lineTo(hw, r); ctx.arc(r, r, r - hw, Math.PI, -Math.PI / 2); ctx.lineTo(w - r, hw); ctx.arc(w - r, r, r - hw, -Math.PI / 2, 0); ctx.lineTo(w - hw, h); } else { ctx.moveTo(hw, h); ctx.lineTo(hw, hw); ctx.lineTo(w - hw, hw); ctx.lineTo(w - hw, h); } ctx.stroke(); // Fade out the bottom of the side borders ctx.globalCompositeOperation = "destination-out"; const fadeGrad = ctx.createLinearGradient(0, h * 0.5, 0, h); fadeGrad.addColorStop(0, "transparent"); fadeGrad.addColorStop(1, "black"); ctx.fillStyle = fadeGrad; ctx.fillRect(0, h * 0.5, w, h * 0.5); ctx.globalCompositeOperation = "source-over"; } } Item { anchors.fill: parent anchors.topMargin: 3 anchors.leftMargin: Math.max(M.Theme.barPadding, M.Theme.screenRadius) anchors.rightMargin: Math.max(M.Theme.barPadding, M.Theme.screenRadius) // ---- center (declared first so left/right can anchor to it) ---- RowLayout { id: centerSection anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter spacing: M.Theme.barSpacing M.Privacy {} M.BarGroup { M.Clock { visible: M.Modules.clock.enable } M.Notifications { bar: bar visible: M.Modules.notifications.enable } } } // ---- left ---- RowLayout { anchors.left: parent.left anchors.right: centerSection.left anchors.verticalCenter: parent.verticalCenter spacing: M.Theme.barSpacing M.BarGroup { M.Workspaces { bar: bar visible: M.Modules.workspaces.enable } } M.BarGroup { M.Tray { bar: bar visible: M.Modules.tray.enable } } M.BarGroup { Layout.minimumWidth: 0 clip: true M.WindowTitle { visible: M.Modules.windowTitle.enable } } Item { Layout.fillWidth: true } } // ---- right ---- RowLayout { anchors.left: centerSection.right anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: M.Theme.barSpacing Item { Layout.fillWidth: true } // Media M.BarGroup { M.Mpris { bar: bar } M.Volume { visible: M.Modules.volume.enable } } // Connectivity M.BarGroup { M.Network { bar: bar visible: M.Modules.network.enable } M.Bluetooth { bar: bar } } // Controls M.BarGroup { M.Backlight {} M.PowerProfile { visible: M.Modules.powerProfile.enable } M.IdleInhibitor { visible: M.Modules.idleInhibitor.enable } } // Stats M.BarGroup { M.Cpu { visible: M.Modules.cpu.enable } M.Memory { visible: M.Modules.memory.enable } M.Temperature { visible: M.Modules.temperature.enable } M.Weather { visible: M.Modules.weather.enable } M.Disk { visible: M.Modules.disk.enable } } // Power M.BarGroup { M.Battery {} M.Power { bar: bar visible: M.Modules.power.enable } } } } }