all repos — quickshell @ 55b30d92682fe15ee20bd17e46c79ca21e176659

A desert-witch desktop shell

0
trickyni trickyniv56@gmail.com
Mon, 06 Apr 2026 12:37:14 +0300
commit

55b30d92682fe15ee20bd17e46c79ca21e176659

parent

c8dd94292004ad74d6235eac1eba89741455077a

63 files changed, 1021 insertions(+), 331 deletions(-)

jump to
A .editorconfig

@@ -0,0 +1,6 @@

+root = true + +[*.qml] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true
M Icons.qmlIcons.qml

@@ -1,64 +1,53 @@

pragma Singleton import QtQuick import Quickshell -import Quickshell.Io - Singleton { id: root + property var modules: { - "sunset": "󰖚", - "ram": "󰍛", - "tasklist": "", - "size": "󰲏", - } - property var workspaces: { - "10": "", - "11": "", - "12": "", + "sunset": "󰖚", + "size": "󰲏" } property var volume: { "mute": "", - "off": "", - "low": "", - "high": "", + "off": "", + "low": "", + "high": "" } property var network: { - "ethernet": "󰈀", - "nobar": "󰣽", - "bar0": "󰣾", - "bar1": "󰣴", - "bar2": "󰣶", - "bar3": "󰣸", - "bar4": "󰣺", + "ethernet": "󰈀", + "nobar": "󰣽", + "bar0": "󰣾", + "bar1": "󰣴", + "bar2": "󰣶", + "bar3": "󰣸", + "bar4": "󰣺" } property var devices: { - "battery": "", - "headphones": "", - "controller": "󰮂", - "earbuds": "󱡏", - "gaming input": "󰮂", - "keyboard": "", - "mouse": "󰍽", - "unknown": "󰂑", - "speakers": "󰓃", - "printer": "󰐪", - "camera": "", - "phone": "", + "battery": "", + "headphones": "", + "controller": "󰮂", + "earbuds": "󱡏", + "gaming input": "󰮂", + "keyboard": "", + "mouse": "󰍽", + "unknown": "󰂑", + "speakers": "󰓃", + "printer": "󰐪", + "camera": "", + "phone": "" } property var battery: { - "10": "󰁺", - "20": "󰁻", - "30": "󰁼", - "40": "󰁽", - "50": "󰁾", - "60": "󰁿", - "70": "󰂀", - "80": "󰂁", - "90": "󰂂", - "100": "󰁹", - + "10": "󰁺", + "20": "󰁻", + "30": "󰁼", + "40": "󰁽", + "50": "󰁾", + "60": "󰁿", + "70": "󰂀", + "80": "󰂁", + "90": "󰂂", + "100": "󰁹" } } - -
M README.mdREADME.md

@@ -25,6 +25,13 @@ Others:

- package moon-phases into the AUR +### post-niri + +- look into converting the bar display into a single-line monospace text display +- redo workspace icons + ## known issues - bluetooth headphones battery disappears sometimes +- network doesn't show disconnection, simply retains last network +- dies when pluging an external monitor, look into
M Resources.qmlResources.qml

@@ -1,45 +1,39 @@

