summaryrefslogtreecommitdiff
path: root/.config/quickshell/Modules
diff options
context:
space:
mode:
authorSam Nystrom <sam@samnystrom.dev>2026-01-15 16:53:43 -0500
committerSam Nystrom <sam@samnystrom.dev>2026-01-15 16:53:43 -0500
commit53008538e5bef961e9ceb5abc5c5ee05a559e97d (patch)
tree3ad2f4fa7fbc88ff4bb67c75395cc4acdb9c09fb /.config/quickshell/Modules
parent3ac17574dbcfe68b2fba11aeeb445f04d1170c2a (diff)
update qs config
Diffstat (limited to '.config/quickshell/Modules')
-rw-r--r--.config/quickshell/Modules/Bar.qml162
-rw-r--r--.config/quickshell/Modules/Music.qml298
-rw-r--r--.config/quickshell/Modules/Wall.qml53
3 files changed, 513 insertions, 0 deletions
diff --git a/.config/quickshell/Modules/Bar.qml b/.config/quickshell/Modules/Bar.qml
new file mode 100644
index 0000000..3120574
--- /dev/null
+++ b/.config/quickshell/Modules/Bar.qml
@@ -0,0 +1,162 @@
+import Quickshell
+import Quickshell.Hyprland
+import QtQuick
+import QtQuick.Layouts
+import qs.Services
+
+Variants {
+ model: Quickshell.screens;
+
+ delegate: Component {
+ PanelWindow {
+ id: root
+
+ required property var modelData
+ screen: modelData
+
+ property string fontFamily: "FiraCode Nerd Font"
+ property int fontSize: 14
+
+ anchors {
+ top: true
+ left: true
+ right: true
+ }
+
+ implicitHeight: 36 + 8
+
+ color: "transparent"
+
+ Rectangle {
+ anchors {
+ fill: parent
+ topMargin: 8
+ leftMargin: 8
+ rightMargin: 8
+ }
+ implicitHeight: 36
+ color: "transparent"
+
+ Rectangle {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ implicitWidth: workspaces.implicitWidth + 12*2
+ height: parent.height
+ color: Flexoki.bg
+ radius: 18
+
+ Row {
+ id: workspaces
+ anchors.centerIn: parent
+ height: 20
+ spacing: 6
+
+ Repeater {
+ model: ScriptModel {
+ values: Hyprland.workspaces.values.filter(ws => ws.id >= 0).sort((a, b) => a.id - b.id)
+ }
+
+ delegate: Rectangle {
+ required property HyprlandWorkspace modelData
+ property bool focused: modelData.focused
+ property bool occupied: modelData.toplevels.values.length > 0
+
+ width: 20
+ height: 20
+ radius: 10
+
+ color: {
+ if (!focused) return "transparent"
+ return occupied ? Flexoki.re : Flexoki.ui3
+ }
+
+ border.width: 2
+ border.color: occupied ? Flexoki.re : Flexoki.ui3
+ }
+ }
+ }
+ }
+
+ Music {}
+
+ Rectangle {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ implicitWidth: status.implicitWidth + 12*2
+ height: parent.height
+ color: Flexoki.bg
+ radius: 18
+
+ RowLayout {
+ id: status
+ anchors.centerIn: parent
+ implicitHeight: parent.implicitHeight
+ spacing: 24
+
+ Text {
+ text: {
+ //    
+ var icon
+ if (Volume.volume == 0) {
+ icon = " "
+ } else if (Volume.volume < 50) {
+ icon = " "
+ } else {
+ icon = " "
+ }
+ return icon + Volume.volume + "%"
+ }
+ color: Flexoki.re
+ font { family: root.fontFamily; pixelSize: root.fontSize }
+ }
+
+ Text {
+ text: Wifi.ssid == "" ? "󰖪 " : "󰖩 " + Wifi.ssid
+ color: Flexoki.or
+ font { family: root.fontFamily; pixelSize: root.fontSize }
+ }
+
+ Text {
+ text: " " + Brightness.brightness + "%"
+ color: Flexoki.ye
+ font { family: root.fontFamily; pixelSize: root.fontSize }
+ }
+
+ Text {
+ text: {
+ var icon
+ var i = Math.floor((Battery.capacity - 1) / 10)
+ switch (Battery.status) {
+ case "Full":
+ icon = "󰂄"
+ break
+ case "Discharging":
+ icon = ["󰁺","󰁻","󰁼","󰁽","󰁾","󰁿","󰂀","󰂁","󰂂","󰁹"][i]
+ break
+ case "Charging":
+ icon = ["󰢜","󰂆","󰂇","󰂈","󰢝","󰂉","󰢞","󰂊","󰂋","󰂅"][i]
+ break
+ }
+ return icon + " " + Battery.capacity + "%"
+ }
+ color: Flexoki.gr
+ font { family: root.fontFamily; pixelSize: root.fontSize }
+ }
+
+ Text {
+ text: " " + Qt.formatDateTime(Time.time, "MMM d hh:mm:ss")
+ color: Flexoki.bl
+ font { family: root.fontFamily; pixelSize: root.fontSize }
+ }
+
+ Text {
+ text: "󰐥"
+ color: Flexoki.pu
+ font { family: root.fontFamily; pixelSize: root.fontSize * 1.5 }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/.config/quickshell/Modules/Music.qml b/.config/quickshell/Modules/Music.qml
new file mode 100644
index 0000000..efb717e
--- /dev/null
+++ b/.config/quickshell/Modules/Music.qml
@@ -0,0 +1,298 @@
+import Quickshell
+import QtQuick
+import qs.Services
+
+MouseArea {
+ id: root
+ anchors.centerIn: parent
+ height: parent.implicitHeight
+ width: musicRow.implicitWidth
+ state: "POPUP_CLOSED"
+
+ hoverEnabled: true
+ onEntered: state = "POPUP_OPEN"
+
+ property string fontFamily: "FiraCode Nerd Font"
+ property int fontSize: 14
+
+ property int contractAnimDuration: 150
+
+ states: [
+ State {
+ name: "POPUP_CLOSED"
+ PropertyChanges { target: popup; visible: false }
+ PropertyChanges { target: musicRow; visible: true; spacing: 4 }
+ PropertyChanges { target: songContainer; bottomRightRadius: 4; topRightRadius: 4 }
+ PropertyChanges { target: cavaContainer; bottomLeftRadius: 4; topLeftRadius: 4 }
+ PropertyChanges { target: song; opacity: 1 }
+ PropertyChanges { target: cava; opacity: 1 }
+ PropertyChanges {
+ target: popupRect
+ width: musicRow.width
+ height: 36
+ border.color: Flexoki.bg
+ }
+ },
+ State {
+ name: "POPUP_OPEN"
+ PropertyChanges { target: popup; visible: true }
+ PropertyChanges { target: musicRow; visible: false; spacing: -1 }
+ PropertyChanges { target: songContainer; bottomRightRadius: 0; topRightRadius: 0 }
+ PropertyChanges { target: cavaContainer; bottomLeftRadius: 0; topLeftRadius: 0 }
+ PropertyChanges { target: song; opacity: 0 }
+ PropertyChanges { target: cava; opacity: 0 }
+ PropertyChanges {
+ target: popupRect
+ width: 700
+ height: 500
+ border.color: Flexoki.ui2
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "POPUP_CLOSED"
+ to: "POPUP_OPEN"
+
+ SequentialAnimation {
+ ParallelAnimation {
+ NumberAnimation {
+ target: songContainer
+ properties: "bottomRightRadius,topRightRadius"
+ duration: root.contractAnimDuration
+ easing.type: Easing.InQuad
+ }
+
+ NumberAnimation {
+ target: cavaContainer
+ properties: "bottomLeftRadius,topLeftRadius"
+ duration: root.contractAnimDuration
+ easing.type: Easing.InQuad
+ }
+
+ NumberAnimation {
+ target: musicRow
+ property: "spacing"
+ duration: root.contractAnimDuration
+ easing.type: Easing.OutQuad
+ }
+
+ NumberAnimation {
+ targets: [song, cava]
+ property: "opacity"
+ duration: root.contractAnimDuration
+ easing.type: Easing.OutQuad
+ }
+ }
+
+ PropertyAction { target: popup; property: "visible" }
+ PropertyAction { target: musicRow; property: "visible" }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: popupRect
+ property: "width"
+ duration: 250
+ easing.type: Easing.OutQuad
+ }
+
+ SpringAnimation {
+ target: popupRect
+ property: "height"
+ spring: 5
+ mass: 0.5
+ damping: 0.2
+ epsilon: 0.25
+ }
+
+ ColorAnimation {
+ target: popupRect
+ property: "border.color"
+ duration: 250
+ easing.type: Easing.OutQuad
+ }
+ }
+ }
+ },
+ Transition {
+ from: "POPUP_OPEN"
+ to: "POPUP_CLOSED"
+
+ SequentialAnimation {
+ ParallelAnimation {
+ NumberAnimation {
+ target: popupRect
+ property: "width"
+ duration: 250
+ easing.type: Easing.OutQuad
+ }
+
+ NumberAnimation {
+ target: popupRect
+ property: "height"
+ duration: 250
+ easing.type: Easing.OutQuad
+ }
+
+ ColorAnimation {
+ target: popupRect
+ property: "border.color"
+ duration: 250
+ easing.type: Easing.OutQuad
+ }
+ }
+
+ PropertyAction { target: musicRow; property: "visible" }
+ PropertyAction { target: popup; property: "visible" }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: songContainer
+ properties: "bottomRightRadius,topRightRadius"
+ duration: root.contractAnimDuration
+ easing.type: Easing.InQuad
+ }
+
+ NumberAnimation {
+ target: cavaContainer
+ properties: "bottomLeftRadius,topLeftRadius"
+ duration: root.contractAnimDuration
+ easing.type: Easing.InQuad
+ }
+
+ NumberAnimation {
+ target: musicRow
+ property: "spacing"
+ duration: root.contractAnimDuration
+ easing.type: Easing.OutQuad
+ }
+
+ NumberAnimation {
+ targets: [song, cava]
+ property: "opacity"
+ duration: root.contractAnimDuration
+ easing.type: Easing.OutQuad
+ }
+ }
+ }
+ },
+ ]
+
+ PopupWindow {
+ id: popup
+ anchor.item: root
+ anchor.rect.x: root.width / 2 - width / 2
+ anchor.rect.y: 0
+ implicitWidth: 1920
+ implicitHeight: 600
+ color: "transparent"
+ visible: false
+
+
+ Rectangle {
+ id: popupRect
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ width: 700
+ height: 36
+ color: Flexoki.bg
+ border.color: Flexoki.ui
+ border.width: 2
+ radius: 18
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onExited: root.state = "POPUP_CLOSED"
+ }
+
+ Text {
+ visible: false
+ anchors.centerIn: parent
+ color: Flexoki.tx
+ text: "Hello world!"
+ }
+ }
+ }
+
+ Row {
+ id: musicRow
+ anchors.centerIn: parent
+ height: parent.height
+ spacing: 4
+
+ Rectangle {
+ id: songContainer
+ implicitWidth: song.implicitWidth + 16*2
+ height: parent.height
+ color: Flexoki.bg
+
+ bottomLeftRadius: 18
+ topLeftRadius: 18
+ bottomRightRadius: 4
+ topRightRadius: 4
+
+ Text {
+ id: song
+ anchors.centerIn: parent
+ text: {
+ if (!Song.file) return "Not playing"
+ var text = Song.file
+ if (Song.title) {
+ if (Song.artist) {
+ text = Song.artist + " – " + Song.title
+ } else {
+ text = Song.title
+ }
+ }
+ if (text.length > 60) {
+ text = text.substring(0, 60) + "…"
+ }
+ return text
+ }
+ color: Flexoki.tx
+ font { family: root.fontFamily; pixelSize: root.fontSize }
+ }
+ }
+
+ Rectangle {
+ id: cavaContainer
+ implicitWidth: cava.implicitWidth + 16*2
+ height: parent.height
+ color: Flexoki.bg
+
+ bottomLeftRadius: 4
+ topLeftRadius: 4
+ bottomRightRadius: 18
+ topRightRadius: 18
+
+ Row {
+ id: cava
+ anchors.centerIn: parent
+ height: 15 + 4
+ spacing: 2
+
+ Repeater {
+ model: Cava.heights
+
+ delegate: Rectangle {
+ required property int modelData
+ y: 15 - modelData
+ width: 8
+ height: modelData + 4
+ radius: 4
+ color: Flexoki.tx
+
+ Behavior on height {
+ NumberAnimation { duration: 1000 / 30; easing.type: Easing.Linear }
+ }
+ Behavior on y {
+ NumberAnimation { duration: 1000 / 30; easing.type: Easing.Linear }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/.config/quickshell/Modules/Wall.qml b/.config/quickshell/Modules/Wall.qml
new file mode 100644
index 0000000..b585c2e
--- /dev/null
+++ b/.config/quickshell/Modules/Wall.qml
@@ -0,0 +1,53 @@
+import Quickshell
+import QtQuick
+import QtQuick.Layouts
+import qs.Services
+
+Variants {
+ model: Quickshell.screens;
+
+ delegate: Component {
+ PanelWindow {
+ id: root
+
+ required property var modelData
+ screen: modelData
+
+ property string fontFamily: "Poppins"
+ property int fontSize: 14
+
+ anchors {
+ top: true
+ bottom: true
+ left: true
+ right: true
+ }
+ aboveWindows: false
+
+ color: "transparent"
+
+ ColumnLayout {
+ x: 32
+ y: 80
+
+ Text {
+ text: Qt.formatDateTime(Time.time, "hh:mm")
+ color: Flexoki.bg
+ font { family: root.fontFamily; weight: 800; pixelSize: root.fontSize * 7 }
+ }
+
+ Text {
+ text: Qt.formatDateTime(Time.time, "MMMM d, yyyy")
+ color: Flexoki.bg
+ font { family: root.fontFamily; weight: 300; pixelSize: root.fontSize * 2.25 }
+ }
+
+ Text {
+ text: Uptime.uptime
+ color: Flexoki.bg
+ font { family: root.fontFamily; weight: 300; pixelSize: root.fontSize * 1.75 }
+ }
+ }
+ }
+ }
+}