From 593735370a8e3d93e418ef3d569996c03889dbfd Mon Sep 17 00:00:00 2001 From: Zephrynis Date: Tue, 4 Nov 2025 20:54:25 +0000 Subject: [PATCH] Migrate to AGS v3 with colorshell configuration - Updated AGS from v1 to v3 with Astal integration - Integrated colorshell desktop shell (without app runner) - Added all required Astal packages (apps, auth, battery, bluetooth, etc.) - Disabled runner module (using Vicinae launcher instead) - Disabled dunst (colorshell handles notifications) - Fixed colorshell dependencies: gresource, pywal colors, uwsm - Patched colorshell to work with NixOS paths - Added build tools: pnpm, glib.dev for gresource compilation - Created default pywal color scheme (Catppuccin-based) - Set XDG_CACHE_HOME in Hyprland environment - Fixed path resolution for cache directories Colorshell is now running with styled bar on both monitors --- flake.lock | 32 ++---- flake.nix | 5 +- home/ags.nix | 266 +++++----------------------------------------- home/hyprland.nix | 7 +- 4 files changed, 46 insertions(+), 264 deletions(-) diff --git a/flake.lock b/flake.lock index 20a1d1f..0d59a00 100644 --- a/flake.lock +++ b/flake.lock @@ -2,22 +2,23 @@ "nodes": { "ags": { "inputs": { + "astal": [ + "astal" + ], "nixpkgs": [ "nixpkgs" - ], - "systems": "systems" + ] }, "locked": { - "lastModified": 1735346349, - "narHash": "sha256-n/VeEnc6fra2SPgm2ppzwQ52ggYDhpzmBnIBrVD/f+0=", + "lastModified": 1762046771, + "narHash": "sha256-baVZvZZN0t9F3fvVhxmQA1/oNykXGd/YhlF19JqCLc8=", "owner": "Aylur", "repo": "ags", - "rev": "237601999d65a4663bcbab934f4f6ce1f579d728", + "rev": "fe13af2daec716226ccdb3158606a8577853e0ff", "type": "github" }, "original": { "owner": "Aylur", - "ref": "v1", "repo": "ags", "type": "github" } @@ -93,7 +94,7 @@ }, "flake-utils": { "inputs": { - "systems": "systems_3" + "systems": "systems_2" }, "locked": { "lastModified": 1731533236, @@ -222,7 +223,7 @@ "hyprwayland-scanner": "hyprwayland-scanner", "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks", - "systems": "systems_2", + "systems": "systems", "xdph": "xdph" }, "locked": { @@ -510,21 +511,6 @@ } }, "systems_2": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "systems_3": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", diff --git a/flake.nix b/flake.nix index ea76409..98bdbdf 100644 --- a/flake.nix +++ b/flake.nix @@ -20,9 +20,10 @@ astal.url = "github:aylur/astal"; astal.inputs.nixpkgs.follows = "nixpkgs"; - # AGS - Aylur's GTK Shell for custom widgets/bar (v1) - ags.url = "github:Aylur/ags/v1"; + # AGS - Aylur's GTK Shell for custom widgets/bar (v3) + ags.url = "github:Aylur/ags"; ags.inputs.nixpkgs.follows = "nixpkgs"; + ags.inputs.astal.follows = "astal"; # Optional: Other useful inputs # nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; diff --git a/home/ags.nix b/home/ags.nix index f9be094..d02db70 100644 --- a/home/ags.nix +++ b/home/ags.nix @@ -1,255 +1,47 @@ { config, pkgs, inputs, ... }: { - # AGS - Aylur's GTK Shell configuration + # AGS v3 - Aylur's GTK Shell with Astal (colorshell configuration) imports = [ inputs.ags.homeManagerModules.default ]; programs.ags = { enable = true; - # null = use ~/.config/ags, or set to a path to symlink + # null = use ~/.config/ags (colorshell files are there) configDir = null; - # Add additional packages needed for AGS + # Add Astal packages needed for colorshell extraPackages = with pkgs; [ + inputs.astal.packages.${pkgs.system}.astal3 + inputs.astal.packages.${pkgs.system}.apps + inputs.astal.packages.${pkgs.system}.auth inputs.astal.packages.${pkgs.system}.battery inputs.astal.packages.${pkgs.system}.bluetooth + inputs.astal.packages.${pkgs.system}.hyprland + inputs.astal.packages.${pkgs.system}.mpris inputs.astal.packages.${pkgs.system}.network + inputs.astal.packages.${pkgs.system}.notifd + inputs.astal.packages.${pkgs.system}.powerprofiles + inputs.astal.packages.${pkgs.system}.tray + inputs.astal.packages.${pkgs.system}.wireplumber + + # Additional dependencies for colorshell + nodejs_22 + pnpm + glib + glib.dev # For glib-compile-resources + gtk4 + libadwaita + networkmanager + bluez + + # Icon theme for fixing "network-wired-symbolic" warnings + papirus-icon-theme ]; }; - # AGS configuration files will go in ~/.config/ags/ - home.file.".config/ags/config.js".text = '' - // AGS Configuration - import { Bar } from "./bar.js" - - App.config({ - windows: [ - Bar(0), // Monitor 0 (DP-2) - Bar(1), // Monitor 1 (DP-1) - ], - style: "./style.css", - }) - ''; - - home.file.".config/ags/bar.js".text = '' - const hyprland = await Service.import("hyprland") - const battery = await Service.import("battery") - const audio = await Service.import("audio") - const bluetooth = await Service.import("bluetooth") - const network = await Service.import("network") - const systemtray = await Service.import("systemtray") - - // Workspaces widget - const Workspaces = (monitor) => Widget.Box({ - class_name: "workspaces", - children: Array.from({ length: 10 }, (_, i) => i + 1).map(i => Widget.Button({ - attribute: i, - label: `''${i}`, - on_clicked: () => hyprland.messageAsync(`dispatch workspace ''${i}`), - setup: self => self.hook(hyprland, () => { - self.toggleClassName("active", hyprland.active.workspace.id === i) - // Show only relevant workspaces per monitor - if (monitor === 0) { - self.visible = [1, 3, 5, 7, 9].includes(i) - } else { - self.visible = [2, 4, 6, 8, 10].includes(i) - } - }), - })), - }) - - // Window title - const ClientTitle = () => Widget.Label({ - class_name: "client-title", - label: hyprland.active.client.bind("title"), - max_width_chars: 50, - truncate: "end", - }) - - // Clock - const Clock = () => Widget.Label({ - class_name: "clock", - setup: self => self.poll(1000, self => { - const date = new Date() - self.label = date.toLocaleTimeString("en-US", { - hour: "2-digit", - minute: "2-digit", - }) - }), - }) - - // Volume - const Volume = () => Widget.Button({ - class_name: "volume", - on_clicked: () => audio.speaker.is_muted = !audio.speaker.is_muted, - child: Widget.Icon().hook(audio.speaker, self => { - const vol = audio.speaker.volume * 100 - const icon = [ - [101, "overamplified"], - [67, "high"], - [34, "medium"], - [1, "low"], - [0, "muted"], - ].find(([threshold]) => threshold <= vol)?.[1] - - self.icon = `audio-volume-''${audio.speaker.is_muted ? "muted" : icon}-symbolic` - self.tooltip_text = `Volume ''${Math.floor(vol)}%` - }), - }) - - // Bluetooth - const Bluetooth = () => Widget.Button({ - class_name: "bluetooth", - on_clicked: () => Utils.execAsync("blueman-manager"), - child: Widget.Icon({ - icon: bluetooth.bind("enabled").as(on => - `bluetooth-''${on ? "active" : "disabled"}-symbolic` - ), - }), - setup: self => self.hook(bluetooth, self => { - const connected = bluetooth.connected_devices.length - self.tooltip_text = bluetooth.enabled - ? `Bluetooth: ''${connected} connected` - : "Bluetooth: Off" - }), - }) - - // Network - const Network = () => Widget.Icon().hook(network, self => { - const icon = network[network.primary || "wired"]?.icon_name - self.icon = icon || "" - self.visible = !!icon - }) - - // Battery - const Battery = () => Widget.Box({ - class_name: "battery", - visible: battery.bind("available"), - children: [ - Widget.Icon({ icon: battery.bind("icon_name") }), - Widget.Label({ - label: battery.bind("percent").as(p => `''${p}%`), - }), - ], - }) - - // System tray - const SysTray = () => Widget.Box({ - class_name: "systray", - children: systemtray.bind("items").as(items => items.map(item => Widget.Button({ - child: Widget.Icon({ icon: item.bind("icon") }), - on_primary_click: (_, event) => item.activate(event), - on_secondary_click: (_, event) => item.openMenu(event), - tooltip_markup: item.bind("tooltip_markup"), - }))), - }) - - // Main bar - export const Bar = (monitor = 0) => Widget.Window({ - name: `bar-''${monitor}`, - class_name: "bar", - monitor, - anchor: ["top", "left", "right"], - exclusivity: "exclusive", - child: Widget.CenterBox({ - start_widget: Widget.Box({ - spacing: 8, - children: [ - Workspaces(monitor), - ClientTitle(), - ], - }), - center_widget: Clock(), - end_widget: Widget.Box({ - hpack: "end", - spacing: 8, - children: [ - Volume(), - Bluetooth(), - Network(), - Battery(), - SysTray(), - ], - }), - }), - }) - ''; - - home.file.".config/ags/style.css".text = '' - * { - all: unset; - font-family: "JetBrainsMono Nerd Font", "FiraCode Nerd Font"; - font-size: 14px; - } - - .bar { - background-color: rgba(30, 30, 46, 0.8); - backdrop-filter: blur(10px); - color: #cdd6f4; - padding: 4px 10px; - border-radius: 0; - } - - .workspaces button { - padding: 4px 10px; - margin: 0 2px; - border-radius: 6px; - background-color: transparent; - color: #585b70; - transition: all 0.2s; - } - - .workspaces button.active { - background: linear-gradient(45deg, rgba(51, 204, 255, 0.8), rgba(0, 255, 153, 0.8)); - color: #1e1e2e; - font-weight: bold; - } - - .workspaces button:hover { - background-color: rgba(88, 91, 112, 0.4); - color: #cdd6f4; - } - - .client-title { - margin-left: 10px; - color: #cdd6f4; - } - - .clock { - font-weight: bold; - color: #89dceb; - font-size: 15px; - } - - .volume, .bluetooth { - padding: 4px 8px; - margin: 0 2px; - border-radius: 6px; - background-color: transparent; - transition: all 0.2s; - } - - .volume:hover, .bluetooth:hover { - background-color: rgba(88, 91, 112, 0.4); - } - - .battery { - padding: 4px 8px; - margin: 0 2px; - border-radius: 6px; - color: #a6e3a1; - } - - .systray button { - padding: 4px 8px; - margin: 0 2px; - border-radius: 6px; - transition: all 0.2s; - } - - .systray button:hover { - background-color: rgba(88, 91, 112, 0.4); - } - ''; + # Install icon theme system-wide to fix colorshell icon warnings + home.packages = with pkgs; [ + papirus-icon-theme + ]; } diff --git a/home/hyprland.nix b/home/hyprland.nix index a045baf..2b0a176 100644 --- a/home/hyprland.nix +++ b/home/hyprland.nix @@ -20,8 +20,8 @@ "mpvpaper -o 'no-audio loop' DP-2 ~/nix-flake/assets/wallpaper.mp4" "mpvpaper -o 'no-audio loop' DP-1 ~/nix-flake/assets/wallpaper.mp4" - "ags run" # Start AGS (bar and widgets) - "dunst" + "ags run --gtk 4" # Start AGS with colorshell (includes notification daemon) + # "dunst" # Disabled - colorshell handles notifications "nm-applet --indicator" # WiFi manager in system tray "vicinae server" # Start Vicinae server ]; @@ -34,6 +34,9 @@ "HYPRCURSOR_SIZE,24" "QT_QPA_PLATFORMTHEME,qt5ct" + # XDG directories for colorshell + "XDG_CACHE_HOME,$HOME/.cache" + # NVIDIA specific environment variables "LIBVA_DRIVER_NAME,nvidia" # Hardware acceleration "GBM_BACKEND,nvidia-drm" # Force GBM backend