pragma Singleton import QtQuick import Quickshell -import Quickshell.Io - Singleton { id: root property var palette: { - "fg": "#afd2e9", - "bg": "#3b3228", - "bg95": "#43392d", - "bg75": "#4c4134", - "altbg": "#5d4f40", - "bg25": "#6b6055", - "sand": "#c1a387", - "scarlet": "#e86045", - "moss": "#92a650", - "celadon": "#ace1af", - "orange": "#e68d53", - "saffron": "#f8e2a0", - "cyan": "#3eccbe", - "grey": "#868686" + "fg": "#afd2e9", + "bg": "#3b3228", + "bg95": "#43392d", + "bg75": "#4c4134", + "altbg": "#5d4f40", + "bg25": "#6b6055", + "sand": "#c1a387", + "scarlet": "#e86045", + "moss": "#92a650", + "celadon": "#ace1af", + "orange": "#e68d53", + "saffron": "#f8e2a0", + "cyan": "#3eccbe", + "grey": "#868686" } property var fontsize: { - "topbar_text": 16*Size.scale, - "topbar_bamum": 14*Size.scale, - "topbar_icon": 12*Size.scale, - "workspace_icon": 10*Size.scale, - "bottombar_sep": 16*Size.scale, - "bottombar_icon": 10*Size.scale, - "moonphase": 24*Size.scale, - "network_indicator": 9*Size.scale - + "topbar_text": 16 * Size.scale, + "topbar_bamum": 14 * Size.scale, + "topbar_icon": 12 * Size.scale, + "workspace_icon": 10 * Size.scale, + "bottombar_sep": 16 * Size.scale, + "bottombar_icon": 10 * Size.scale, + "moonphase": 24 * Size.scale, + "network_indicator": 9 * Size.scale } property var barsize: { - - "topbar": 18*Size.scale, - "topbar_twister": 15*Size.scale, - "bottombar": 12*Size.scale, + "topbar": 17 * Size.scale, + "bottombar": 15 * Size.scale //on twister, to maintain optimal aspect ratio for terminal at fontsize 16, with 1.5 monitor scaling, bars should have a combined 10px,27px, or 45px height //on irregularnotes, combined height should be 25px or 42px } } -
M bar/Bar.qmlbar/Bar.qml

@@ -1,36 +1,31 @@

// Bar.qml import Quickshell import QtQuick -import QtQuick.Layouts -import ".." -import "modules" as Module -import "classes" as Class +import "modules" Scope { TopBar { - TopbarRight { - Module.Timedate {} - Module.Sunset {} - Module.Volume {} - // Module.Moonphase {} - Module.Ram {} - Module.Taskwarrior {} - } - //topbar middle - Module.Scale{} - TopbarLeft { - Module.Workspaces {} - // Module.Test {} - } + topRightContent: [ + Ram {}, + Volume {}, + Sunset {}, + Timedate {} + ] + topCenterContent: [ + Scale {} + ] + topLeftContent: [] } BottomBar { - BottombarRight { - Module.Battery{} - } - Module.Music{} - BottombarLeft{ - Module.Network{} - } + bottomRightContent: [ + Battery {} + ] + bottomCenterContent: [ + Music {} + ] + bottomLeftContent: [ + Network {}, + NetTest {} + ] } } -
M bar/BottomBar.qmlbar/BottomBar.qml

@@ -1,19 +1,35 @@

import Quickshell import QtQuick -import QtQuick.Layouts import ".." PanelWindow { - id: bottom_bar - anchors { - bottom: true - left: true - right: true - } - margins { - left: 8 - right:8 - } + id: bottomBar + property alias bottomRightContent: bottomRight.children + property alias bottomCenterContent: bottomCenter.children + property alias bottomLeftContent: bottomLeft.children + anchors.bottom: true + anchors.left: true + anchors.right: true implicitHeight: Resources.barsize.bottombar color: Resources.palette.bg + + Row { + id: bottomRow + anchors.fill: parent + spacing: 2 + Row { // LEFT + id: bottomLeft + anchors.left: bottomRow.left + leftPadding: 8 + } + Row { // CENTER + id: bottomCenter + anchors.centerIn: bottomRow + } + Row { // RIGHT + id: bottomRight + anchors.right: bottomRow.right + rightPadding: 8 + } + } }
A bar/BottomBar_WORKS.qml.baka

@@ -0,0 +1,43 @@

+import Quickshell +import QtQuick +import QtQuick.Layouts +import ".." + +PanelWindow { + id: bottomBar + property alias bottomRightContent: bottomRight.children + property alias bottomCenterContent: bottomCenter.children + property alias bottomLeftContent: bottomLeft.children + anchors.bottom: true + anchors.left: true + anchors.right: true + implicitHeight: Resources.barsize.bottombar + color: Resources.palette.bg + + RowLayout { // LEFT + id: bottomRow + anchors.fill: parent + spacing: 2 + uniformCellSizes:false + RowLayout { + id: bottomLeft + Layout.alignment: Qt.AlignLeft + Layout.leftMargin: 8 + } + RowLayout { // CENTER + id: bottomCenter + anchors.centerIn: bottomRow + Layout.fillWidth: true + } + // Item { Layout.fillWidth: true } + RowLayout { // RIGHT + id: bottomRight + Layout.alignment: Qt.AlignRight + Layout.rightMargin: 8 + } + } + // RowLayout { // CENTER + // id: bottomCenter + // anchors.centerIn: bottomRow + // } +}
A bar/BottomBar_thee_rows.qml.bak

@@ -0,0 +1,48 @@

+import Quickshell +import QtQuick +import QtQuick.Layouts +import ".." + +PanelWindow { + id: bottomBar + property alias bottomRightContent: bottomRight.children + property alias bottomCenterContent: bottomCenter.children + property alias bottomLeftContent: bottomLeft.children + aboveWindows: false + anchors { + bottom: true + left: true + right: true + } + implicitHeight: Resources.barsize.bottombar + color: Resources.palette.bg + + RowLayout { //BOTTOM RIGHT + id: bottomRight + Item {Layout.rightMargin: 8} + spacing: 2 + layoutDirection: Qt.RightToLeft + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + } + } + + RowLayout { + id: bottomCenter + spacing: 2 + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + } + + RowLayout { + id: bottomLeft + spacing: 2 + Item {Layout.leftMargin: 8} + anchors { + verticalCenter: parent.verticalCenter + } + } +}
M bar/TopBar.qmlbar/TopBar.qml

@@ -1,25 +1,35 @@

-// TopBar.qml import Quickshell import QtQuick -import QtQuick.Layouts import ".." -import Quickshell.I3 -PanelWindow { - id: top_bar - anchors { - top: true - left: true - right: true - } - margins { - left: 8 - right: 8 - top: 0 - bottom: 0 - } - implicitHeight: (I3.focusedMonitor?.name == "eDP-1") - ? Resources.barsize.topbar_twister - : Resources.barsize.topbar +PanelWindow { + id: topBar + property alias topRightContent: topRight.children + property alias topCenterContent: topCenter.children + property alias topLeftContent: topLeft.children + anchors.top: true + anchors.left: true + anchors.right: true + implicitHeight: Resources.barsize.topbar color: Resources.palette.bg + + Row { + id: topRow + anchors.fill: parent + spacing: 2 + Row { // LEFT + id: topLeft + anchors.left: topRow.left + leftPadding: 8 + } + Row { // CENTER + id: topCenter + anchors.centerIn: topRow + } + Row { // RIGHT + id: topRight + anchors.right: topRow.right + rightPadding: 8 + } + } }
A bar/TopBar_three_rows.qml.bak

@@ -0,0 +1,46 @@

+import Quickshell +import QtQuick +import QtQuick.Layouts +import ".." + +PanelWindow { + id: topBar + property alias topRightContent: topRight.children + property alias topCenterContent: topCenter.children + property alias topLeftContent: topLeft.children + anchors { + top: true + left: true + right: true + } + implicitHeight: Resources.barsize.topbar + color: Resources.palette.bg + + RowLayout { //TOP RIGHT + id: topRight + spacing: 2 + layoutDirection: Qt.RightToLeft + Item {Layout.rightMargin: 8} + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + } + } + RowLayout { // TOP CENTER + id: topCenter + spacing: 2 + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + } + RowLayout { //TOP LEFT + id: topLeft + spacing: 2 + Item {Layout.leftMargin: 8} + anchors { + left: parent.left + verticalCenter: parent.verticalCenter + } + } +}
M bar/classes/Sep.qmlswaybar/classes/Sep.qml

@@ -6,7 +6,8 @@ import "../.."

TopbarText { id: separator - text: "|" + // text: "|" + text: "│" color: Resources.palette.sand padding: 0 // anchors.verticalCenter : parent
M bar/modules/Battery.qmlbar/modules/Battery.qml

@@ -1,64 +1,59 @@

-//Battery.qml +import "../.." import QtQuick -import Quickshell import QtQuick.Layouts import Quickshell.Services.UPower -import "../.." -import "../classes" as Class +import "classes" +RowLayout { + layoutDirection: Qt.RightToLeft + Repeater { + model: UPower.devices.values.filter(d => { + return d.model; + }) -Repeater { - model: UPower.devices.values.filter(d=>d.model) - RowLayout { - spacing: 2 - property var lvl: Math.round(modelData.percentage*100) - property var charge_state: UPowerDeviceState.toString(modelData.state) - property var device_type: UPowerDeviceType.toString(modelData.type) - Class.Sep{} + RowLayout { + property var lvl: Math.round(modelData.percentage * 100) + property var charge_state: UPowerDeviceState.toString(modelData.state) + property var device_type: UPowerDeviceType.toString(modelData.type) + + spacing: 2 + layoutDirection: Qt.RightToLeft + + Text { + id: battery_level_indicator + + Layout.alignment: Qt.AlignCenter + font.pixelSize: 16 * Size.scale + renderType: Text.NativeRendering + font.family: font_proggy.name + text: lvl + "%" + color: (charge_state == "Charging") ? Resources.palette.saffron : (lvl < 20) ? Resources.palette.scarlet : Resources.palette.fg + } + Text { id: battery_device_icon + + Layout.alignment: Qt.AlignCenter font.family: font_icon.name - text: modelData.isLaptopBattery - ? Icons.devices.battery - : modelData.model == "Jupiter of the Monkey" - ? Icons.devices.headphones - : { - "Headphones": Icons.devices.headphones, - "Headset": Icons.devices.headphones, - "Gaming Input": Icons.devices.controller, - "Keyboard": Icons.devices.keyboard, - "Mouse": Icons.devices.mouse, - "Unknown": Icons.devices.unknown, - "Speakers": Icons.devices.speaker, - "Printer": Icons.devices.printer, - "Camera": Icons.devices.camera, - "Phone": Icons.devices.phone, - }[device_type] ?? modelData.model - font.pixelSize: - (device_type == "Gaming Input") - ? 14*Size.scale - : Resources.fontsize.bottombar_icon - color: - modelData.model == "Jupiter of the Monkey" - ? "#897bc7" - : (charge_state == "Charging") - ? Resources.palette.saffron - : lvl < 20 - ? Resources.palette.scarlet - : (charge_state == "FullyCharged") - ? Resources.palette.cyan - : Resources.palette.orange - } - Class.TopbarText { - id: battery_level_indicator - text: lvl+"%" - font.family: font_proggy.name - color: - (charge_state == "Charging") - ? Resources.palette.saffron - : (lvl < 20) - ? Resources.palette.scarlet - : Resources.palette.fg + text: modelData.isLaptopBattery ? Icons.devices.battery : modelData.model == "Jupiter of the Monkey" ? Icons.devices.headphones : { + "Headphones": Icons.devices.headphones, + "Headset": Icons.devices.headphones, + "Gaming Input": Icons.devices.controller, + "Keyboard": Icons.devices.keyboard, + "Mouse": Icons.devices.mouse, + "Unknown": Icons.devices.unknown, + "Speakers": Icons.devices.speaker, + "Printer": Icons.devices.printer, + "Camera": Icons.devices.camera, + "Phone": Icons.devices.phone + }[device_type] ?? modelData.model + font.pixelSize: (device_type == "Gaming Input") ? 14 * Size.scale : Resources.fontsize.bottombar_icon + color: modelData.model == "Jupiter of the Monkey" ? "#897bc7" : (charge_state == "Charging") ? Resources.palette.saffron : lvl < 20 ? Resources.palette.scarlet : (charge_state == "FullyCharged") ? Resources.palette.cyan : Resources.palette.orange + } + + Sep { + Layout.alignment: Qt.AlignBaseline + } } } }
M bar/modules/Music.qmlbar/modules/Music.qml

@@ -1,35 +1,29 @@

- // Sunset.qml +// Sunset.qml import QtQuick -import Quickshell -import Quickshell.Io import QtQuick.Layouts -import QtQuick.Controls import Quickshell.Services.Mpris -import "../../" -import "../classes" as Class +import "classes" RowLayout { - anchors.centerIn: parent id: music + Layout.alignment: Qt.AlignCenter spacing: 4 // property var player: Mpris.players.values[1] - property var player: Mpris.players.values?.find(x=>x.identity=="Music Player Daemon") - Class.BottombarIcon { + property var player: Mpris.players.values?.find(x => x.identity == "Music Player Daemon") + BottombarIcon { // font.pixelSize: this+2 text: ({ - 0: "", - 1: "", - 2: "" - }) [music.player?.playbackState] ?? "" + 0: "", + 1: "", + 2: "" + })[music.player?.playbackState] ?? "" } - Class.TopbarText { + BarText { // font.pixelSize: this-1 // text: music.player.desktopEntry - text: (music.player?.playbackState != 0) - ? (music.player?.trackTitle+" - "+music.player?.trackArtist) - : "" + text: (music.player?.playbackState != 0) ? (music.player?.trackTitle + " - " + music.player?.trackArtist) : "" } -} +} // TODO: make alt-player for firefox/youtube/audiobookshelf // TODO: KDEconnect? // TODO: duration?
A bar/modules/NetTest.qml

@@ -0,0 +1,13 @@

+import QtQuick +import Quickshell +// import Quickshell.Networking +import QtQuick.Layouts +import "../../" +import "classes" + +RowLayout { + Text { + text: '<span style="color: red;">Hello</span> <span style="color: blue;">World</span>' + textFormat: Text.RichText + } +}
M bar/modules/Network.qmlbar/modules/Network.qml

@@ -1,11 +1,9 @@

- // Sunset.qml import QtQuick import Quickshell import Quickshell.Io import QtQuick.Layouts -import QtQuick.Controls import "../../" -import "../classes" as Class +import "classes" RowLayout { property var wifi_strength

@@ -16,16 +14,9 @@ color: Resources.palette.orange

font.family: font_icon.name property var indicator_data font.pixelSize: Resources.fontsize.network_indicator - text: - (indicator_data == 100) ? Icons.network.ethernet - : (indicator_data == 404) ? Icons.network.nobar - : (indicator_data > -50) ? Icons.network.bar4 - : (indicator_data > -60) ? Icons.network.bar3 - : (indicator_data > -70) ? Icons.network.bar2 - : (indicator_data > -80) ? Icons.network.bar1 - : Icons.network.bar0 + text: (indicator_data == 100) ? Icons.network.ethernet : (indicator_data == 404) ? Icons.network.nobar : (indicator_data > -50) ? Icons.network.bar4 : (indicator_data > -60) ? Icons.network.bar3 : (indicator_data > -70) ? Icons.network.bar2 : (indicator_data > -80) ? Icons.network.bar1 : Icons.network.bar0 } - Class.TopbarText { + BarText { id: network font.family: zwj ? font_emoji.name : font_proggy.name Process {

@@ -35,9 +26,9 @@ workingDirectory: Quickshell.shellDir

running: true stdout: StdioCollector { onStreamFinished: { - network.text = this.text.trim().split(" ")[1] - indicator.indicator_data = this.text.split(" ")[0].trim() - zwj=[...network.text].includes('\u200d') + network.text = this.text.trim().split(" ")[1]; + indicator.indicator_data = this.text.split(" ")[0].trim(); + zwj = [...network.text].includes('\u200d'); } } }
M bar/modules/Ram.qmlbar/modules/Ram.qml

@@ -3,28 +3,22 @@ import QtQuick

import Quickshell import Quickshell.Io import QtQuick.Layouts -import "../../" -import "../classes" as Class +import "../.." +import "classes" RowLayout { - spacing: 2 id: ram_module - Class.Sep {} - Class.TopbarIcon { - text: "𖡶" - font.pixelSize: Resources.fontsize.topbar_bamum - } - Class.TopbarText { + spacing: 2 + BarText { id: ram - // Layout.alignment: Qt.AlignBottom - // anchors.bottom: ram_module.top + textFormat: Text.RichText Process { id: ram_script command: ["bar/scripts/ram.sh"] workingDirectory: Quickshell.shellDir running: true stdout: StdioCollector { - onStreamFinished: ram.text = this.text.trim() +"%" + onStreamFinished: ram.text = '<span style="color:#c1a387;">│</span>' + " " + this.text.trim() + "%" } }

@@ -36,4 +30,3 @@ onTriggered: ram_script.running = true

} } } -
M bar/modules/Scale.qmlbar/modules/Scale.qml

@@ -4,12 +4,11 @@ import Quickshell

import QtQuick.Layouts import Quickshell.Services.UPower import "../.." -import "../classes" as Class +import "classes" RowLayout { spacing: 4 - anchors.centerIn: parent - Class.TopbarIcon { + TopbarIcon { text: (Size.scale == 1.5) ? Icons.modules.size : "" font.family: font_icon.name // anchors.centerIn: parent
M bar/modules/Sunset.qmlbar/modules/Sunset.qml

@@ -3,40 +3,31 @@ import QtQuick

import Quickshell import Quickshell.Io import QtQuick.Layouts -import "../../" -import "../classes" as Class -import QtQuick.VectorImage +import "../.." +import "classes" -RowLayout { - id: sunset_module - spacing: 2 - Class.Sep {} - Class.TopbarIcon { - id: sunset_indicator - text: sunset.text[0]== "+" ? "𖡹" :"𖥸" - font.pixelSize: Resources.fontsize.topbar_bamum - } - Class.TopbarText { - id: sunset - // Layout.alignment: Qt.AlignBottom - // anchors.bottom: sunset_module.top - Process { - id: sunset_script - command: ["bar/scripts/suntime.sh"] - workingDirectory: Quickshell.shellDir - running: true - stdout: StdioCollector { - onStreamFinished: { - sunset.text = this.text.trim() - } - } +// TopbarIcon { +// id: sunset_indicator +// text: sunset.text[0] == "+" ? "𖡹" : "𖥸" +// font.pixelSize: Resources.fontsize.topbar_bamum +// } +BarText { + id: sunset + Process { + id: sunset_script + command: ["bar/scripts/suntime.sh"] + workingDirectory: Quickshell.shellDir + running: true + stdout: StdioCollector { + onStreamFinished: { + sunset.text = '<span style="color:#c1a387;">│</span>' + Icons.modules.sunset + this.text.trim(); } } - Timer { - interval: 1000 - running: true - repeat: true - onTriggered: sunset_script.running = true + } + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: sunset_script.running = true } } -
M bar/modules/Taskwarrior.qmlbar/modules/Taskwarrior.qml

@@ -4,21 +4,20 @@ import Quickshell

import Quickshell.Io import QtQuick.Layouts import QtQuick.Controls -import "../classes" as Class +import "classes" import "../../" -import QtQuick.VectorImage RowLayout { spacing: 2 id: taskwarrior_module - // Class.TopbarSVG {icon.source: "../../icons/phosphor/regular/list-checks.svg"} - Class.Sep {} - Class.TopbarIcon { + // TopbarSVG {icon.source: "../../icons/phosphor/regular/list-checks.svg"} + Sep {} + TopbarIcon { text: "𖣋" font.pixelSize: Resources.fontsize.topbar_bamum } - Class.TopbarText { + TopbarText { id: taskwarrior // Layout.alignment: Qt.AlignBottom // anchors.bottom: taskwarrior_module.top
M bar/modules/Timedate.qmlbar/modules/Timedate.qml

@@ -1,25 +1,13 @@

// Timedate.qml import QtQuick import Quickshell -import QtQuick.Layouts -import ".." -import "../classes" as Class +import "classes" -RowLayout { - spacing: 2 - id: timedate - Class.Sep {} - Class.TopbarText { - id: date - text: Qt.formatDateTime(clock.date, "MMM dd") - } - Class.Sep{} - SystemClock { - id: clock - precision: SystemClock.Seconds - } - Class.TopbarText { - id: time - text: Qt.formatDateTime(clock.date, "hh:mm") - } +BarText { + id: timedate + text: '<span style="color:#c1a387;">│</span>' + Qt.formatDateTime(clock.date, "MMM dd (ddd)") + '<span style="color:#c1a387;">│</span>' + Qt.formatDateTime(clock.date, "hh:mm") + SystemClock { + id: clock + precision: SystemClock.Seconds + } }
M bar/modules/Volume.qmlbar/modules/Volume.qml

@@ -1,42 +1,31 @@

import QtQuick -import Quickshell -import QtQuick.Controls.Basic -import QtQuick.Layouts import Quickshell.Services.Pipewire -import "../classes" as Class -import "../../" +import "classes" +import "../.." -RowLayout { - spacing: 2 - layoutDirection: Qt.RightToLeft +BarText { + id: volume_indicator PwObjectTracker { - objects: [ Pipewire.defaultAudioSink ] + objects: [Pipewire.defaultAudioSink] } + property var muted: Pipewire.defaultAudioSink?.audio.muted - id: volume_module - Class.TopbarText { - id: volume_indicator - property var vol: Math.round((Pipewire.defaultAudioSink?.audio.volume ?? 0) * 100) - text: (muted) - ? "" - : vol + "%" - color: Resources.palette.fg - } - Class.TopbarIcon { - text: (muted) - ? "" - : (volume_indicator.vol == 0) - ? "" - : (volume_indicator.vol <= 50) - ? "󰺕" - : (volume_indicator.vol > 50) - ? "" - : Icons.volume.low - color: (muted) - ? Resources.palette.scarlet - : Resources.palette.orange - bottomPadding: 0.5 - } - Class.Sep{} + property var vol: Math.round((Pipewire.defaultAudioSink?.audio.volume ?? 0) * 100) + text: '<span style="color:#c1a387;">│</span>' + Icons.volume.low + " " + vol + "%" } +// TopbarIcon { +// text: (muted) +// ? "" +// : (volume_indicator.vol == 0) +// ? "" +// : (volume_indicator.vol <= 50) +// ? "󰺕" +// : (volume_indicator.vol > 50) +// ? "" +// : Icons.volume.low +// color: (muted) +// ? Resources.palette.scarlet +// : Resources.palette.orange +// bottomPadding: 0.5 +// }
A bar/modules/classes/BarText.qml

@@ -0,0 +1,10 @@

+import QtQuick +import "../../.." + +Text { + font.pixelSize: Resources.fontsize.topbar_text + font.family: font_proggy.name + color: Resources.palette.fg + renderType: Text.NativeRendering + textFormat: Text.RichText +}
A bar/modules/classes/BottombarIcon.qml

@@ -0,0 +1,11 @@

+//BottombarIcon.qml +import QtQuick +import "../../.." + +Text { + font.pixelSize: Resources.fontsize.bottombar_icon + color: Resources.palette.orange + font.family: font_icon.name +} + +
A bar/modules/classes/Sep.qml

@@ -0,0 +1,12 @@

+//TopSep.qml +import QtQuick +import "../../.." + +BarText { + id: separator + // text: "|" + text: "│" + color: Resources.palette.sand + padding: 0 + // anchors.verticalCenter : parent +}
A bar/modules/classes/TopbarIcon.qml

@@ -0,0 +1,10 @@

+//TopbarIcon.qml +import QtQuick +import "../../.." + +Text { + font.pixelSize: Resources.fontsize.topbar_icon + color: Resources.palette.orange + font.family: font_icon.name + // anchors.verticalCenter: verticalCenter +}
A bar/modules/classes/TopbarSVG.qml

@@ -0,0 +1,15 @@

+import QtQuick +import QtQuick.Controls +import "../../.." + +Button { + padding: 0 + icon.color: Resources.palette.orange + icon.width: Resources.fontsize.topbar_text + icon.height: Resources.fontsize.topbar_text + background: Rectangle { + color: Resources.palette.bg + width:0 + height:0 + } +}
A bar/modules/classes/qmldir

@@ -0,0 +1,7 @@

+module Classes + +BottombarIcon BottombarIcon.qml +BarText BarText.qml +Sep Sep.qml +TopbarIcon TopbarIcon.qml +TopbarSVG TopbarSVG.qml
A bar/modules/qmldir

@@ -0,0 +1,12 @@

+module Components + +Battery Battery.qml +Music Music.qml +Network Network.qml +Volume Volume.qml +Ram Ram.qml +Scale Scale.qml +Sunset Sunset.qml +Taskwarrior Taskwarrior.qml +Timedate Timedate.qml +NetTest NetTest.qml
A qmldir

@@ -0,0 +1,5 @@

+module baseShell + +singleton Resources Resources.qml +singleton Size Size.qml +singleton Icons Icons.qml
M shell.qmlshell.qml

@@ -1,10 +1,7 @@

//@ pragma Env QT_QPA_PLATFORM=wayland import Quickshell -import Quickshell.Io import QtQuick -import ".." import "bar" -import "animation" Scope { FontLoader {

@@ -28,5 +25,5 @@ id: font_emoji

source: "fonts/twemoji.ttf" } Bar {} - // Debug{} + // BarOneRow {} }
A swaybar/Bar.qml

@@ -0,0 +1,36 @@

+// Bar.qml +import Quickshell +import QtQuick +import QtQuick.Layouts +import ".." +import "modules" as Module +import "classes" as Class + +Scope { + TopBar { + TopbarRight { + Module.Timedate {} + Module.Sunset {} + Module.Volume {} + // Module.Moonphase {} + Module.Ram {} + // Module.Taskwarrior {} + } + //topbar middle + Module.Scale{} + TopbarLeft { + Module.Workspaces {} + // Module.Test {} + } + } + BottomBar { + BottombarRight { + Module.Battery{} + } + Module.Music{} + BottombarLeft{ + Module.Network{} + } + } +} +
A swaybar/BottomBar.qml

@@ -0,0 +1,19 @@

+import Quickshell +import QtQuick +import QtQuick.Layouts +import ".." + +PanelWindow { + id: bottom_bar + anchors { + bottom: true + left: true + right: true + } + margins { + left: 8 + right:8 + } + implicitHeight: Resources.barsize.bottombar + color: Resources.palette.bg +}
A swaybar/TopBar.qml

@@ -0,0 +1,25 @@

+// TopBar.qml +import Quickshell +import QtQuick +import QtQuick.Layouts +import ".." +import Quickshell.I3 +PanelWindow { + id: top_bar + anchors { + top: true + left: true + right: true + } + margins { + left: 8 + right: 8 + top: 0 + bottom: 0 + } + implicitHeight: (I3.focusedMonitor?.name == "eDP-1") + ? Resources.barsize.topbar_twister + : Resources.barsize.topbar + + color: Resources.palette.bg +}
A swaybar/modules/Battery.qml

@@ -0,0 +1,64 @@

+//Battery.qml +import QtQuick +import Quickshell +import QtQuick.Layouts +import Quickshell.Services.UPower +import "../.." +import "../classes" as Class + + +Repeater { + model: UPower.devices.values.filter(d=>d.model) + RowLayout { + spacing: 2 + property var lvl: Math.round(modelData.percentage*100) + property var charge_state: UPowerDeviceState.toString(modelData.state) + property var device_type: UPowerDeviceType.toString(modelData.type) + Class.Sep{} + Text { + id: battery_device_icon + font.family: font_icon.name + text: modelData.isLaptopBattery + ? Icons.devices.battery + : modelData.model == "Jupiter of the Monkey" + ? Icons.devices.headphones + : { + "Headphones": Icons.devices.headphones, + "Headset": Icons.devices.headphones, + "Gaming Input": Icons.devices.controller, + "Keyboard": Icons.devices.keyboard, + "Mouse": Icons.devices.mouse, + "Unknown": Icons.devices.unknown, + "Speakers": Icons.devices.speaker, + "Printer": Icons.devices.printer, + "Camera": Icons.devices.camera, + "Phone": Icons.devices.phone, + }[device_type] ?? modelData.model + font.pixelSize: + (device_type == "Gaming Input") + ? 14*Size.scale + : Resources.fontsize.bottombar_icon + color: + modelData.model == "Jupiter of the Monkey" + ? "#897bc7" + : (charge_state == "Charging") + ? Resources.palette.saffron + : lvl < 20 + ? Resources.palette.scarlet + : (charge_state == "FullyCharged") + ? Resources.palette.cyan + : Resources.palette.orange + } + Class.TopbarText { + id: battery_level_indicator + text: lvl+"%" + font.family: font_proggy.name + color: + (charge_state == "Charging") + ? Resources.palette.saffron + : (lvl < 20) + ? Resources.palette.scarlet + : Resources.palette.fg + } + } +}
A swaybar/modules/Music.qml

@@ -0,0 +1,37 @@

+ // Sunset.qml +import QtQuick +import Quickshell +import Quickshell.Io +import QtQuick.Layouts +import QtQuick.Controls +import Quickshell.Services.Mpris +import "../../" +import "../classes" as Class + +RowLayout { + anchors.centerIn: parent + id: music + spacing: 4 + // property var player: Mpris.players.values[1] + property var player: Mpris.players.values?.find(x=>x.identity=="Music Player Daemon") + Class.BottombarIcon { + // font.pixelSize: this+2 + text: ({ + 0: "", + 1: "", + 2: "" + }) [music.player?.playbackState] ?? "" + } + Class.TopbarText { + // font.pixelSize: this-1 + // text: music.player.desktopEntry + text: (music.player?.playbackState != 0) + ? (music.player?.trackTitle+" - "+music.player?.trackArtist) + : "" + } +} +// TODO: make alt-player for firefox/youtube/audiobookshelf +// TODO: KDEconnect? +// TODO: duration? +// TODO: Buttons, play/pause, goto source. next/prev +// TODO: keyboard keys
A swaybar/modules/Network.qml

@@ -0,0 +1,51 @@

+ // Sunset.qml +import QtQuick +import Quickshell +import Quickshell.Io +import QtQuick.Layouts +import QtQuick.Controls +import "../../" +import "../classes" as Class + +RowLayout { + property var wifi_strength + property var zwj + Text { + id: indicator + color: Resources.palette.orange + font.family: font_icon.name + property var indicator_data + font.pixelSize: Resources.fontsize.network_indicator + text: + (indicator_data == 100) ? Icons.network.ethernet + : (indicator_data == 404) ? Icons.network.nobar + : (indicator_data > -50) ? Icons.network.bar4 + : (indicator_data > -60) ? Icons.network.bar3 + : (indicator_data > -70) ? Icons.network.bar2 + : (indicator_data > -80) ? Icons.network.bar1 + : Icons.network.bar0 + } + Class.TopbarText { + id: network + font.family: zwj ? font_emoji.name : font_proggy.name + Process { + id: network_script + command: ["bar/scripts/network.sh"] + workingDirectory: Quickshell.shellDir + running: true + stdout: StdioCollector { + onStreamFinished: { + network.text = this.text.trim().split(" ")[1] + indicator.indicator_data = this.text.split(" ")[0].trim() + zwj=[...network.text].includes('\u200d') + } + } + } + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: network_script.running = true + } + } +}
A swaybar/modules/Ram.qml

@@ -0,0 +1,39 @@

+// Ram.qml TODO +import QtQuick +import Quickshell +import Quickshell.Io +import QtQuick.Layouts +import "../../" +import "../classes" as Class + +RowLayout { + spacing: 2 + id: ram_module + Class.Sep {} + Class.TopbarIcon { + text: "𖡶" + font.pixelSize: Resources.fontsize.topbar_bamum + } + Class.TopbarText { + id: ram + // Layout.alignment: Qt.AlignBottom + // anchors.bottom: ram_module.top + Process { + id: ram_script + command: ["bar/scripts/ram.sh"] + workingDirectory: Quickshell.shellDir + running: true + stdout: StdioCollector { + onStreamFinished: ram.text = this.text.trim() +"%" + } + } + + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: ram_script.running = true + } + } +} +
A swaybar/modules/Scale.qml

@@ -0,0 +1,19 @@

+//Scale.qml +import QtQuick +import Quickshell +import QtQuick.Layouts +import Quickshell.Services.UPower +import "../.." +import "../classes" as Class + +RowLayout { + spacing: 4 + anchors.centerIn: parent + Class.TopbarIcon { + text: (Size.scale == 1.5) ? Icons.modules.size : "" + font.family: font_icon.name + // anchors.centerIn: parent + Layout.alignment: Qt.AlignHCenter + leftPadding: 4 + } +}
A swaybar/modules/Sunset.qml

@@ -0,0 +1,42 @@

+// Sunset.qml +import QtQuick +import Quickshell +import Quickshell.Io +import QtQuick.Layouts +import "../../" +import "../classes" as Class +import QtQuick.VectorImage + +RowLayout { + id: sunset_module + spacing: 2 + Class.Sep {} + Class.TopbarIcon { + id: sunset_indicator + text: sunset.text[0]== "+" ? "𖡹" :"𖥸" + font.pixelSize: Resources.fontsize.topbar_bamum + } + Class.TopbarText { + id: sunset + // Layout.alignment: Qt.AlignBottom + // anchors.bottom: sunset_module.top + Process { + id: sunset_script + command: ["bar/scripts/suntime.sh"] + workingDirectory: Quickshell.shellDir + running: true + stdout: StdioCollector { + onStreamFinished: { + sunset.text = this.text.trim() + } + } + } + } + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: sunset_script.running = true + } +} +
A swaybar/modules/Taskwarrior.qml

@@ -0,0 +1,44 @@

+// taskwarrior.qml +import QtQuick +import Quickshell +import Quickshell.Io +import QtQuick.Layouts +import QtQuick.Controls +import "../classes" as Class +import "../../" +import QtQuick.VectorImage + +RowLayout { + spacing: 2 + id: taskwarrior_module + // Class.TopbarSVG {icon.source: "../../icons/phosphor/regular/list-checks.svg"} + Class.Sep {} + Class.TopbarIcon { + text: "𖣋" + font.pixelSize: Resources.fontsize.topbar_bamum + + } + Class.TopbarText { + id: taskwarrior + // Layout.alignment: Qt.AlignBottom + // anchors.bottom: taskwarrior_module.top + Process { + id: taskwarrior_script + command: ["task", "rc.verbose:", "rc.report.next.columns:description", "rc.report.next.labels:1", "limit:1 next"] + workingDirectory: Quickshell.shellDir + running: true + stdout: StdioCollector { + onStreamFinished: taskwarrior.text = this.text.trim() + } + } + + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: taskwarrior_script.running = true + } + } +} + +// "task", "rc.verbose:", "rc.report.next.columns:description", "rc.report.next.labels:1", "limit:1 next"
A swaybar/modules/Timedate.qml

@@ -0,0 +1,25 @@

+// Timedate.qml +import QtQuick +import Quickshell +import QtQuick.Layouts +import ".." +import "../classes" as Class + +RowLayout { + spacing: 2 + id: timedate + SystemClock { + id: clock + precision: SystemClock.Seconds + } + Class.Sep {} + Class.TopbarText { + id: date + text: Qt.formatDateTime(clock.date, "MMM dd (ddd)") + } + Class.Sep{} + Class.TopbarText { + id: time + text: Qt.formatDateTime(clock.date, "hh:mm") + } +}
A swaybar/modules/Volume.qml

@@ -0,0 +1,42 @@

+import QtQuick +import Quickshell +import QtQuick.Controls.Basic +import QtQuick.Layouts +import Quickshell.Services.Pipewire +import "../classes" as Class +import "../../" + +RowLayout { + spacing: 2 + layoutDirection: Qt.RightToLeft + PwObjectTracker { + objects: [ Pipewire.defaultAudioSink ] + } + property var muted: Pipewire.defaultAudioSink?.audio.muted + id: volume_module + Class.TopbarText { + id: volume_indicator + property var vol: Math.round((Pipewire.defaultAudioSink?.audio.volume ?? 0) * 100) + text: (muted) + ? "" + : vol + "%" + color: Resources.palette.fg + } + Class.TopbarIcon { + text: (muted) + ? "" + : (volume_indicator.vol == 0) + ? "" + : (volume_indicator.vol <= 50) + ? "󰺕" + : (volume_indicator.vol > 50) + ? "" + : Icons.volume.low + color: (muted) + ? Resources.palette.scarlet + : Resources.palette.orange + bottomPadding: 0.5 + } + Class.Sep{} +} +
A swaybar/scripts/moon.sh

@@ -0,0 +1,4 @@

+#!/bin/sh +moon-phases -t + +# cargo install moon-phases
A swaybar/scripts/network.sh

@@ -0,0 +1,17 @@

+#!/usr/bin/env bash + +# Find the first wireless interface +ethernet_name=$(nmcli device status | grep ethernet | awk '{print $4}' || false) +if [ $ethernet_name ]; then + echo 100 $ethernet_name +else + wifi_name=$(nmcli device status | grep -m 1 wifi | awk '{print $4}' || false) + if [ $wifi_name ]; then + wifi_device=$(nmcli device status | grep -m 1 wifi | awk '{print $1}') + signal_strength=$(iw dev $wifi_device link | awk '/signal:/ {print $2}') + echo -n "$signal_strength" "$wifi_name" + else + echo 404 + fi +fi +
A swaybar/scripts/network.sh.old

@@ -0,0 +1,15 @@

+#!/usr/bin/env bash + +# Find the first wireless interface +is_ethernet=$(nmcli device status | grep ethernet && true || false) +connection_type=$(iw dev | awk '$1=="Interface"{print $2; exit}') #gets network type (wired/wifi) +network_name=$(iw dev $connection_type link | awk -F': ' '/^\s*SSID:/ {print $2}') +signal_strength=$(iw dev $connection_type link | awk '/signal:/ {print $2}') +if [ is ethernet ]; then + echo -n 100 ethernet $network_name +else + if [ -n $signal_strength ]; then + echo -n "$signal_strength"+"$network_name" + fi +fi +
A swaybar/scripts/ram.sh

@@ -0,0 +1,2 @@

+#!/usr/bin/env bash +free -m | grep Mem | awk '{print ($3/$2)*100}' | tr '.' ' ' | awk '{print $1}'
A swaybar/scripts/suntime.sh

@@ -0,0 +1,23 @@

+#!/bin/bash +if [ ! -e '~/.location' ]; then + coordinates=$(cat ~/.location) +else + echo "<~/.location> file not found. please create one with coordinates in a <XX.XXXXXN XX.XXXXXXXE> format" >&2 + exit 1 +fi + +if [ "$(sunwait poll $coordinates)" == DAY ]; then + sun=$(sunwait list set $coordinates civil) + now=$(date '+%H:%M') + output=$(qalc -t $sun - $now to time) + echo "+"$output +else + exit 1 +fi + + +#echo $(sunwait list set $(cat ~/.location) civil)":00" + + +# coordinates=$(curl -s ipinfo.io | grep loc | cut -d ' ' -f 4 | sed 's/",/E/g' | sed 's/,/N /g' | sed 's/"//g') +# coordinates= xx.xxxN xx.xxxE