//@ pragma UseQApplication import QtQuick import Quickshell import Quickshell.Wayland import Quickshell.Io import "bar" import "launcher" import "widgets/bgDate" import "polkit" import "config" as Cfg ShellRoot { id: root Component.onCompleted: { Qt.application.organization = "quickshell" Qt.application.name = "quickshell" } readonly property bool isTop: Cfg.Config.barPosition === "top" property color frameBackground: Cfg.Config.theme.bgFrame property color frameBorderColor: Cfg.Config.theme.frameBorder ?? Cfg.Config.theme.borderPopup // ── Polkit Agent ───────────────────────────────────────────────────────── Loader { active: Cfg.Config.enablePolkit source: Qt.resolvedUrl("polkit/Polkit.qml") } Component { id: polkitComp Polkit {} } // ── Spacing Gap: Top / Bottom ──────────────────────────────────────── Variants { model: Quickshell.screens PanelWindow { required property var modelData screen: modelData anchors { top: !root.isTop bottom: root.isTop left: true right: true } implicitHeight: Cfg.Config.margin color: "transparent" WlrLayershell.layer: WlrLayer.Top WlrLayershell.exclusiveZone: Cfg.Config.margin mask: Region {} } } // ── Spacing Gap: Left ──────────────────────────────────────────────── Variants { model: Quickshell.screens PanelWindow { required property var modelData screen: modelData anchors { left: true; top: true; bottom: true } implicitWidth: Cfg.Config.margin color: "transparent" WlrLayershell.layer: WlrLayer.Top WlrLayershell.exclusiveZone: Cfg.Config.margin mask: Region {} } } // ── Spacing Gap: Right ─────────────────────────────────────────────── Variants { model: Quickshell.screens PanelWindow { required property var modelData screen: modelData anchors { right: true; top: true; bottom: true } implicitWidth: Cfg.Config.margin color: "transparent" WlrLayershell.layer: WlrLayer.Top WlrLayershell.exclusiveZone: Cfg.Config.margin mask: Region {} } } // ── Wallpaper ──────────────────────────────────────────────────────── Variants { model: Quickshell.screens PanelWindow { required property var modelData screen: modelData color: "transparent" anchors { top: true; bottom: true; left: true; right: true } WlrLayershell.layer: WlrLayer.Background WlrLayershell.namespace: "main-shell-wallpaper" WlrLayershell.exclusiveZone: -1 mask: Region {} Image { anchors.fill: parent source: { var p = Cfg.Config.theme.wallpaper return p.startsWith("file://") ? p : "file://" + p } fillMode: Image.PreserveAspectCrop asynchronous: true } } } // ── Center Clock (bgDate Widget) ───────────────────────────────────── Variants { model: Cfg.Config.enableBgDate ? Quickshell.screens : [] BgDate { modelData: modelData } } // ── Frame ──────────────────────────────────────────────────────────── Variants { model: Quickshell.screens PanelWindow { required property var modelData screen: modelData color: "transparent" anchors { top: true; bottom: true; left: true; right: true } WlrLayershell.layer: WlrLayer.Top WlrLayershell.namespace: "main-shell-frame" WlrLayershell.exclusiveZone: -1 mask: Region {} Canvas { id: frameCanvas anchors.fill: parent opacity: 0 scale: 0.98 Component.onCompleted: startupAnimation.start() ParallelAnimation { id: startupAnimation NumberAnimation { target: frameCanvas; property: "opacity" from: 0; to: 1; duration: 500 easing.type: Easing.OutCubic } NumberAnimation { target: frameCanvas; property: "scale" from: 0.98; to: 1.0; duration: 600 easing.type: Easing.OutBack } } onPaint: { var ctx = getContext("2d") ctx.clearRect(0, 0, width, height) var mT = root.isTop ? Cfg.Config.barHeight : Cfg.Config.margin var mB = root.isTop ? Cfg.Config.margin : Cfg.Config.barHeight var r = Cfg.Config.radius var cw = width - Cfg.Config.margin * 2 var ch = height - mT - mB var x = Cfg.Config.margin var y = mT ctx.fillStyle = root.frameBackground ctx.fillRect(0, 0, width, mT) ctx.fillRect(0, height - mB, width, mB) ctx.fillRect(0, mT, x, ch) ctx.fillRect(x + cw, mT, width - (x + cw), ch) ctx.beginPath() ctx.moveTo(x, y) ctx.lineTo(x + r, y) ctx.arc(x + r, y + r, r, -Math.PI / 2, Math.PI, true) ctx.closePath() ctx.fill() ctx.beginPath() ctx.moveTo(x + cw, y) ctx.lineTo(x + cw - r, y) ctx.arc(x + cw - r, y + r, r, -Math.PI / 2, 0, false) ctx.closePath() ctx.fill() ctx.beginPath() ctx.moveTo(x + cw, y + ch) ctx.lineTo(x + cw, y + ch - r) ctx.arc(x + cw - r, y + ch - r, r, 0, Math.PI / 2, false) ctx.closePath() ctx.fill() ctx.beginPath() ctx.moveTo(x, y + ch) ctx.lineTo(x + r, y + ch) ctx.arc(x + r, y + ch - r, r, Math.PI / 2, Math.PI, false) ctx.closePath() ctx.fill() ctx.lineWidth = Cfg.Config.frameBorderWidth ctx.strokeStyle = root.frameBorderColor ctx.beginPath() ctx.moveTo(x + r, y) ctx.lineTo(x + cw - r, y) ctx.arcTo(x + cw, y, x + cw, y + r, r) ctx.stroke() ctx.beginPath() ctx.moveTo(x + cw, y + r) ctx.lineTo(x + cw, y + ch - r) ctx.arcTo(x + cw, y + ch, x + cw - r, y + ch, r) ctx.stroke() ctx.beginPath() ctx.moveTo(x + cw - r, y + ch) ctx.lineTo(x + r, y + ch) ctx.arcTo(x, y + ch, x, y + ch - r, r) ctx.stroke() ctx.beginPath() ctx.moveTo(x, y + ch - r) ctx.lineTo(x, y + r) ctx.arcTo(x, y, x + r, y, r) ctx.stroke() } Connections { target: root function onFrameBackgroundChanged() { frameCanvas.requestPaint() } function onFrameBorderColorChanged() { frameCanvas.requestPaint() } } } } } // ── Launcher ───────────────────────────────────────────────────────── Variants { model: Quickshell.screens Launcher { required property var modelData screen: modelData isTop: root.isTop Component.onCompleted: modelData.launcher = this } } // ── Bar ────────────────────────────────────────────────────────────── Variants { model: Quickshell.screens Bar { screen: modelData isTop: root.isTop } } }