From ef9ef549632b9ef5a411b29883638e439c807b47 Mon Sep 17 00:00:00 2001 From: "info@data-pro.nu" Date: Sun, 12 Apr 2026 10:46:43 +0200 Subject: [PATCH] Regenerated --- Droidnix/README.html | 1088 +++++++++++------ Droidnix/README.org | 418 ++++++- .../generated/.config/hypr/window-rules.conf | 10 + .../.config/quickshell/media/shell.qml | 301 +++++ .../.config/quickshell/powermenu/shell.qml | 12 +- Droidnix/generated/.config/scripts/media.sh | 63 + Droidnix/generated/.config/scripts/power.sh | 12 +- Droidnix/generated/.config/waybar/config | 11 + 8 files changed, 1549 insertions(+), 366 deletions(-) create mode 100644 Droidnix/generated/.config/quickshell/media/shell.qml create mode 100755 Droidnix/generated/.config/scripts/media.sh diff --git a/Droidnix/README.html b/Droidnix/README.html index f9304a348..f378b39c6 100644 --- a/Droidnix/README.html +++ b/Droidnix/README.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Droidnix: A Dendritic NixOS + Home Manager Configuration NixOS Configuration Structure @@ -204,127 +204,129 @@

Table of Contents

-
-

Shortcuts

-
+
+

Shortcuts

+

Introduction The Assets Folder @@ -340,25 +342,25 @@

Introduction   intro

-
-

What is Droidnix

-
+
+

What is Droidnix

+

Droidnix is a modular, declarative NixOS + Home Manager configuration system. with configurations managed via Emacs Org and Nix Flakes. The project is designed for reproducibility, maintainability, and cross-machine compatibility.

-
-

Installed components:

-
+
+

Installed components:

+
    -
  • Core
  • -
  • Hyprland
  • +
  • Core
  • +
  • Hyprland
-
-

Goals, project Structure, import hierarchy

-
+
+

Goals, project Structure, import hierarchy

+

This project uses a modular NixOS configuration with Hyprland support, designed for literate programming and cross-device reusability. The Droidnix repository is organized into two main parts: @@ -371,9 +373,9 @@ The Droidnix repository is organized into two main parts:

-
-

Root Level

-
+
+

Root Level

+
  • flake.nix is the entry point and imports:
      @@ -384,16 +386,16 @@ The Droidnix repository is organized into two main parts:
-
-

Generated Structure

-
+
+

Generated Structure

+

The generated/ directory contains all generated configurations, divided into three main groups: system, hyprland, and mangowc.

-
-

First Setup

-
+
+

First Setup

+
  1. Clone this repository.
  2. Run the setup script: ./setup_droid.
  3. @@ -414,9 +416,9 @@ The generated/ directory contains all generated configurations, div The .assets/ folder contains all static files, such as configs, scripts, and themes. These files are not generated and can be edited directly.

-
-

generated/assets/2_b_installed.conf

-
+
+

generated/assets/2_b_installed.conf

+

This is a list of additional apps to install

@@ -494,9 +496,9 @@ com.todoist.Todoist This section contains the Org blocks for tangling Nix code into the generated folders.

-
-

generated/flake.nix

-
+
+

generated/flake.nix

+

The Nix flake definition for Droidnix.

@@ -570,9 +572,9 @@ The Nix flake definition for Droidnix.
-
-

generated/modules/traveldroid/system/Colors.nix

-
+
+

generated/modules/traveldroid/system/Colors.nix

+

Setting the colors for Droidnix.

@@ -656,9 +658,9 @@ in
-
-

generated/hosts/traveldroid/boot.nix

-
+
+

generated/hosts/traveldroid/boot.nix

+
{ config, pkgs, lib, flakeRoot, ... }:
 
@@ -704,9 +706,9 @@ in
 
-
-

generated/hosts/traveldroid/hardware-configuration.nix

-
+
+

generated/hosts/traveldroid/hardware-configuration.nix

+
  1. Boot into NixOS Live ISO or your installed system.
  2. Open a terminal.
  3. @@ -764,9 +766,9 @@ in
-
-

generated/hosts/traveldroid/host.nix

-
+
+

generated/hosts/traveldroid/host.nix

+
{ lib, config, pkgs, flakeRoot, import-tree, home-manager, ... }:
 
@@ -825,13 +827,13 @@ in
 
-
-

generated/traveldroid/modules/apps

-
+
+

generated/traveldroid/modules/apps

+
-
-

generated/modules/traveldroid/apps/2_b_installed.nix

-
+
+

generated/modules/traveldroid/apps/2_b_installed.nix

+

This installs a list of apps

