diff --git a/.chezmoiexternal.toml b/.chezmoiexternal.toml index 884ff1b..c3d522d 100644 --- a/.chezmoiexternal.toml +++ b/.chezmoiexternal.toml @@ -6,3 +6,10 @@ type = "git-repo" url = "https://github.com/Meisterlala/nvim.git" refreshPeriod = "30s" + +{{ if ne .chezmoi.os "windows" }} +[".config/quickshell"] + type = "git-repo" + url = "https://github.com/Meisterlala/quickshell.git" + refreshPeriod = "30s" +{{ end }} diff --git a/dot_config/quickshell/main/Bar.qml b/dot_config/quickshell/main/Bar.qml deleted file mode 100644 index 341238d..0000000 --- a/dot_config/quickshell/main/Bar.qml +++ /dev/null @@ -1,251 +0,0 @@ -import "./components" -import "./modules" -import QtQuick -import Quickshell -import Quickshell.Hyprland - -Scope { - id: root - - required property var ipc - - function isPrimary(screen) { - return screen && screen.name === "DP-3"; - } - - function isSecondary(screen) { - return screen && screen.name === "DP-2"; - } - - Theme { - id: theme - } - - Variants { - model: Quickshell.screens - - PanelWindow { - id: bar - - required property var modelData - - screen: modelData - implicitHeight: 38 - color: "transparent" - - anchors { - top: true - left: true - right: true - } - - Rectangle { - anchors.fill: parent - color: theme.alpha(theme.base, 0.4) - } - - Row { - id: left - - anchors.left: parent.left - anchors.leftMargin: 4 - anchors.verticalCenter: parent.verticalCenter - spacing: 4 - - Workspaces { - barWindow: bar - } - - } - - ActiveWindow { - anchors.centerIn: parent - maxWidth: Math.max(280, parent.width * 0.36) - } - - Row { - id: right - - anchors.right: parent.right - anchors.rightMargin: 4 - anchors.verticalCenter: parent.verticalCenter - spacing: 4 - - NotificationModule { - moduleVisible: root.isPrimary(bar.screen) - } - - Tray { - visible: root.isPrimary(bar.screen) - barWindow: bar - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "fritz-traffic" - command: "/home/misti/.config/waybar/fritz_traffic.py" - interval: 10000 - onClickCommand: "qs ipc -c main call bar refreshModule fritz-traffic" - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "nvidia-driver" - command: "/home/misti/.config/waybar/nvidia-driver.py" - interval: 60000 - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "systemd-failed-units" - command: "/home/misti/.config/waybar/failed-units.sh" - interval: 10000 - onClickCommand: "/home/misti/.config/waybar/restart-failed.sh" - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "scrcpy-active" - command: "/home/misti/.config/waybar/scrcpy-active.sh" - interval: 2000 - onClickCommand: "/home/misti/.config/waybar/scrcpy-active.sh --kill" - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "updates" - command: "/home/misti/.config/waybar/arch_updates.py" - interval: 900000 - onClickCommand: "ghostty -e bash -lc 'paru -Syu; echo; read -rp \"Press Enter to close...\"'" - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "codex" - command: "/home/misti/.config/waybar/codex_usage.py" - interval: 300000 - } - - ScriptModule { - moduleVisible: root.isPrimary(bar.screen) - ipc: root.ipc - moduleName: "habits" - command: "/home/misti/.local/bin/habits-waybar" - interval: 30000 - onClickCommand: "/home/misti/.local/bin/habits-waybar --toggle" - } - - Audio { - moduleVisible: root.isPrimary(bar.screen) - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "load" - command: "awk '{print $1 \" \" $2 \" \" $3}' /proc/loadavg" - interval: 10000 - parseJson: false - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "hypridle" - command: "/home/misti/.config/waybar/idle_inhibit.py" - interval: 5000 - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "gpu" - command: "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits | awk '{printf \"%2d%% 󰢮\", $1}'" - interval: 5000 - parseJson: false - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "cpu" - command: "top -bn1 | awk '/Cpu\\(s\\)/ {printf \"%2d%% \", 100 - $8}'" - interval: 3000 - parseJson: false - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "memory" - command: "free | awk '/Mem:/ {printf \"%2d%% \", $3/$2*100}'" - interval: 5000 - parseJson: false - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "k8s-alerts" - command: "/home/misti/.config/waybar/k8s-alerts.py" - interval: 60000 - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "weight" - command: "/home/misti/opencode/weight-unlock/show_weight_waybar.py" - interval: 60000 - onClickCommand: "/home/misti/opencode/weight-unlock/show_weight_waybar.py --toggle" - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "sleep" - textOverride: "" - onClickCommand: "systemctl suspend" - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "garage-longhorn" - command: "/home/misti/.config/waybar/garage-status.sh longhorn-backup L" - interval: 10000 - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "garage-velero" - command: "/home/misti/.config/waybar/garage-status.sh velero V" - interval: 10000 - } - - ScriptModule { - moduleVisible: root.isSecondary(bar.screen) - ipc: root.ipc - moduleName: "garage-kopia" - command: "/home/misti/.config/waybar/garage-status.sh kopia K" - interval: 10000 - } - - Clock { - barWindow: bar - } - - } - - } - - } - -} diff --git a/dot_config/quickshell/main/README.md b/dot_config/quickshell/main/README.md deleted file mode 100644 index 24826da..0000000 --- a/dot_config/quickshell/main/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Quickshell Main - -First replacement slice for the current Waybar setup. - -Run manually after installing Quickshell: - -```sh -qs -c main -``` - -Useful IPC calls: - -```sh -qs ipc -c main show -qs ipc -c main call bar refreshModule updates -qs ipc -c main call bar refreshModule all -qs ipc -c main call bar getState -``` - -This config intentionally does not modify Hyprland autostart yet. Keep `waybar.service` enabled until the Quickshell bar has been tested. diff --git a/dot_config/quickshell/main/Theme.qml b/dot_config/quickshell/main/Theme.qml deleted file mode 100644 index e451621..0000000 --- a/dot_config/quickshell/main/Theme.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick - -QtObject { - readonly property string rosewater: "#f5e0dc" - readonly property string red: "#f38ba8" - readonly property string yellow: "#f9e2af" - readonly property string green: "#a6e3a1" - readonly property string sky: "#89dceb" - readonly property string text: "#cdd6f4" - readonly property string subtext0: "#a6adc8" - readonly property string overlay1: "#7f849c" - readonly property string surface2: "#585b70" - readonly property string surface1: "#45475a" - readonly property string surface0: "#313244" - readonly property string base: "#1e1e2e" - readonly property string mantle: "#181825" - readonly property string crust: "#11111b" - - function alpha(hex, opacity) { - const clean = hex.replace("#", ""); - const value = Math.round(opacity * 255).toString(16).padStart(2, "0"); - return `#${value}${clean}`; - } - - function classColor(name) { - if (name === "critical" || name === "error") - return red; - - if (name === "warning" || name === "users") - return yellow; - - if (name === "upload") - return green; - - if (name === "delete") - return red; - - return text; - } - -} diff --git a/dot_config/quickshell/main/components/ModulePill.qml b/dot_config/quickshell/main/components/ModulePill.qml deleted file mode 100644 index ea8308c..0000000 --- a/dot_config/quickshell/main/components/ModulePill.qml +++ /dev/null @@ -1,45 +0,0 @@ -import ".." -import QtQuick - -Rectangle { - id: root - - property alias text: label.text - property string moduleClass: "" - property bool hoverable: true - - signal clicked(int button) - - implicitWidth: Math.max(30, label.implicitWidth + 20) - implicitHeight: 30 - radius: 8 - color: mouse.containsMouse && hoverable ? theme.surface2 : theme.alpha(theme.surface0, 0.55) - border.color: theme.alpha(theme.text, 0.1) - border.width: 1 - visible: text.length > 0 - - Theme { - id: theme - } - - Text { - id: label - - anchors.centerIn: parent - color: theme.classColor(root.moduleClass) - font.family: "FiraCode Nerd Font" - font.pixelSize: 14 - textFormat: Text.PlainText - verticalAlignment: Text.AlignVCenter - } - - MouseArea { - id: mouse - - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton - hoverEnabled: true - onClicked: root.clicked(mouse.button) - } - -} diff --git a/dot_config/quickshell/main/components/PopupSurface.qml b/dot_config/quickshell/main/components/PopupSurface.qml deleted file mode 100644 index addf2a2..0000000 --- a/dot_config/quickshell/main/components/PopupSurface.qml +++ /dev/null @@ -1,16 +0,0 @@ -import ".." -import QtQuick - -Rectangle { - id: root - - radius: 16 - color: theme.alpha(theme.mantle, 0.96) - border.color: theme.alpha(theme.text, 0.12) - border.width: 1 - - Theme { - id: theme - } - -} diff --git a/dot_config/quickshell/main/dot_gitignore b/dot_config/quickshell/main/dot_gitignore deleted file mode 100644 index dfbea23..0000000 --- a/dot_config/quickshell/main/dot_gitignore +++ /dev/null @@ -1 +0,0 @@ -.qmlls.ini diff --git a/dot_config/quickshell/main/modules/ActiveWindow.qml b/dot_config/quickshell/main/modules/ActiveWindow.qml deleted file mode 100644 index 754669c..0000000 --- a/dot_config/quickshell/main/modules/ActiveWindow.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick -import Quickshell.Hyprland - -Text { - id: root - - property int maxWidth: 420 - - function cleanTitle(title) { - if (!title) - return ""; - - return title.replace(/(.*) — Zen Browser$/, "$1"); - } - - text: cleanTitle(Hyprland.activeToplevel ? Hyprland.activeToplevel.title : "") - color: "#cdd6f4" - font.family: "FiraCode Nerd Font" - font.pixelSize: 14 - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter - width: Math.min(maxWidth, implicitWidth) -} diff --git a/dot_config/quickshell/main/modules/Audio.qml b/dot_config/quickshell/main/modules/Audio.qml deleted file mode 100644 index c088e42..0000000 --- a/dot_config/quickshell/main/modules/Audio.qml +++ /dev/null @@ -1,19 +0,0 @@ -import "../components" -import QtQuick - -ScriptModule { - moduleName: "audio" - command: "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{ if ($3 == \"[MUTED]\") print \"󰖁\"; else printf \"%d%% \", $2 * 100 }'" - interval: 2000 - parseJson: false - onClickCommand: "pwvucontrol" - onRightClickCommand: "helvum" - onClicked: (button) => { - if (button === Qt.MiddleButton) - runCommand("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"); - else if (button === Qt.LeftButton) - runCommand(onClickCommand); - else if (button === Qt.RightButton) - runCommand(onRightClickCommand); - } -} diff --git a/dot_config/quickshell/main/modules/Clock.qml b/dot_config/quickshell/main/modules/Clock.qml deleted file mode 100644 index 6bebdd0..0000000 --- a/dot_config/quickshell/main/modules/Clock.qml +++ /dev/null @@ -1,85 +0,0 @@ -import "../components" -import QtQuick -import Quickshell - -Item { - id: root - - required property var barWindow - property bool popupOpen: false - - implicitWidth: pill.implicitWidth - implicitHeight: pill.implicitHeight - - SystemClock { - id: clock - - precision: SystemClock.Minutes - } - - ModulePill { - id: pill - - text: Qt.formatDateTime(clock.date, "hh:mm") + " " - onClicked: root.popupOpen = !root.popupOpen - } - - PopupWindow { - anchor.window: root.barWindow - anchor.rect.x: root.barWindow.width - width - 8 - anchor.rect.y: root.barWindow.height + 8 - implicitWidth: 320 - implicitHeight: 250 - visible: root.popupOpen - grabFocus: true - onVisibleChanged: { - if (!visible) - root.popupOpen = false; - - } - - PopupSurface { - anchors.fill: parent - - Column { - anchors.fill: parent - anchors.margins: 18 - spacing: 12 - - Text { - text: Qt.formatDateTime(clock.date, "dddd, dd.MM.yyyy") - color: "#cdd6f4" - font.family: "FiraCode Nerd Font" - font.pixelSize: 18 - } - - Text { - text: Qt.formatDateTime(clock.date, "hh:mm") - color: "#f5e0dc" - font.family: "FiraCode Nerd Font" - font.pixelSize: 44 - font.bold: true - } - - Rectangle { - width: parent.width - height: 1 - color: "#3345475a" - } - - Text { - width: parent.width - wrapMode: Text.WordWrap - text: "Calendar grid and agenda go here next. This popup is already anchored to the clock and managed by Quickshell, not a Waybar tooltip." - color: "#a6adc8" - font.family: "FiraCode Nerd Font" - font.pixelSize: 13 - } - - } - - } - - } - -} diff --git a/dot_config/quickshell/main/modules/NotificationModule.qml b/dot_config/quickshell/main/modules/NotificationModule.qml deleted file mode 100644 index 0367eb2..0000000 --- a/dot_config/quickshell/main/modules/NotificationModule.qml +++ /dev/null @@ -1,11 +0,0 @@ -import "../components" -import QtQuick - -ScriptModule { - moduleName: "notification" - command: "command -v swaync-client >/dev/null && swaync-client -swb || true" - interval: 5000 - parseJson: true - onClickCommand: "swaync-client -t -sw" - onRightClickCommand: "swaync-client -d -sw" -} diff --git a/dot_config/quickshell/main/modules/ScriptModule.qml b/dot_config/quickshell/main/modules/ScriptModule.qml deleted file mode 100644 index 40a8c19..0000000 --- a/dot_config/quickshell/main/modules/ScriptModule.qml +++ /dev/null @@ -1,97 +0,0 @@ -import "../components" -import QtQuick -import Quickshell.Io - -ModulePill { - id: root - - required property string moduleName - property var ipc: null - property string command: "" - property int interval: 30000 - property bool parseJson: true - property bool hideEmptyText: true - property bool moduleVisible: true - property string onClickCommand: "" - property string onRightClickCommand: "" - property string textOverride: "" - property string currentText: textOverride - property string currentClass: "" - - function runCommand(commandText) { - if (commandText.length === 0) - return ; - - runner.exec(["sh", "-lc", commandText]); - } - - function refresh() { - if (textOverride.length > 0) { - currentText = textOverride; - return ; - } - runCommand(command); - } - - function applyOutput(output) { - const trimmed = output.trim(); - if (trimmed.length === 0) { - currentText = ""; - currentClass = ""; - return ; - } - if (!parseJson) { - currentText = trimmed; - currentClass = ""; - return ; - } - try { - const parsed = JSON.parse(trimmed); - currentText = String(parsed.text ?? ""); - currentClass = Array.isArray(parsed.class) ? parsed.class[0] ?? "" : String(parsed.class ?? ""); - } catch (error) { - currentText = trimmed; - currentClass = "error"; - } - } - - text: currentText - moduleClass: currentClass - visible: moduleVisible && (!hideEmptyText || currentText.length > 0) - onClicked: (button) => { - if (button === Qt.LeftButton) - runCommand(onClickCommand); - - if (button === Qt.RightButton) - runCommand(onRightClickCommand || `qs ipc -c main call bar refreshModule ${moduleName}`); - - } - Component.onCompleted: refresh() - - Timer { - interval: root.interval - running: root.command.length > 0 && root.interval > 0 - repeat: true - onTriggered: root.refresh() - } - - Process { - id: runner - - stdout: StdioCollector { - onStreamFinished: root.applyOutput(this.text) - } - - } - - Connections { - function onRefreshRequested(name) { - if (name === root.moduleName || name === "all") - root.refresh(); - - } - - target: root.ipc - } - -} diff --git a/dot_config/quickshell/main/modules/Tray.qml b/dot_config/quickshell/main/modules/Tray.qml deleted file mode 100644 index 871a68b..0000000 --- a/dot_config/quickshell/main/modules/Tray.qml +++ /dev/null @@ -1,46 +0,0 @@ -import "../components" -import QtQuick -import Quickshell.Services.SystemTray -import Quickshell.Widgets - -Row { - id: root - - required property var barWindow - - spacing: 8 - - Repeater { - model: SystemTray.items - - Item { - required property var modelData - - width: 24 - height: 30 - - IconImage { - anchors.centerIn: parent - width: 20 - height: 20 - source: modelData.icon - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton - onClicked: (mouse) => { - if (mouse.button === Qt.LeftButton && !modelData.onlyMenu) - modelData.activate(); - else if (mouse.button === Qt.MiddleButton) - modelData.secondaryActivate(); - else - modelData.display(root.barWindow, parent.x, root.barWindow.height); - } - } - - } - - } - -} diff --git a/dot_config/quickshell/main/modules/Workspaces.qml b/dot_config/quickshell/main/modules/Workspaces.qml deleted file mode 100644 index 9ff11a8..0000000 --- a/dot_config/quickshell/main/modules/Workspaces.qml +++ /dev/null @@ -1,45 +0,0 @@ -import "../components" -import QtQuick -import Quickshell.Hyprland - -Row { - id: root - - required property var barWindow - - function monitorMatches(workspace) { - if (!workspace || !workspace.monitor || !barWindow.screen) - return true; - - return workspace.monitor.name === barWindow.screen.name; - } - - function workspaceText(workspace) { - if (!workspace) - return ""; - - const count = workspace.toplevels ? workspace.toplevels.values.length : 0; - if (count === 0) - return String(workspace.id); - - return `${workspace.id} ${count}`; - } - - spacing: 4 - - Repeater { - model: Hyprland.workspaces - - ModulePill { - required property var modelData - - text: root.workspaceText(modelData) - moduleClass: modelData.urgent ? "critical" : "" - visible: root.monitorMatches(modelData) - color: modelData.active ? "#585b70" : (modelData.toplevels && modelData.toplevels.values.length > 0 ? "#55313244" : "#22313244") - onClicked: modelData.activate() - } - - } - -} diff --git a/dot_config/quickshell/main/popups/.keep b/dot_config/quickshell/main/popups/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/dot_config/quickshell/main/services/ShellIpc.qml b/dot_config/quickshell/main/services/ShellIpc.qml deleted file mode 100644 index 82afd82..0000000 --- a/dot_config/quickshell/main/services/ShellIpc.qml +++ /dev/null @@ -1,29 +0,0 @@ -import Quickshell -import Quickshell.Io - -Scope { - id: root - - signal refreshRequested(string name) - signal popupRequested(string name) - - property string lastMessage: "ready" - - IpcHandler { - target: "bar" - - function refreshModule(name: string): void { - root.lastMessage = `refresh:${name}`; - root.refreshRequested(name); - } - - function togglePopup(name: string): void { - root.lastMessage = `popup:${name}`; - root.popupRequested(name); - } - - function getState(): string { - return root.lastMessage; - } - } -} diff --git a/dot_config/quickshell/main/shell.qml b/dot_config/quickshell/main/shell.qml deleted file mode 100644 index 3b3c921..0000000 --- a/dot_config/quickshell/main/shell.qml +++ /dev/null @@ -1,15 +0,0 @@ -import "./services" -import Quickshell - -Scope { - id: root - - ShellIpc { - id: shellIpc - } - - Bar { - ipc: shellIpc - } - -}