diff --git a/quickshell/.config/quickshell/Globals.qml b/quickshell/.config/quickshell/Globals.qml deleted file mode 100644 index 8c4a5af..0000000 --- a/quickshell/.config/quickshell/Globals.qml +++ /dev/null @@ -1,18 +0,0 @@ -pragma Singleton - -import QtQuick -import Quickshell - -Singleton { - id: root - property var popupContext: PopupContext {}; - property var date: new Date() - - Timer { - interval: 1000 - repeat: true - running: true - - onTriggered: root.date = new Date() - } -} diff --git a/quickshell/.config/quickshell/Theme.qml b/quickshell/.config/quickshell/Theme.qml new file mode 100644 index 0000000..9e5f2d3 --- /dev/null +++ b/quickshell/.config/quickshell/Theme.qml @@ -0,0 +1,103 @@ +pragma Singleton + +import QtQuick +import Quickshell + +Singleton { + property Item get: black + + Item { + id: windowsXP + + property string barBgColor: "#235EDC" + property string buttonBorderColor: "#99000000" + property bool buttonBorderShadow: false + property bool onTop: false + property string iconColor: "green" + property string iconPressedColor: "green" + property Gradient barGradient: black.barGradient + property Gradient buttonInactiveGradientV: Gradient { + GradientStop { position: 0.0; color: "#55FFFFFF" } + GradientStop { position: 0.3; color: "#22FFFFFF" } + } + property Gradient buttonInactiveGradientH: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: "#55FFFFFF" } + GradientStop { position: 0.1; color: "#00000000" } + } + property Gradient buttonActiveGradient: Gradient { + GradientStop { position: 0.0; color: "#99000000" } + GradientStop { position: 0.3; color: "#55000000" } + GradientStop { position: 1.0; color: "#55000000" } + } + } + + Item { + id: black + + property string barBgColor: "#cc000000" + property string buttonBorderColor: "#44FFFFFF" + property bool buttonBorderShadow: true + property bool onTop: true + property string iconColor: "blue" + property string iconPressedColor: "dark_blue" + property Gradient barGradient: Gradient { + GradientStop { position: 0.0; color: "#55FFFFFF" } + GradientStop { position: 0.4; color: "#00FFFFFF" } + GradientStop { position: 0.8; color: "#00FFFFFF" } + GradientStop { position: 1.0; color: "#AA000000" } + } + property Gradient buttonInactiveGradientV: Gradient { + GradientStop { position: 0.0; color: "#33FFFFFF" } + GradientStop { position: 0.3; color: "#55000000" } + } + property Gradient buttonInactiveGradientH: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: "#55FFFFFF" } + GradientStop { position: 0.1; color: "#00000000" } + } + property Gradient buttonActiveGradient: Gradient { + GradientStop { position: 0.92; color: "#FF000000" } + GradientStop { position: 0.93; color: "#FFFFFFFF" } + GradientStop { position: 1.0; color: "#FFFFFFFF" } + } + } + + Item { + id: black_bright + + property string barBgColor: black.barBgColor + property string buttonBorderColor: windowsXP.buttonBorderColor + property bool buttonBorderShadow: windowsXP.buttonBorderShadow + property bool onTop: black.onTop + property string iconColor: "orange" + property string iconPressedColor: "orange" + property Gradient barGradient: black.barGradient + property Gradient buttonInactiveGradientV: windowsXP.buttonInactiveGradientV + property Gradient buttonInactiveGradientH: windowsXP.buttonInactiveGradientH + property Gradient buttonActiveGradient: windowsXP.buttonActiveGradient + } + + Item { + id: black_flat + + property string barBgColor: "#cc000000" + property string buttonBorderColor: "#01000000" // Making this transparent breaks things + property bool buttonBorderShadow: false + property bool onTop: true + property string iconColor: "" + property string iconPressedColor: "" + property Gradient barGradient: Gradient { + GradientStop { position: 0.0; color: "transparent" } + } + property Gradient buttonInactiveGradientV: Gradient { + GradientStop { position: 0.0; color: "transparent" } + } + property Gradient buttonInactiveGradientH: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: "transparent" } + } + property Gradient buttonActiveGradient: black.buttonActiveGradient + } +} + diff --git a/quickshell/.config/quickshell/bar/Bar.qml b/quickshell/.config/quickshell/bar/Bar.qml index 48a2bfa..6d45b46 100644 --- a/quickshell/.config/quickshell/bar/Bar.qml +++ b/quickshell/.config/quickshell/bar/Bar.qml @@ -1,49 +1,98 @@ import Quickshell import Quickshell.Io +import Quickshell.Hyprland import QtQuick import QtQuick.Layouts import "blocks" as Blocks +import "root:/" Scope { Variants { model: Quickshell.screens PanelWindow { + id: bar property var modelData screen: modelData - color: "#cc000000" - height: 27 + color: Theme.get.barBgColor + + Rectangle { + id: highlight + anchors.fill: parent + gradient: Theme.get.barGradient + } + + height: 30 + + visible: true + + IpcHandler { + target: "bar" + + function toggleVis(): void { + visible = !visible; + } + } anchors { - top: true + top: Theme.get.onTop + bottom: !Theme.get.onTop left: true right: true } RowLayout { + id: allBlocks spacing: 0 - width: parent.width - height: parent.height + anchors.fill: parent // Left side RowLayout { - spacing: 0 + id: leftBlocks + spacing: 10 Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true Blocks.Icon {} Blocks.Workspaces {} - Blocks.ActiveWorkspace {} + } + + Blocks.ActiveWorkspace { + id: activeWorkspace + Layout.leftMargin: 10 + anchors.centerIn: undefined + + chopLength: { + var space = Math.floor(bar.width - (rightBlocks.implicitWidth + leftBlocks.implicitWidth)) + return space * 0.08; + } + + text: { + var str = activeWindowTitle + return str.length > chopLength ? str.slice(0, chopLength) + '...' : str; + } + + color: { + return Hyprland.focusedMonitor == Hyprland.monitorFor(screen) + ? "#FFFFFF" : "#CCCCCC" + } + } + + // Without this filler item, the active window block will be centered + // despite setting left alignment + Item { + Layout.fillWidth: true } // Right side RowLayout { + id: rightBlocks spacing: 0 Layout.alignment: Qt.AlignRight + Layout.fillWidth: true Blocks.SystemTray {} - Blocks.Test {} - Blocks.Notifications {} Blocks.Memory {} Blocks.Sound {} Blocks.Battery {} diff --git a/quickshell/.config/quickshell/bar/BarBlock.qml b/quickshell/.config/quickshell/bar/BarBlock.qml index 9daf98a..edd4aca 100644 --- a/quickshell/.config/quickshell/bar/BarBlock.qml +++ b/quickshell/.config/quickshell/bar/BarBlock.qml @@ -4,8 +4,11 @@ import Quickshell Rectangle { id: root - Layout.preferredWidth: wsText.implicitWidth + 10 - Layout.preferredHeight: 27 + Layout.preferredWidth: contentContainer.implicitWidth + 10 + Layout.preferredHeight: 30 + + property Item content + property Item mouseArea: mouseArea property string text property bool dim: false @@ -14,9 +17,7 @@ Rectangle { property int leftPadding property int rightPadding - property string fgColor: "white" - property string dimFgColor: "#999999" - property string hoveredBgColor: "#444444" + property string hoveredBgColor: "#666666" // Background color color: { @@ -40,28 +41,13 @@ Rectangle { } } - BarText { - id: wsText - text: root.text - anchors { - left: parent.left - right: parent.right - leftMargin: root.leftPadding - rightMargin: root.rightPadding - verticalCenter: parent.verticalCenter - } - - color: { - if (mouseArea.containsMouse || !root.dim) - return fgColor - return dimFgColor - } - - Behavior on color { - ColorAnimation { - duration: 100 - } - } + Item { + // Contents of the bar block + id: contentContainer + implicitWidth: content.implicitWidth + implicitHeight: content.implicitHeight + anchors.centerIn: parent + children: content } MouseArea { @@ -76,11 +62,11 @@ Rectangle { Rectangle { id: wsLine width: parent.width - height: 3 + height: 2 color: { if (parent.underline) - return fgColor; + return "white"; return "transparent"; } anchors.bottom: parent.bottom diff --git a/quickshell/.config/quickshell/bar/BarText.qml b/quickshell/.config/quickshell/bar/BarText.qml index 25e2299..3b40767 100644 --- a/quickshell/.config/quickshell/bar/BarText.qml +++ b/quickshell/.config/quickshell/bar/BarText.qml @@ -1,39 +1,57 @@ import Quickshell import Quickshell.Io +import Quickshell.Widgets import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import Qt5Compat.GraphicalEffects -Item { - property string text - property string color: "white" +Text { property string mainFont: "FiraCode" property string symbolFont: "Symbols Nerd Font Mono" - property int pointSize: 11 + property int pointSize: 12 + property int symbolSize: pointSize * 1.37 + property string symbolText + property bool dim + text: wrapSymbols(symbolText) + anchors.centerIn: parent + color: dim ? "#CCCCCC" : "white" + textFormat: Text.RichText + font { + family: mainFont + pointSize: pointSize + } - implicitWidth: thetext.implicitWidth - implicitHeight: thetext.implicitHeight + Text { + visible: false + id: textcopy + text: parent.text + textFormat: parent.textFormat + color: parent.color + font: parent.font + } + + DropShadow { + anchors.fill: parent + horizontalOffset: 1 + verticalOffset: 1 + color: "#000000" + source: textcopy + } function wrapSymbols(text) { + if (!text) + return "" + const isSymbol = (codePoint) => (codePoint >= 0xE000 && codePoint <= 0xF8FF) // Private Use Area || (codePoint >= 0xF0000 && codePoint <= 0xFFFFF) // Supplementary Private Use Area-A || (codePoint >= 0x100000 && codePoint <= 0x10FFFF); // Supplementary Private Use Area-B return text.replace(/./gu, (c) => isSymbol(c.codePointAt(0)) - ? `${c}` + ? `${c}` + // ? c : c); } - - Text { - id: thetext - text: wrapSymbols(parent.text) - color: parent.color - anchors.centerIn: parent - - font { - family: parent.mainFont - pointSize: parent.pointSize - } - textFormat: Text.RichText - } } diff --git a/quickshell/.config/quickshell/bar/blocks/ActiveWorkspace.qml b/quickshell/.config/quickshell/bar/blocks/ActiveWorkspace.qml index 22091f5..7969212 100644 --- a/quickshell/.config/quickshell/bar/blocks/ActiveWorkspace.qml +++ b/quickshell/.config/quickshell/bar/blocks/ActiveWorkspace.qml @@ -1,15 +1,16 @@ import QtQuick +import QtQuick.Layouts import Quickshell.Io import Quickshell.Hyprland import "../" BarText { - text: { - var str = activeWindowTitle - return str.length > chopLength ? str.slice(0, chopLength) + '...' : str; - } + // text: { + // var str = activeWindowTitle + // return str.length > chopLength ? str.slice(0, chopLength) + '...' : str; + // } - property int chopLength: 70 + property int chopLength property string activeWindowTitle Process { diff --git a/quickshell/.config/quickshell/bar/blocks/Battery.qml b/quickshell/.config/quickshell/bar/blocks/Battery.qml index 10be0e0..a8d4ccc 100644 --- a/quickshell/.config/quickshell/bar/blocks/Battery.qml +++ b/quickshell/.config/quickshell/bar/blocks/Battery.qml @@ -4,7 +4,9 @@ import "../" BarBlock { property string battery - text: battery + content: BarText { + symbolText: battery + } Process { id: batteryProc diff --git a/quickshell/.config/quickshell/bar/blocks/Date.qml b/quickshell/.config/quickshell/bar/blocks/Date.qml index 8b94919..11ce193 100644 --- a/quickshell/.config/quickshell/bar/blocks/Date.qml +++ b/quickshell/.config/quickshell/bar/blocks/Date.qml @@ -3,6 +3,8 @@ import "../" BarBlock { id: text - text: ` ${Datetime.date}` + content: BarText { + symbolText: ` ${Datetime.date}` + } } diff --git a/quickshell/.config/quickshell/bar/blocks/Icon.qml b/quickshell/.config/quickshell/bar/blocks/Icon.qml index 217e40c..3f69856 100644 --- a/quickshell/.config/quickshell/bar/blocks/Icon.qml +++ b/quickshell/.config/quickshell/bar/blocks/Icon.qml @@ -1,11 +1,66 @@ import QtQuick import QtQuick.Layouts import Quickshell +import Quickshell.Io +import Quickshell.Widgets +import Qt5Compat.GraphicalEffects import "../" +import "root:/" BarBlock { - Layout.preferredWidth: 30 - rightPadding: 5 - text: "" + id: root + Layout.preferredWidth: 40 + + content: BarText { + text: "" + pointSize: 17 + anchors.horizontalCenterOffset: -2 + } + // content: IconImage { + // id: theicon + // visible: false + // anchors.centerIn: parent + // source: "image://icon/extra-nixos" + // implicitSize: 20 + // } + // DropShadow { + // anchors.fill: parent + // horizontalOffset: 1 + // verticalOffset: 1 + // radius: 6.0 + // samples: 20 + // color: "#000000" + // source: parent.content + // } + // IconImage { + // anchors.centerIn: parent + // source: "image://icon/extra-nixos" + // implicitSize: 20 + // } + + Image { + anchors.fill: parent + source: mouseArea.containsMouse + ? "../images/" + Theme.get.iconPressedColor + ".png" + : "../images/" + Theme.get.iconColor + ".png"; + visible: true + z: -1 + } + + color: "transparent" + + Process { + id: neofetch + running: false + command: [ "sh", "-c", "hyprctl dispatch exec [floating] \ + \"foot -W 95x22 -e zsh -c 'neofetch; while true; do; done'\"" ] + stdout: SplitParser { + onRead: data => console.log(`line read: ${data}`) + } + } + + onClicked: function() { + neofetch.running = true + } } diff --git a/quickshell/.config/quickshell/bar/blocks/Memory.qml b/quickshell/.config/quickshell/bar/blocks/Memory.qml index 26900c0..d274325 100644 --- a/quickshell/.config/quickshell/bar/blocks/Memory.qml +++ b/quickshell/.config/quickshell/bar/blocks/Memory.qml @@ -6,7 +6,9 @@ import "../" BarBlock { id: text - text: ` ${Math.floor(percentFree)}%` + content: BarText { + symbolText: ` ${Math.floor(percentFree)}%` + } property real percentFree diff --git a/quickshell/.config/quickshell/bar/blocks/Sound.qml b/quickshell/.config/quickshell/bar/blocks/Sound.qml index 0553162..0950beb 100644 --- a/quickshell/.config/quickshell/bar/blocks/Sound.qml +++ b/quickshell/.config/quickshell/bar/blocks/Sound.qml @@ -7,9 +7,13 @@ import "../" BarBlock { id: text - text: ` ${Math.floor(sink?.audio.volume * 100)}%` + content: BarText { + symbolText: ` ${Math.floor(volume * 100)}%` + } property PwNode sink: Pipewire.defaultAudioSink + property real volume: sink?.audio.volume + PwObjectTracker { objects: [ sink ] } } diff --git a/quickshell/.config/quickshell/bar/blocks/SystemTray.qml b/quickshell/.config/quickshell/bar/blocks/SystemTray.qml index 12818f1..15c4691 100644 --- a/quickshell/.config/quickshell/bar/blocks/SystemTray.qml +++ b/quickshell/.config/quickshell/bar/blocks/SystemTray.qml @@ -4,13 +4,20 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import Quickshell.Services.SystemTray -import "../" as Bar +import "root:/bar" RowLayout { spacing: 5 Repeater { - model: SystemTray.items + model: ScriptModel { + values: {[...SystemTray.items.values] + .filter((item) => { + return (item.id != "spotify-client" + && item.id != "chrome_status_icon_1") + }) + } + } MouseArea { id: delegate @@ -43,7 +50,6 @@ RowLayout { id: icon anchors.centerIn: parent source: item.icon - implicitSize: 16 } @@ -62,7 +68,7 @@ RowLayout { } } - Bar.Tooltip { + Tooltip { relativeItem: delegate.containsMouse ? delegate : null Label { diff --git a/quickshell/.config/quickshell/bar/blocks/Time.qml b/quickshell/.config/quickshell/bar/blocks/Time.qml index 770403d..5650fcb 100644 --- a/quickshell/.config/quickshell/bar/blocks/Time.qml +++ b/quickshell/.config/quickshell/bar/blocks/Time.qml @@ -3,6 +3,8 @@ import "../" BarBlock { id: text - text: ` ${Datetime.time}` + content: BarText { + symbolText: ` ${Datetime.time}` + } } diff --git a/quickshell/.config/quickshell/bar/blocks/Workspaces.qml b/quickshell/.config/quickshell/bar/blocks/Workspaces.qml index 5d32c48..834654b 100644 --- a/quickshell/.config/quickshell/bar/blocks/Workspaces.qml +++ b/quickshell/.config/quickshell/bar/blocks/Workspaces.qml @@ -2,6 +2,8 @@ import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.Hyprland +import Quickshell.Widgets +import Qt5Compat.GraphicalEffects import "root:/" import "../" @@ -43,21 +45,223 @@ RowLayout { property bool hasClients: ws.name.length > 2 dim: true - underline: isActive || isOpen + underline: false + border.color: Theme.get.buttonBorderColor + radius: 5 + gradient: isActive || isOpen ? Theme.get.buttonActiveGradient : Theme.get.buttonInactiveGradientV + Layout.preferredWidth: content.width + 20 + + Rectangle { + visible: !isActive && !isOpen + gradient: Theme.get.buttonInactiveGradientH + implicitWidth: parent.width + implicitHeight: parent.height + radius: parent.radius + z:-1 + } + + Rectangle { + visible: Theme.get.buttonBorderShadow + implicitWidth: parent.width - 1 + implicitHeight: parent.height - 1 + radius: parent.radius + color: "transparent" // Transparent fill + border.color: parent.isActive || parent.isOpen ? "transparent" : "black" // Inner border color + border.width: 1 // Inner border width + + x: 1 + y: 1 + z: -1 + } + onClicked: function() { Hyprland.dispatch(`workspace ${ws.id}`); } - leftPadding: hasClients ? 2 : 0 - text: { - if (isActive) { - if (!hasClients) - return `${ws.name}` - var split_i = ws.id > 9 ? 3 : 2 - return `${ws.name.slice(0, split_i)}${ws.name.slice(split_i)}` + + content: RowLayout { + spacing: 0 + anchors.centerIn: parent + + Repeater { + id: therepeater + model: ScriptModel { + values: getChunks(ws.name) + } + + delegate: Item { + property bool showText: modelData.type === "text" && modelData.value.length > 0 + property bool showIcon: modelData.type === "icon" + // property int symbolSize: 18 + property int symbolSize: 22 + property int spacerSize: 3 + + implicitWidth: { + if (showText) + return thetext.implicitWidth + if (showIcon) + return symbolSize + return spacerSize; + } + implicitHeight: { + if (showText) + return thetext.implicitHeight + if (showIcon) + return symbolSize + return spacerSize; + } + Layout.alignment: Qt.AlignCenter + + Loader { + id: thetext + anchors.centerIn: parent + active: modelData.type === "text" + sourceComponent: BarText { + text: modelData.value + dim: !isActive + + // pointSize: 10 + } + } + + Loader { + id: theicon + anchors.centerIn: parent + active: modelData.type === "icon" + + sourceComponent: Item { + implicitWidth: inside.implicitWidth + implicitHeight: inside.implicitHeight + IconImage { + id: inside + anchors.centerIn: parent + source: modelData.source + implicitSize: symbolSize + opacity: modelData.active ? 1 : 0.7 + mipmap: true + } + DropShadow { + anchors.fill: parent + verticalOffset: 1 + horizontalOffset: 1 + radius: 8.0 + color: "#000000" + source: inside + opacity: modelData.active ? 1 : 0.7 + } + Rectangle { + visible: modelData.mult > 1 + width: 10 + height: width + radius: width / 2 + color: "black" + opacity: 0.8 + BarText { + text: modelData.mult + pointSize: 10 + dim: !isActive + style: Text.Outline + styleColor: "black" + } + } + } + } + } } - return ws.name } } } + + function getChunks(text) { + let chunks = []; + let buffer = ""; // Temporary storage for text segments + + let symbolChunkInd = {} + + let nextIsActive = false + for (let c of text) { + if (c === "󰀦") { + nextIsActive = true + continue + } + + if (!(c in symbolImgMap)) { + buffer += c; + nextIsActive = false + continue; + } + + if (buffer.length > 0 && !/^\s*$/.test(buffer)) { + chunks.push({ + type: "text", + value: buffer, + }); + buffer = ""; // Reset text buffer + } + + if (!(c in symbolChunkInd)) { + if (chunks[chunks.length - 1].type == "icon") { + chunks.push({type: "spacer"}) + } + symbolChunkInd[c] = chunks.length + chunks.push({ + type: "icon", + active: nextIsActive, + source: `image://icon/${symbolImgMap[c]}`, + mult: 1, // multiplicity; how many times this symbol was seen + }); + } else { + chunks[symbolChunkInd[c]].mult++ + if (nextIsActive) + chunks[symbolChunkInd[c]].active = true; + } + nextIsActive = false + } + + if (buffer.length > 0 && !/^\s*$/.test(buffer)) { + chunks.push({ type: "text", value: buffer}) + } + + return chunks; + } + + property var symbolImgMap: { + "": "extra-scale-vim", + "󰇥": "extra-scale-yazi", + // "󰇧": "extra-zen", + "󰇧": "extra-scale-firefox", + "󰒱": "extra-scale-slack", + "": "extra-scale-terminal-thin", + "": "extra-scale-firefox", + "": "extra-scale-element-desktop", + "󰊴": "extra-scale-discord-circle-dark", + "": "extra-scale-chromium", + // "": "chromium", + "󰽉": "libreoffice-draw", + "󰷈": "libreoffice-writer", + "": "libreoffice-calc", + "󰈩": "libreoffice-impress", + // "󰭹": "signal-desktop", + "󰭹": "extra-signal-simple", + "": "extra-zathura", + "": "extra-spotify", + // "": "extra-scale-spotify", + "": "extra-steam", + "": "extra-scale-bluetooth", + "": "extra-anki", + "": "extra-scale-gimp", + "": "extra-ghidra", + // "󰄄": "com.obsproject.Studio", + "󰄄": "extra-scale-obs", + "": "extra-scale-photos", + "": "extra-anki", + "": "extra-mpv", + "": "extra-virtualbox", + "": "extra-scale-emacs", + "": "monero", + "󰻎": "extra-scale-system-explorer-outline", + "󱍼": "extra-scale-vlc", + "": "com.usebottles.bottles", + "": "Zoom", + } } diff --git a/quickshell/.config/quickshell/bar/images/blue.png b/quickshell/.config/quickshell/bar/images/blue.png new file mode 100644 index 0000000..46fff43 Binary files /dev/null and b/quickshell/.config/quickshell/bar/images/blue.png differ diff --git a/quickshell/.config/quickshell/bar/images/dark_blue.png b/quickshell/.config/quickshell/bar/images/dark_blue.png new file mode 100644 index 0000000..387c175 Binary files /dev/null and b/quickshell/.config/quickshell/bar/images/dark_blue.png differ diff --git a/quickshell/.config/quickshell/bar/images/green.png b/quickshell/.config/quickshell/bar/images/green.png new file mode 100644 index 0000000..ac3b389 Binary files /dev/null and b/quickshell/.config/quickshell/bar/images/green.png differ diff --git a/quickshell/.config/quickshell/bar/images/green.xcf b/quickshell/.config/quickshell/bar/images/green.xcf new file mode 100644 index 0000000..892f81b Binary files /dev/null and b/quickshell/.config/quickshell/bar/images/green.xcf differ diff --git a/quickshell/.config/quickshell/bar/images/orange.png b/quickshell/.config/quickshell/bar/images/orange.png new file mode 100644 index 0000000..dc523c2 Binary files /dev/null and b/quickshell/.config/quickshell/bar/images/orange.png differ diff --git a/quickshell/.config/quickshell/shell.qml b/quickshell/.config/quickshell/shell.qml index 6d8d8da..3079f29 100644 --- a/quickshell/.config/quickshell/shell.qml +++ b/quickshell/.config/quickshell/shell.qml @@ -1,8 +1,8 @@ //@ pragma UseQApplication import Quickshell -import "bar" as Bar +import "bar" ShellRoot { - Bar.Bar {} + Bar {} }