@@ -939,9 +941,9 @@ in {
-
-

generated/modules/traveldroid/apps/emacs/emacs.nix

-
+
+

generated/modules/traveldroid/apps/emacs/emacs.nix

+

This installs emacs

@@ -1037,9 +1039,9 @@ in
-
-

generated/modules/traveldroid/apps/flameshot.nix

-
+
+

generated/modules/traveldroid/apps/flameshot.nix

+

This is top file of this level which contains just an import statement for all relevant files and/or the subfolder in this folder

@@ -1078,9 +1080,9 @@ in
-
-

generated/modules/traveldroid/apps/kitty.nix

-
+
+

generated/modules/traveldroid/apps/kitty.nix

+

This file sets up Kitty terminal

@@ -1138,9 +1140,9 @@ in
-
-

generated/modules/traveldroid/apps/starship.nix

-
+
+

generated/modules/traveldroid/apps/starship.nix

+

This file sets up starship prompt

@@ -1179,9 +1181,9 @@ in
-
-

generated/modules/traveldroid/apps/thunar.nix

-
+
+

generated/modules/traveldroid/apps/thunar.nix

+

This is top file of this level which contains just an import statement for all relevant files and/or the subfolder in this folder

@@ -1222,9 +1224,9 @@ in
-
-

generated/modules/traveldroid/apps/wofi.nix

-
+
+

generated/modules/traveldroid/apps/wofi.nix

+

This is the install for Wofi, the launcher

@@ -1257,9 +1259,9 @@ in
-
-

generated/modules/traveldroid/apps/zenbrowser.nix

-
+
+

generated/modules/traveldroid/apps/zenbrowser.nix

+

This installs zen browser

@@ -1279,9 +1281,9 @@ in
-
-

generated/modules/traveldroid/apps/zsh.nix

-
+
+

generated/modules/traveldroid/apps/zsh.nix

+

This sets up the zsh in the terminal

@@ -1344,13 +1346,13 @@ in
-
-

generated/modules/traveldroid/desktop

-
+
+

generated/modules/traveldroid/desktop

+
-
-

generated/modules/traveldroid/desktop/fonts.nix

-
+
+

generated/modules/traveldroid/desktop/fonts.nix

+

This file installs and configures fonts

@@ -1368,9 +1370,9 @@ This file installs and configures fonts
-
-

generated/modules/traveldroid/desktop/gtk.nix

-
+
+

generated/modules/traveldroid/desktop/gtk.nix

+

Setting up GTK

@@ -1396,9 +1398,9 @@ in
-
-

generated/modules/traveldroid/desktop/hyprland.nix

-
+
+

generated/modules/traveldroid/desktop/hyprland.nix

+

Setting up Hyprland

@@ -1444,9 +1446,9 @@ in
-
-

generated/modules/traveldroid/desktop/stylix.nix

-
+
+

generated/modules/traveldroid/desktop/stylix.nix

+
{ lib, config, pkgs, flakeRoot, stylix, ... }:
 
@@ -1533,9 +1535,9 @@ in
 
-
-

generated/modules/traveldroid/desktop/wallpaper.nix

-
+
+

generated/modules/traveldroid/desktop/wallpaper.nix

+

Setting up wallpaper engine + wallpaper gui

@@ -1634,9 +1636,9 @@ in
-
-

generated/modules/traveldroid/desktop/waybar.nix

-
+
+

generated/modules/traveldroid/desktop/waybar.nix

+

This file installs and configures waybar

@@ -1703,9 +1705,9 @@ in
-
-

generated/modules/traveldroid/desktop/wayland.nix

-
+
+

generated/modules/traveldroid/desktop/wayland.nix

+
{ lib, config, pkgs, ... }:
 
@@ -1735,9 +1737,9 @@ in
 
-
-

generated/modules/traveldroid/desktop/xdg.nix

-
+
+

generated/modules/traveldroid/desktop/xdg.nix

+

This sets the XDG implementation

@@ -1791,13 +1793,13 @@ in
-
-

generated/modules/traveldroid/system

-
+
+

generated/modules/traveldroid/system

+
-
-

generated/modules/traveldroid/system/audio.nix

-
+
+

generated/modules/traveldroid/system/audio.nix

+
{ lib, config, pkgs, ... }:
 
@@ -1815,9 +1817,9 @@ in
 
-
-

generated/modules/traveldroid/system/bluetooth.nix

-
+
+

generated/modules/traveldroid/system/bluetooth.nix

+
{ lib, config, pkgs, home-manager, ... }:
 
@@ -1838,9 +1840,9 @@ in
 
-
-

generated/modules/traveldroid/system/copy_scripts.nix

-
+
+

generated/modules/traveldroid/system/copy_scripts.nix

+
{ lib, config, pkgs, flakeRoot, ... }:
 let
@@ -1878,9 +1880,9 @@ in
 
-
-

generated/modules/traveldroid/system/dbus.nix

-
+
+

generated/modules/traveldroid/system/dbus.nix

+

This sets the dbus implementation

@@ -1907,9 +1909,9 @@ This sets the dbus implementation
-
-

generated/modules/traveldroid/system/gnome-keyring.nix

-
+
+

generated/modules/traveldroid/system/gnome-keyring.nix

+

This sets the dbus implementation

@@ -1957,9 +1959,9 @@ This sets the dbus implementation
-
-

generated/modules/traveldroid/system/login-tuigreet.nix

-
+
+

generated/modules/traveldroid/system/login-tuigreet.nix

+

This sets up tuigreeter which is not fancy but imo fits the aesthetic I am aiming for

@@ -2013,9 +2015,9 @@ in
-
-

generated/modules/traveldroid/system/networking.nix

-
+
+

generated/modules/traveldroid/system/networking.nix

+

This sets the networking.

@@ -2080,9 +2082,9 @@ This sets the networking.
-
-

generated/modules/traveldroid/system/nix.nix

-
+
+

generated/modules/traveldroid/system/nix.nix

+
{ lib, config, ... }:
 
@@ -2098,9 +2100,9 @@ This sets the networking.
 
-
-

generated/modules/traveldroid/system/printing.nix

-
+
+

generated/modules/traveldroid/system/printing.nix

+

This sets the dbus implementation

@@ -2124,9 +2126,9 @@ This sets the dbus implementation
-
-

generated/modules/traveldroid/system/quickshell.nix

-
+
+

generated/modules/traveldroid/system/quickshell.nix

+

This sets the dbus implementation

@@ -2179,13 +2181,13 @@ in
-
-

generated/users

-
+
+

generated/users

+
-
-

generated/users/

-
+
+

generated/users/

+

This is the default user, just search and replace henrov another name if you want to change

@@ -2247,9 +2249,9 @@ in

These are all the prepared config files

-
-

generated/.config/emacs/early-init.el

-
+
+

generated/.config/emacs/early-init.el

+

This contaions emacs

@@ -2350,9 +2352,9 @@ package-archive-priorities '(("gnu" . 99)
-
-

generated/.config/emacs/init.el

-
+
+

generated/.config/emacs/init.el

+

This contaions emacs

@@ -2762,9 +2764,9 @@ the top of the file."
-
-

generated/.config/hypr/animations.conf

-
+
+

generated/.config/hypr/animations.conf

+

These are config files for .config/hypr

@@ -2785,9 +2787,9 @@ animations {
-
-

generated/.config/hypr/behaviour.conf

-
+
+

generated/.config/hypr/behaviour.conf

+

These are config files for .config/hypr

@@ -2801,9 +2803,9 @@ These are config files for .config/hypr
-
-

generated/.config/hypr/bindings.conf

-
+
+

generated/.config/hypr/bindings.conf

+

These are config files for .config/hypr

@@ -2967,9 +2969,9 @@ bind = $mainMod, U, exec, kitty -e bash -lc "$HOME/.config/scripts/update.sh"
-
-

generated/.config/hypr/exec-once.conf

-
+
+

generated/.config/hypr/exec-once.conf

+

These are config files for .config/hypr

@@ -2989,9 +2991,9 @@ exec-once = ~/.config/scripts/hypr-autocolwidth.sh
-
-

generated/.config/hypr/hypridle.conf

-
+
+

generated/.config/hypr/hypridle.conf

+

These are config files for .config/hypr

@@ -3016,9 +3018,9 @@ listener {
-
-

generated/.config/hypr/hyprland.conf

-
+
+

generated/.config/hypr/hyprland.conf

+

These are config files for .config/hypr

@@ -3064,9 +3066,9 @@ misc {
-
-

generated/.config/hypr/hyprlock.conf

-
+
+

generated/.config/hypr/hyprlock.conf

+

These are config files for .config/hypr

@@ -3107,9 +3109,9 @@ label {
-
-

generated/.config/hypr/layer-rules.conf

-
+
+

generated/.config/hypr/layer-rules.conf

+

These are config files for .config/hypr

@@ -3124,9 +3126,9 @@ layerrule = blur on, ignore_alpha 1, match:namespace swaync-notification-window
-
-

generated/.config/hypr/layout.conf

-
+
+

generated/.config/hypr/layout.conf

+

These are config files for .config/hypr

@@ -3141,9 +3143,9 @@ scrolling {
-
-

generated/.config/hypr/monitor-rules.conf

-
+
+

generated/.config/hypr/monitor-rules.conf

+

These are config files for .config/hypr

@@ -3154,9 +3156,9 @@ monitor=DP-1,3840x1080@144,1920x0,1
-
-

generated/.config/hypr/theming.conf

-
+
+

generated/.config/hypr/theming.conf

+

These are config files for .config/hypr

@@ -3206,9 +3208,9 @@ decoration {
-
-

generated/.config/hypr/window-rules.conf

-
+
+

generated/.config/hypr/window-rules.conf

+

These are config files for .config/hypr

@@ -3242,6 +3244,7 @@ windowrule { size = 900 700 } +#Quickshell powermenu windowrule { name = quickshell-powermenu match:title = quickshell-powermenu @@ -3251,13 +3254,22 @@ windowrule { pin = on } +#Quickshell media menu +windowrule { + name = quickshell-media + match:title = quickshell-media + float = on + move = cursor -50% 0 + pin = on +} +
-
-

generated/.config/hypr/workspace-rules.conf

-
+
+

generated/.config/hypr/workspace-rules.conf

+

These are config files for .config/hypr

@@ -3282,11 +3294,322 @@ workspace = 10
-
-

generated/.config/quickshell/powermenu/shell.qml

-
+
+

generated/.config/quickshell/media/shell.qml

+

-This sets up the zsh in the terminal +offers a adio widget +

+
+
// --- This file has been auto-generated. For permanent changes alter the appropriate block in the README.org. ---
+import Quickshell
+import Quickshell.Io
+import QtQuick
+import QtQuick.Layouts
+
+ShellRoot {
+    QtObject {
+        id: colors
+        readonly property color baseAlpha: Qt.rgba(30/255, 30/255, 46/255, 0.95)
+        readonly property color base:      "#1e1e2e"
+        readonly property color surface0:  "#313244"
+        readonly property color surface1:  "#45475a"
+        readonly property color surface2:  "#585b70"
+        readonly property color text:      "#cdd6f4"
+        readonly property color subtext0:  "#a6adc8"
+        readonly property color subtext1:  "#bac2de"
+        readonly property color blue:      "#89b4fa"
+        readonly property color green:     "#a6e3a1"
+        readonly property color teal:      "#94e2d5"
+        readonly property color red:       "#f38ba8"
+        readonly property color mauve:     "#cba6f7"
+        readonly property color peach:     "#fab387"
+        readonly property color lavender:  "#b4befe"
+    }
+
+    // State
+    QtObject {
+        id: media
+        property string artist:   ""
+        property string title:    ""
+        property string album:    ""
+        property string artUrl:   ""
+        property string status:   ""
+        property string device:   ""
+        property real   progress: 0.0
+        property real   duration: 0.0
+        property real   position: 0.0
+    }
+
+    // Poll playerctl every second
+    Timer {
+        interval: 1000
+        running: true
+        repeat: true
+        onTriggered: {
+            artistProc.running = true
+            titleProc.running = true
+            albumProc.running = true
+            artProc.running = true
+            statusProc.running = true
+            positionProc.running = true
+            lengthProc.running = true
+        }
+    }
+
+    Process {
+        id: artistProc
+        command: ["playerctl", "metadata", "artist"]
+        stdout: StdioCollector { onStreamFinished: media.artist = text.trim() }
+    }
+    Process {
+        id: titleProc
+        command: ["playerctl", "metadata", "title"]
+        stdout: StdioCollector { onStreamFinished: media.title = text.trim() }
+    }
+    Process {
+        id: albumProc
+        command: ["playerctl", "metadata", "album"]
+        stdout: StdioCollector { onStreamFinished: media.album = text.trim() }
+    }
+    Process {
+        id: artProc
+        command: ["playerctl", "metadata", "mpris:artUrl"]
+        stdout: StdioCollector { onStreamFinished: media.artUrl = text.trim() }
+    }
+    Process {
+        id: statusProc
+        command: ["playerctl", "status"]
+        stdout: StdioCollector { onStreamFinished: media.status = text.trim() }
+    }
+    Process {
+        id: positionProc
+        command: ["playerctl", "position"]
+        stdout: StdioCollector {
+            onStreamFinished: {
+                media.position = parseFloat(text.trim()) || 0
+                if (media.duration > 0)
+                    media.progress = media.position / media.duration
+            }
+        }
+    }
+    Process {
+        id: lengthProc
+        command: ["playerctl", "metadata", "mpris:length"]
+        stdout: StdioCollector {
+            onStreamFinished: {
+                media.duration = (parseFloat(text.trim()) || 0) / 1000000
+            }
+        }
+    }
+
+    // Playback controls
+    Process { id: prevProc;   command: ["playerctl", "previous"] }
+    Process { id: playProc;   command: ["playerctl", "play-pause"] }
+    Process { id: nextProc;   command: ["playerctl", "next"] }
+
+    FloatingWindow {
+        id: root
+        title: "quickshell-media"
+        visible: true
+        width: 300
+        height: 420
+        color: "transparent"
+
+        Shortcut {
+            sequence: "Escape"
+            onActivated: Qt.quit()
+        }
+
+        // Gradient border
+        Rectangle {
+            anchors.fill: parent
+            anchors.margins: -2
+            radius: 18
+            z: -1
+            gradient: Gradient {
+                orientation: Gradient.Horizontal
+                GradientStop { position: 0.0; color: colors.blue }
+                GradientStop { position: 1.0; color: colors.green }
+            }
+        }
+
+        Rectangle {
+            anchors.fill: parent
+            radius: 16
+            color: colors.base
+
+            ColumnLayout {
+                anchors {
+                    fill: parent
+                    margins: 16
+                }
+                spacing: 12
+
+                // Album art
+                Rectangle {
+                    Layout.fillWidth: true
+                    Layout.preferredHeight: 200
+                    radius: 12
+                    color: colors.surface0
+                    clip: true
+
+                    Image {
+                        anchors.fill: parent
+                        source: media.artUrl
+                        fillMode: Image.PreserveAspectCrop
+                        visible: media.artUrl !== ""
+                    }
+
+                    // Placeholder when no art
+                    Text {
+                        anchors.centerIn: parent
+                        text: "󰝚"
+                        font.pixelSize: 48
+                        color: colors.surface2
+                        visible: media.artUrl === ""
+                    }
+                }
+
+                // Artist
+                Text {
+                    Layout.fillWidth: true
+                    text: media.artist || "Unknown artist"
+                    color: colors.subtext1
+                    font.pixelSize: 12
+                    elide: Text.ElideRight
+                }
+
+                // Title
+                Text {
+                    Layout.fillWidth: true
+                    text: media.title || "Nothing playing"
+                    color: colors.text
+                    font.pixelSize: 14
+                    font.bold: true
+                    elide: Text.ElideRight
+                }
+
+                // Album
+                Text {
+                    Layout.fillWidth: true
+                    text: media.album
+                    color: colors.subtext0
+                    font.pixelSize: 11
+                    elide: Text.ElideRight
+                    visible: media.album !== ""
+                }
+
+                // Device (Spotify)
+                Text {
+                    Layout.fillWidth: true
+                    text: "󰓻 " + media.device
+                    color: colors.green
+                    font.pixelSize: 11
+                    visible: media.device !== ""
+                }
+
+                // Progress bar
+                Rectangle {
+                    Layout.fillWidth: true
+                    height: 4
+                    radius: 2
+                    color: colors.surface1
+
+                    Rectangle {
+                        width: parent.width * media.progress
+                        height: parent.height
+                        radius: parent.radius
+                        gradient: Gradient {
+                            orientation: Gradient.Horizontal
+                            GradientStop { position: 0.0; color: colors.blue }
+                            GradientStop { position: 1.0; color: colors.green }
+                        }
+                    }
+                }
+
+                // Time
+                RowLayout {
+                    Layout.fillWidth: true
+
+                    Text {
+                        text: {
+                            var m = Math.floor(media.position / 60)
+                            var s = Math.floor(media.position % 60)
+                            return m + ":" + (s < 10 ? "0" + s : s)
+                        }
+                        color: colors.subtext0
+                        font.pixelSize: 11
+                    }
+
+                    Item { Layout.fillWidth: true }
+
+                    Text {
+                        text: {
+                            var m = Math.floor(media.duration / 60)
+                            var s = Math.floor(media.duration % 60)
+                            return m + ":" + (s < 10 ? "0" + s : s)
+                        }
+                        color: colors.subtext0
+                        font.pixelSize: 11
+                    }
+                }
+
+                // Playback controls
+                RowLayout {
+                    Layout.fillWidth: true
+                    Layout.alignment: Qt.AlignHCenter
+                    spacing: 24
+
+                    Text {
+                        text: "󰒮"
+                        font.pixelSize: 22
+                        color: prevHover.containsMouse ? colors.blue : colors.text
+                        MouseArea {
+                            id: prevHover
+                            anchors.fill: parent
+                            hoverEnabled: true
+                            onClicked: prevProc.running = true
+                        }
+                    }
+
+                    Text {
+                        text: media.status === "Playing" ? "󰏤" : "󰐊"
+                        font.pixelSize: 28
+                        color: playHover.containsMouse ? colors.green : colors.text
+                        MouseArea {
+                            id: playHover
+                            anchors.fill: parent
+                            hoverEnabled: true
+                            onClicked: playProc.running = true
+                        }
+                    }
+
+                    Text {
+                        text: "󰒭"
+                        font.pixelSize: 22
+                        color: nextHover.containsMouse ? colors.blue : colors.text
+                        MouseArea {
+                            id: nextHover
+                            anchors.fill: parent
+                            hoverEnabled: true
+                            onClicked: nextProc.running = true
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+

generated/.config/quickshell/powermenu/shell.qml

+
+

+Provides a powermenu

import Quickshell
@@ -3365,12 +3688,12 @@ ShellRoot {
 
                 Repeater {
                     model: [
-                        { label: "󰌾 Lock",      cmd: ["loginctl", "lock-session"] },
-                        { label: "󰐥 Shutdown",  cmd: ["systemctl", "poweroff"] },
-                        { label: "󰑙 Reboot",    cmd: ["systemctl", "reboot"] },
-                        { label: "󰍃 Logout",   cmd: ["bash", "-c", "loginctl terminate-session $XDG_SESSION_ID"] },
-                        { label: "󰒲 Hibernate", cmd: ["systemctl", "hibernate"] },
-                        { label: "󰤄 Suspend",   cmd: ["systemctl", "suspend"] },
+                        { label: "󰌾  Lock",      cmd: ["loginctl", "lock-session"] },
+                        { label: "󰐥  Shutdown",  cmd: ["systemctl", "poweroff"] },
+                        { label: "󰑙  Reboot",    cmd: ["systemctl", "reboot"] },
+                        { label: "󰍃  Logout",   cmd: ["bash", "-c", "loginctl terminate-session $XDG_SESSION_ID"] },
+                        { label: "󰒲  Hibernate", cmd: ["systemctl", "hibernate"] },
+                        { label: "󰤄  Suspend",   cmd: ["systemctl", "suspend"] },
                     ]
 
                     delegate: Rectangle {
@@ -3428,9 +3751,81 @@ ShellRoot {
 
-
-

generated/.config/scripts/layout-selector.sh

-
+
+

generated/.config/scripts/media.sh

+
+

+Providing an media +

+
+
#!/usr/bin/env bash
+player=$(playerctl -l 2>/dev/null | head -n1)
+
+if [ -z "$player" ]; then
+    jq -c -n '{text: "", tooltip: "", class: "inactive"}'
+    exit 0
+fi
+
+status=$(playerctl --player="$player" status 2>/dev/null)
+
+if [ "$status" != "Playing" ] && [ "$status" != "Paused" ]; then
+    jq -c -n '{text: "", tooltip: "", class: "inactive"}'
+    exit 0
+fi
+
+artist=$(playerctl --player="$player" metadata artist 2>/dev/null)
+title=$(playerctl --player="$player" metadata title 2>/dev/null)
+album=$(playerctl --player="$player" metadata album 2>/dev/null)
+art=$(playerctl --player="$player" metadata mpris:artUrl 2>/dev/null)
+length=$(playerctl --player="$player" metadata mpris:length 2>/dev/null)
+position=$(playerctl --player="$player" position 2>/dev/null)
+
+# Progress percentage
+if [ -n "$length" ] && [ "$length" -gt 0 ] 2>/dev/null; then
+    progress=$(echo "scale=0; $position * 1000000 / $length * 100 / 100" | bc)
+else
+    progress=0
+fi
+
+# Spotify device
+device=""
+if [[ "$player" == *"spotify"* ]]; then
+    device=$(playerctl --player="$player" metadata xesam:url 2>/dev/null | grep -o 'device=[^&]*' | cut -d= -f2)
+fi
+
+# Ticker text — truncate if long
+text="${artist} — ${title}"
+if [ ${#text} -gt 40 ]; then
+    text="${text:0:37}..."
+fi
+
+# Icon
+if [ "$status" = "Paused" ]; then
+    icon="⏸ "
+else
+    icon="▶ "
+fi
+
+# Build tooltip
+tooltip="${artist}\n${title}\n${album}"
+if [ -n "$device" ]; then
+    tooltip="${tooltip}\n󰓻 ${device}"
+fi
+tooltip="${tooltip}\n$(printf '%.0f' "$progress")%"
+
+jq -c -n \
+    --arg text "${icon}${text}" \
+    --arg tooltip "$tooltip" \
+    --arg class "$player" \
+    --arg art "$art" \
+    '{text: $text, tooltip: $tooltip, class: $class, alt: $art}'
+
+
+
+
+
+

generated/.config/scripts/layout-selector.sh

+

Choose your layout

@@ -3472,9 +3867,9 @@ hyprctl dispatch oSD "Layout: $LAYOUT_NAME" 2000
-
-

generated/.config/scripts/hypr-autocolwidth.sh

-
+
+

generated/.config/scripts/hypr-autocolwidth.sh

+

These are config files for .config/scripts

@@ -3528,9 +3923,9 @@ done
-
-

generated/.config/scripts/power.sh

-
+
+

generated/.config/scripts/power.sh

+

A file containing color variables

@@ -3546,12 +3941,12 @@ A file containing color variables main() { local list=( - "Lock" - "Shutdown" - "Reboot" - "Logout" - "Hibernate" - "Suspend" + "󰌾 Lock" + "󰐥 Shutdown" + "󰑙 Reboot" + "󰍃 Logout" + "󰒲 Hibernate" + "󰤄 Suspend" ) local options=( @@ -3586,9 +3981,9 @@ main
-
-

generated/.config/scripts/update.sh

-
+
+

generated/.config/scripts/update.sh

+

A file containing color variables

@@ -3607,9 +4002,9 @@ flatpak update -y
-
-

generated/.config/shared/Colors.css

-
+
+

generated/.config/shared/Colors.css

+

A file containing color variables

@@ -3649,9 +4044,9 @@ A file containing color variables
-
-

generated/.config/starship.toml

-
+
+

generated/.config/starship.toml

+

These are config files for Starship

@@ -3939,9 +4334,9 @@ crust = "#181926"
-
-

generated/.config/stylix/stylix.conf

-
+
+

generated/.config/stylix/stylix.conf

+

These are config files for .config/stylix

@@ -3978,9 +4373,9 @@ icons = {
-
-

generated/.config/stylix/palette.json

-
+
+

generated/.config/stylix/palette.json

+

These are config files for .config/stylix

@@ -4010,9 +4405,9 @@ These are config files for .config/stylix
-
-

generated/.config/stylix/palette.html

-
+
+

generated/.config/stylix/palette.html

+

These are config files for .config/stylix

@@ -4090,9 +4485,9 @@ These are config files for .config/stylix
-
-

generated/.config/waybar/config

-
+
+

generated/.config/waybar/config

+

These are config files for waybar

@@ -4183,6 +4578,7 @@ These are config files for waybar "group/audio": { "orientation": "horizontal", "modules": [ + "custom/media", "pulseaudio", "pulseaudio/slider", ] @@ -4207,6 +4603,16 @@ These are config files for waybar "tooltip": true }, +"custom/media": { + "exec": "~/.config/scripts/media.sh", + "interval": 2, + "return-type": "json", + "on-click": "qs -c media", + "max-length": 40, + "scroll-step": 1, + "tooltip": true +} + "custom/bluetooth": { "exec": "~/.config/scripts/bluetooth-status.sh", "interval": 5, @@ -4345,9 +4751,9 @@ These are config files for waybar
-
-

generated/.config/waybar/style-dark.css

-
+
+

generated/.config/waybar/style-dark.css

+

This file contains all css for waybar

@@ -4560,9 +4966,9 @@ label#custom-windows:not(.active) {
-
-

generated/.config/scripts/bluetooth-status.sh

-
+
+

generated/.config/scripts/bluetooth-status.sh

+

These are config files for waybar

@@ -4587,9 +4993,9 @@ printf '{"text": "%s", "tooltip": "%s"}\n' "$icon" "$tooltip"
-
-

generated/.config/scripts/hypr-workspaces.sh

-
+
+

generated/.config/scripts/hypr-workspaces.sh

+

These are config files for waybar

@@ -4631,9 +5037,9 @@ jq -c -n \
-
-

generated/.config/scripts/hypr-workspacesmenu.sh

-
+
+

generated/.config/scripts/hypr-workspacesmenu.sh

+

These are config files for waybar

@@ -4649,9 +5055,9 @@ hyprctl dispatch focuswindow address:$addr
-
-

generated/.config/waypaper/config.ini

-
+
+

generated/.config/waypaper/config.ini

+

These are config files for waypaper

@@ -4688,9 +5094,9 @@ keybindings = ~/.config/waypaper/keybindings.ini
-
-

generated/.config/waypaper/config.ini

-
+
+

generated/.config/waypaper/config.ini

+

These are config files for .config/waypaper

@@ -4726,9 +5132,9 @@ keybindings = ~/.config/waypaper/keybindings.ini
-
-

generated/.config/wofi/config

-
+
+

generated/.config/wofi/config

+

These are config files for .config/wofi

@@ -4777,9 +5183,9 @@ prompt = > ...
-
-

generated/.config/wofi/style.css

-
+
+

generated/.config/wofi/style.css

+

These are config files for .config/wofi

@@ -4874,9 +5280,9 @@ These are config files for .config/wofi
-
-

generated/.config/zed/settings.json

-
+
+

generated/.config/zed/settings.json

+

These are config files for Zed editor

@@ -4912,9 +5318,9 @@ These are config files for Zed editor
-
-

generated/.config/zsh/.zshrc

-
+
+

generated/.config/zsh/.zshrc

+

This sets up the zsh in the terminal

@@ -4939,7 +5345,7 @@ fi

Author: Henro Veijer

-

Created: 2026-04-11 za 23:24

+

Created: 2026-04-12 zo 10:46

Validate

diff --git a/Droidnix/README.org b/Droidnix/README.org index c75cf64c0..804814d16 100644 --- a/Droidnix/README.org +++ b/Droidnix/README.org @@ -2619,6 +2619,7 @@ windowrule { size = 900 700 } +#Quickshell powermenu windowrule { name = quickshell-powermenu match:title = quickshell-powermenu @@ -2628,6 +2629,15 @@ windowrule { pin = on } +#Quickshell media menu +windowrule { + name = quickshell-media + match:title = quickshell-media + float = on + move = cursor -50% 0 + pin = on +} + #+END_SRC ** =generated/.config/hypr/workspace-rules.conf= @@ -2651,8 +2661,313 @@ workspace = 9 workspace = 10 #+END_SRC +** =generated/.config/quickshell/media/shell.qml= +offers a adio widget +#+BEGIN_SRC qml :tangle generated/.config/quickshell/media/shell.qml :noweb yes :mkdirp yes :eval never +// --- This file has been auto-generated. For permanent changes alter the appropriate block in the README.org. --- +import Quickshell +import Quickshell.Io +import QtQuick +import QtQuick.Layouts + +ShellRoot { + QtObject { + id: colors + readonly property color baseAlpha: Qt.rgba(30/255, 30/255, 46/255, 0.95) + readonly property color base: "#1e1e2e" + readonly property color surface0: "#313244" + readonly property color surface1: "#45475a" + readonly property color surface2: "#585b70" + readonly property color text: "#cdd6f4" + readonly property color subtext0: "#a6adc8" + readonly property color subtext1: "#bac2de" + readonly property color blue: "#89b4fa" + readonly property color green: "#a6e3a1" + readonly property color teal: "#94e2d5" + readonly property color red: "#f38ba8" + readonly property color mauve: "#cba6f7" + readonly property color peach: "#fab387" + readonly property color lavender: "#b4befe" + } + + // State + QtObject { + id: media + property string artist: "" + property string title: "" + property string album: "" + property string artUrl: "" + property string status: "" + property string device: "" + property real progress: 0.0 + property real duration: 0.0 + property real position: 0.0 + } + + // Poll playerctl every second + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: { + artistProc.running = true + titleProc.running = true + albumProc.running = true + artProc.running = true + statusProc.running = true + positionProc.running = true + lengthProc.running = true + } + } + + Process { + id: artistProc + command: ["playerctl", "metadata", "artist"] + stdout: StdioCollector { onStreamFinished: media.artist = text.trim() } + } + Process { + id: titleProc + command: ["playerctl", "metadata", "title"] + stdout: StdioCollector { onStreamFinished: media.title = text.trim() } + } + Process { + id: albumProc + command: ["playerctl", "metadata", "album"] + stdout: StdioCollector { onStreamFinished: media.album = text.trim() } + } + Process { + id: artProc + command: ["playerctl", "metadata", "mpris:artUrl"] + stdout: StdioCollector { onStreamFinished: media.artUrl = text.trim() } + } + Process { + id: statusProc + command: ["playerctl", "status"] + stdout: StdioCollector { onStreamFinished: media.status = text.trim() } + } + Process { + id: positionProc + command: ["playerctl", "position"] + stdout: StdioCollector { + onStreamFinished: { + media.position = parseFloat(text.trim()) || 0 + if (media.duration > 0) + media.progress = media.position / media.duration + } + } + } + Process { + id: lengthProc + command: ["playerctl", "metadata", "mpris:length"] + stdout: StdioCollector { + onStreamFinished: { + media.duration = (parseFloat(text.trim()) || 0) / 1000000 + } + } + } + + // Playback controls + Process { id: prevProc; command: ["playerctl", "previous"] } + Process { id: playProc; command: ["playerctl", "play-pause"] } + Process { id: nextProc; command: ["playerctl", "next"] } + + FloatingWindow { + id: root + title: "quickshell-media" + visible: true + width: 300 + height: 420 + color: "transparent" + + Shortcut { + sequence: "Escape" + onActivated: Qt.quit() + } + + // Gradient border + Rectangle { + anchors.fill: parent + anchors.margins: -2 + radius: 18 + z: -1 + gradient: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: colors.blue } + GradientStop { position: 1.0; color: colors.green } + } + } + + Rectangle { + anchors.fill: parent + radius: 16 + color: colors.base + + ColumnLayout { + anchors { + fill: parent + margins: 16 + } + spacing: 12 + + // Album art + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 200 + radius: 12 + color: colors.surface0 + clip: true + + Image { + anchors.fill: parent + source: media.artUrl + fillMode: Image.PreserveAspectCrop + visible: media.artUrl !== "" + } + + // Placeholder when no art + Text { + anchors.centerIn: parent + text: "󰝚" + font.pixelSize: 48 + color: colors.surface2 + visible: media.artUrl === "" + } + } + + // Artist + Text { + Layout.fillWidth: true + text: media.artist || "Unknown artist" + color: colors.subtext1 + font.pixelSize: 12 + elide: Text.ElideRight + } + + // Title + Text { + Layout.fillWidth: true + text: media.title || "Nothing playing" + color: colors.text + font.pixelSize: 14 + font.bold: true + elide: Text.ElideRight + } + + // Album + Text { + Layout.fillWidth: true + text: media.album + color: colors.subtext0 + font.pixelSize: 11 + elide: Text.ElideRight + visible: media.album !== "" + } + + // Device (Spotify) + Text { + Layout.fillWidth: true + text: "󰓻 " + media.device + color: colors.green + font.pixelSize: 11 + visible: media.device !== "" + } + + // Progress bar + Rectangle { + Layout.fillWidth: true + height: 4 + radius: 2 + color: colors.surface1 + + Rectangle { + width: parent.width * media.progress + height: parent.height + radius: parent.radius + gradient: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: colors.blue } + GradientStop { position: 1.0; color: colors.green } + } + } + } + + // Time + RowLayout { + Layout.fillWidth: true + + Text { + text: { + var m = Math.floor(media.position / 60) + var s = Math.floor(media.position % 60) + return m + ":" + (s < 10 ? "0" + s : s) + } + color: colors.subtext0 + font.pixelSize: 11 + } + + Item { Layout.fillWidth: true } + + Text { + text: { + var m = Math.floor(media.duration / 60) + var s = Math.floor(media.duration % 60) + return m + ":" + (s < 10 ? "0" + s : s) + } + color: colors.subtext0 + font.pixelSize: 11 + } + } + + // Playback controls + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + spacing: 24 + + Text { + text: "󰒮" + font.pixelSize: 22 + color: prevHover.containsMouse ? colors.blue : colors.text + MouseArea { + id: prevHover + anchors.fill: parent + hoverEnabled: true + onClicked: prevProc.running = true + } + } + + Text { + text: media.status === "Playing" ? "󰏤" : "󰐊" + font.pixelSize: 28 + color: playHover.containsMouse ? colors.green : colors.text + MouseArea { + id: playHover + anchors.fill: parent + hoverEnabled: true + onClicked: playProc.running = true + } + } + + Text { + text: "󰒭" + font.pixelSize: 22 + color: nextHover.containsMouse ? colors.blue : colors.text + MouseArea { + id: nextHover + anchors.fill: parent + hoverEnabled: true + onClicked: nextProc.running = true + } + } + } + } + } + } +} +#+END_SRC + ** =generated/.config/quickshell/powermenu/shell.qml= -This sets up the zsh in the terminal +Provides a powermenu #+BEGIN_SRC qml :tangle generated/.config/quickshell/powermenu/shell.qml :noweb yes :mkdirp yes :eval never import Quickshell import Quickshell.Io @@ -2730,12 +3045,12 @@ ShellRoot { Repeater { model: [ - { label: "󰌾 Lock", cmd: ["loginctl", "lock-session"] }, - { label: "󰐥 Shutdown", cmd: ["systemctl", "poweroff"] }, - { label: "󰑙 Reboot", cmd: ["systemctl", "reboot"] }, - { label: "󰍃 Logout", cmd: ["bash", "-c", "loginctl terminate-session $XDG_SESSION_ID"] }, - { label: "󰒲 Hibernate", cmd: ["systemctl", "hibernate"] }, - { label: "󰤄 Suspend", cmd: ["systemctl", "suspend"] }, + { label: "󰌾 Lock", cmd: ["loginctl", "lock-session"] }, + { label: "󰐥 Shutdown", cmd: ["systemctl", "poweroff"] }, + { label: "󰑙 Reboot", cmd: ["systemctl", "reboot"] }, + { label: "󰍃 Logout", cmd: ["bash", "-c", "loginctl terminate-session $XDG_SESSION_ID"] }, + { label: "󰒲 Hibernate", cmd: ["systemctl", "hibernate"] }, + { label: "󰤄 Suspend", cmd: ["systemctl", "suspend"] }, ] delegate: Rectangle { @@ -2791,6 +3106,72 @@ ShellRoot { } #+END_SRC +** =generated/.config/scripts/media.sh= +Providing an media +#+BEGIN_SRC sh :tangle generated/.config/scripts/media.sh :shebang "#!/usr/bin/env bash" :noweb yes :mkdirp yes :eval never +#!/usr/bin/env bash +player=$(playerctl -l 2>/dev/null | head -n1) + +if [ -z "$player" ]; then + jq -c -n '{text: "", tooltip: "", class: "inactive"}' + exit 0 +fi + +status=$(playerctl --player="$player" status 2>/dev/null) + +if [ "$status" != "Playing" ] && [ "$status" != "Paused" ]; then + jq -c -n '{text: "", tooltip: "", class: "inactive"}' + exit 0 +fi + +artist=$(playerctl --player="$player" metadata artist 2>/dev/null) +title=$(playerctl --player="$player" metadata title 2>/dev/null) +album=$(playerctl --player="$player" metadata album 2>/dev/null) +art=$(playerctl --player="$player" metadata mpris:artUrl 2>/dev/null) +length=$(playerctl --player="$player" metadata mpris:length 2>/dev/null) +position=$(playerctl --player="$player" position 2>/dev/null) + +# Progress percentage +if [ -n "$length" ] && [ "$length" -gt 0 ] 2>/dev/null; then + progress=$(echo "scale=0; $position * 1000000 / $length * 100 / 100" | bc) +else + progress=0 +fi + +# Spotify device +device="" +if [[ "$player" == *"spotify"* ]]; then + device=$(playerctl --player="$player" metadata xesam:url 2>/dev/null | grep -o 'device=[^&]*' | cut -d= -f2) +fi + +# Ticker text — truncate if long +text="${artist} — ${title}" +if [ ${#text} -gt 40 ]; then + text="${text:0:37}..." +fi + +# Icon +if [ "$status" = "Paused" ]; then + icon="⏸ " +else + icon="▶ " +fi + +# Build tooltip +tooltip="${artist}\n${title}\n${album}" +if [ -n "$device" ]; then + tooltip="${tooltip}\n󰓻 ${device}" +fi +tooltip="${tooltip}\n$(printf '%.0f' "$progress")%" + +jq -c -n \ + --arg text "${icon}${text}" \ + --arg tooltip "$tooltip" \ + --arg class "$player" \ + --arg art "$art" \ + '{text: $text, tooltip: $tooltip, class: $class, alt: $art}' +#+END_SRC + ** =generated/.config/scripts/layout-selector.sh= Choose your layout #+BEGIN_SRC bash :tangle generated/.config/scripts/layout-selector.sh :shebang "#!/usr/bin/env bash" :noweb yes :mkdirp yes :eval never @@ -2895,12 +3276,12 @@ A file containing color variables main() { local list=( - "Lock" - "Shutdown" - "Reboot" - "Logout" - "Hibernate" - "Suspend" + "󰌾 Lock" + "󰐥 Shutdown" + "󰑙 Reboot" + "󰍃 Logout" + "󰒲 Hibernate" + "󰤄 Suspend" ) local options=( @@ -3490,6 +3871,7 @@ These are config files for waybar "group/audio": { "orientation": "horizontal", "modules": [ + "custom/media", "pulseaudio", "pulseaudio/slider", ] @@ -3514,6 +3896,16 @@ These are config files for waybar "tooltip": true }, +"custom/media": { + "exec": "~/.config/scripts/media.sh", + "interval": 2, + "return-type": "json", + "on-click": "qs -c media", + "max-length": 40, + "scroll-step": 1, + "tooltip": true +} + "custom/bluetooth": { "exec": "~/.config/scripts/bluetooth-status.sh", "interval": 5, diff --git a/Droidnix/generated/.config/hypr/window-rules.conf b/Droidnix/generated/.config/hypr/window-rules.conf index 069ae2444..cdb978651 100644 --- a/Droidnix/generated/.config/hypr/window-rules.conf +++ b/Droidnix/generated/.config/hypr/window-rules.conf @@ -28,6 +28,7 @@ windowrule { size = 900 700 } +#Quickshell powermenu windowrule { name = quickshell-powermenu match:title = quickshell-powermenu @@ -36,3 +37,12 @@ windowrule { move = cursor -50% 0 pin = on } + +#Quickshell media menu +windowrule { + name = quickshell-media + match:title = quickshell-media + float = on + move = cursor -50% 0 + pin = on +} diff --git a/Droidnix/generated/.config/quickshell/media/shell.qml b/Droidnix/generated/.config/quickshell/media/shell.qml new file mode 100644 index 000000000..38e025668 --- /dev/null +++ b/Droidnix/generated/.config/quickshell/media/shell.qml @@ -0,0 +1,301 @@ +// --- This file has been auto-generated. For permanent changes alter the appropriate block in the README.org. --- +// --- This file has been auto-generated. For permanent changes alter the appropriate block in the README.org. --- +import Quickshell +import Quickshell.Io +import QtQuick +import QtQuick.Layouts + +ShellRoot { + QtObject { + id: colors + readonly property color baseAlpha: Qt.rgba(30/255, 30/255, 46/255, 0.95) + readonly property color base: "#1e1e2e" + readonly property color surface0: "#313244" + readonly property color surface1: "#45475a" + readonly property color surface2: "#585b70" + readonly property color text: "#cdd6f4" + readonly property color subtext0: "#a6adc8" + readonly property color subtext1: "#bac2de" + readonly property color blue: "#89b4fa" + readonly property color green: "#a6e3a1" + readonly property color teal: "#94e2d5" + readonly property color red: "#f38ba8" + readonly property color mauve: "#cba6f7" + readonly property color peach: "#fab387" + readonly property color lavender: "#b4befe" + } + + // State + QtObject { + id: media + property string artist: "" + property string title: "" + property string album: "" + property string artUrl: "" + property string status: "" + property string device: "" + property real progress: 0.0 + property real duration: 0.0 + property real position: 0.0 + } + + // Poll playerctl every second + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: { + artistProc.running = true + titleProc.running = true + albumProc.running = true + artProc.running = true + statusProc.running = true + positionProc.running = true + lengthProc.running = true + } + } + + Process { + id: artistProc + command: ["playerctl", "metadata", "artist"] + stdout: StdioCollector { onStreamFinished: media.artist = text.trim() } + } + Process { + id: titleProc + command: ["playerctl", "metadata", "title"] + stdout: StdioCollector { onStreamFinished: media.title = text.trim() } + } + Process { + id: albumProc + command: ["playerctl", "metadata", "album"] + stdout: StdioCollector { onStreamFinished: media.album = text.trim() } + } + Process { + id: artProc + command: ["playerctl", "metadata", "mpris:artUrl"] + stdout: StdioCollector { onStreamFinished: media.artUrl = text.trim() } + } + Process { + id: statusProc + command: ["playerctl", "status"] + stdout: StdioCollector { onStreamFinished: media.status = text.trim() } + } + Process { + id: positionProc + command: ["playerctl", "position"] + stdout: StdioCollector { + onStreamFinished: { + media.position = parseFloat(text.trim()) || 0 + if (media.duration > 0) + media.progress = media.position / media.duration + } + } + } + Process { + id: lengthProc + command: ["playerctl", "metadata", "mpris:length"] + stdout: StdioCollector { + onStreamFinished: { + media.duration = (parseFloat(text.trim()) || 0) / 1000000 + } + } + } + + // Playback controls + Process { id: prevProc; command: ["playerctl", "previous"] } + Process { id: playProc; command: ["playerctl", "play-pause"] } + Process { id: nextProc; command: ["playerctl", "next"] } + + FloatingWindow { + id: root + title: "quickshell-media" + visible: true + width: 300 + height: 420 + color: "transparent" + + Shortcut { + sequence: "Escape" + onActivated: Qt.quit() + } + + // Gradient border + Rectangle { + anchors.fill: parent + anchors.margins: -2 + radius: 18 + z: -1 + gradient: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: colors.blue } + GradientStop { position: 1.0; color: colors.green } + } + } + + Rectangle { + anchors.fill: parent + radius: 16 + color: colors.base + + ColumnLayout { + anchors { + fill: parent + margins: 16 + } + spacing: 12 + + // Album art + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 200 + radius: 12 + color: colors.surface0 + clip: true + + Image { + anchors.fill: parent + source: media.artUrl + fillMode: Image.PreserveAspectCrop + visible: media.artUrl !== "" + } + + // Placeholder when no art + Text { + anchors.centerIn: parent + text: "󰝚" + font.pixelSize: 48 + color: colors.surface2 + visible: media.artUrl === "" + } + } + + // Artist + Text { + Layout.fillWidth: true + text: media.artist || "Unknown artist" + color: colors.subtext1 + font.pixelSize: 12 + elide: Text.ElideRight + } + + // Title + Text { + Layout.fillWidth: true + text: media.title || "Nothing playing" + color: colors.text + font.pixelSize: 14 + font.bold: true + elide: Text.ElideRight + } + + // Album + Text { + Layout.fillWidth: true + text: media.album + color: colors.subtext0 + font.pixelSize: 11 + elide: Text.ElideRight + visible: media.album !== "" + } + + // Device (Spotify) + Text { + Layout.fillWidth: true + text: "󰓻 " + media.device + color: colors.green + font.pixelSize: 11 + visible: media.device !== "" + } + + // Progress bar + Rectangle { + Layout.fillWidth: true + height: 4 + radius: 2 + color: colors.surface1 + + Rectangle { + width: parent.width * media.progress + height: parent.height + radius: parent.radius + gradient: Gradient { + orientation: Gradient.Horizontal + GradientStop { position: 0.0; color: colors.blue } + GradientStop { position: 1.0; color: colors.green } + } + } + } + + // Time + RowLayout { + Layout.fillWidth: true + + Text { + text: { + var m = Math.floor(media.position / 60) + var s = Math.floor(media.position % 60) + return m + ":" + (s < 10 ? "0" + s : s) + } + color: colors.subtext0 + font.pixelSize: 11 + } + + Item { Layout.fillWidth: true } + + Text { + text: { + var m = Math.floor(media.duration / 60) + var s = Math.floor(media.duration % 60) + return m + ":" + (s < 10 ? "0" + s : s) + } + color: colors.subtext0 + font.pixelSize: 11 + } + } + + // Playback controls + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + spacing: 24 + + Text { + text: "󰒮" + font.pixelSize: 22 + color: prevHover.containsMouse ? colors.blue : colors.text + MouseArea { + id: prevHover + anchors.fill: parent + hoverEnabled: true + onClicked: prevProc.running = true + } + } + + Text { + text: media.status === "Playing" ? "󰏤" : "󰐊" + font.pixelSize: 28 + color: playHover.containsMouse ? colors.green : colors.text + MouseArea { + id: playHover + anchors.fill: parent + hoverEnabled: true + onClicked: playProc.running = true + } + } + + Text { + text: "󰒭" + font.pixelSize: 22 + color: nextHover.containsMouse ? colors.blue : colors.text + MouseArea { + id: nextHover + anchors.fill: parent + hoverEnabled: true + onClicked: nextProc.running = true + } + } + } + } + } + } +} diff --git a/Droidnix/generated/.config/quickshell/powermenu/shell.qml b/Droidnix/generated/.config/quickshell/powermenu/shell.qml index dbfeb98bd..1d78901e3 100644 --- a/Droidnix/generated/.config/quickshell/powermenu/shell.qml +++ b/Droidnix/generated/.config/quickshell/powermenu/shell.qml @@ -75,12 +75,12 @@ ShellRoot { Repeater { model: [ - { label: "󰌾 Lock", cmd: ["loginctl", "lock-session"] }, - { label: "󰐥 Shutdown", cmd: ["systemctl", "poweroff"] }, - { label: "󰑙 Reboot", cmd: ["systemctl", "reboot"] }, - { label: "󰍃 Logout", cmd: ["bash", "-c", "loginctl terminate-session $XDG_SESSION_ID"] }, - { label: "󰒲 Hibernate", cmd: ["systemctl", "hibernate"] }, - { label: "󰤄 Suspend", cmd: ["systemctl", "suspend"] }, + { label: "󰌾 Lock", cmd: ["loginctl", "lock-session"] }, + { label: "󰐥 Shutdown", cmd: ["systemctl", "poweroff"] }, + { label: "󰑙 Reboot", cmd: ["systemctl", "reboot"] }, + { label: "󰍃 Logout", cmd: ["bash", "-c", "loginctl terminate-session $XDG_SESSION_ID"] }, + { label: "󰒲 Hibernate", cmd: ["systemctl", "hibernate"] }, + { label: "󰤄 Suspend", cmd: ["systemctl", "suspend"] }, ] delegate: Rectangle { diff --git a/Droidnix/generated/.config/scripts/media.sh b/Droidnix/generated/.config/scripts/media.sh new file mode 100755 index 000000000..ca4878481 --- /dev/null +++ b/Droidnix/generated/.config/scripts/media.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# --- This file has been auto-generated. For permanent changes alter the appropriate block in the README.org. --- +#!/usr/bin/env bash +player=$(playerctl -l 2>/dev/null | head -n1) + +if [ -z "$player" ]; then + jq -c -n '{text: "", tooltip: "", class: "inactive"}' + exit 0 +fi + +status=$(playerctl --player="$player" status 2>/dev/null) + +if [ "$status" != "Playing" ] && [ "$status" != "Paused" ]; then + jq -c -n '{text: "", tooltip: "", class: "inactive"}' + exit 0 +fi + +artist=$(playerctl --player="$player" metadata artist 2>/dev/null) +title=$(playerctl --player="$player" metadata title 2>/dev/null) +album=$(playerctl --player="$player" metadata album 2>/dev/null) +art=$(playerctl --player="$player" metadata mpris:artUrl 2>/dev/null) +length=$(playerctl --player="$player" metadata mpris:length 2>/dev/null) +position=$(playerctl --player="$player" position 2>/dev/null) + +# Progress percentage +if [ -n "$length" ] && [ "$length" -gt 0 ] 2>/dev/null; then + progress=$(echo "scale=0; $position * 1000000 / $length * 100 / 100" | bc) +else + progress=0 +fi + +# Spotify device +device="" +if [[ "$player" == *"spotify"* ]]; then + device=$(playerctl --player="$player" metadata xesam:url 2>/dev/null | grep -o 'device=[^&]*' | cut -d= -f2) +fi + +# Ticker text — truncate if long +text="${artist} — ${title}" +if [ ${#text} -gt 40 ]; then + text="${text:0:37}..." +fi + +# Icon +if [ "$status" = "Paused" ]; then + icon="⏸ " +else + icon="▶ " +fi + +# Build tooltip +tooltip="${artist}\n${title}\n${album}" +if [ -n "$device" ]; then + tooltip="${tooltip}\n󰓻 ${device}" +fi +tooltip="${tooltip}\n$(printf '%.0f' "$progress")%" + +jq -c -n \ + --arg text "${icon}${text}" \ + --arg tooltip "$tooltip" \ + --arg class "$player" \ + --arg art "$art" \ + '{text: $text, tooltip: $tooltip, class: $class, alt: $art}' diff --git a/Droidnix/generated/.config/scripts/power.sh b/Droidnix/generated/.config/scripts/power.sh index 5dd57ea24..927bdc644 100755 --- a/Droidnix/generated/.config/scripts/power.sh +++ b/Droidnix/generated/.config/scripts/power.sh @@ -11,12 +11,12 @@ main() { local list=( - "Lock" - "Shutdown" - "Reboot" - "Logout" - "Hibernate" - "Suspend" + "󰌾 Lock" + "󰐥 Shutdown" + "󰑙 Reboot" + "󰍃 Logout" + "󰒲 Hibernate" + "󰤄 Suspend" ) local options=( diff --git a/Droidnix/generated/.config/waybar/config b/Droidnix/generated/.config/waybar/config index 100394d3c..2b0da104a 100644 --- a/Droidnix/generated/.config/waybar/config +++ b/Droidnix/generated/.config/waybar/config @@ -84,6 +84,7 @@ "group/audio": { "orientation": "horizontal", "modules": [ + "custom/media", "pulseaudio", "pulseaudio/slider", ] @@ -108,6 +109,16 @@ "tooltip": true }, +"custom/media": { + "exec": "~/.config/scripts/media.sh", + "interval": 2, + "return-type": "json", + "on-click": "qs -c media", + "max-length": 40, + "scroll-step": 1, + "tooltip": true +} + "custom/bluetooth": { "exec": "~/.config/scripts/bluetooth-status.sh", "interval": 5,