diff --git a/flake.lock b/flake.lock
index 760afdc..23348a9 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,5 +1,73 @@
{
"nodes": {
+ "base16": {
+ "inputs": {
+ "fromYaml": "fromYaml"
+ },
+ "locked": {
+ "lastModified": 1755819240,
+ "narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=",
+ "owner": "SenchoPens",
+ "repo": "base16.nix",
+ "rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6",
+ "type": "github"
+ },
+ "original": {
+ "owner": "SenchoPens",
+ "repo": "base16.nix",
+ "type": "github"
+ }
+ },
+ "base16-fish": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1765809053,
+ "narHash": "sha256-XCUQLoLfBJ8saWms2HCIj4NEN+xNsWBlU1NrEPcQG4s=",
+ "owner": "tomyun",
+ "repo": "base16-fish",
+ "rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tomyun",
+ "repo": "base16-fish",
+ "rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
+ "type": "github"
+ }
+ },
+ "base16-helix": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1760703920,
+ "narHash": "sha256-m82fGUYns4uHd+ZTdoLX2vlHikzwzdu2s2rYM2bNwzw=",
+ "owner": "tinted-theming",
+ "repo": "base16-helix",
+ "rev": "d646af9b7d14bff08824538164af99d0c521b185",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "base16-helix",
+ "type": "github"
+ }
+ },
+ "base16-vim": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1732806396,
+ "narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=",
+ "owner": "tinted-theming",
+ "repo": "base16-vim",
+ "rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "base16-vim",
+ "rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
+ "type": "github"
+ }
+ },
"comfyui-nix": {
"inputs": {
"flake-parts": "flake-parts",
@@ -19,6 +87,22 @@
"type": "github"
}
},
+ "firefox-gnome-theme": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1764873433,
+ "narHash": "sha256-1XPewtGMi+9wN9Ispoluxunw/RwozuTRVuuQOmxzt+A=",
+ "owner": "rafaelmardojai",
+ "repo": "firefox-gnome-theme",
+ "rev": "f7ffd917ac0d253dbd6a3bf3da06888f57c69f92",
+ "type": "github"
+ },
+ "original": {
+ "owner": "rafaelmardojai",
+ "repo": "firefox-gnome-theme",
+ "type": "github"
+ }
+ },
"flake-compat": {
"locked": {
"lastModified": 1733328505,
@@ -90,6 +174,62 @@
"type": "github"
}
},
+ "flake-parts_4": {
+ "inputs": {
+ "nixpkgs-lib": [
+ "stylix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1767609335,
+ "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "250481aafeb741edfe23d29195671c19b36b6dca",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "fromYaml": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1731966426,
+ "narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=",
+ "owner": "SenchoPens",
+ "repo": "fromYaml",
+ "rev": "106af9e2f715e2d828df706c386a685698f3223b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "SenchoPens",
+ "repo": "fromYaml",
+ "type": "github"
+ }
+ },
+ "gnome-shell": {
+ "flake": false,
+ "locked": {
+ "host": "gitlab.gnome.org",
+ "lastModified": 1767737596,
+ "narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
+ "owner": "GNOME",
+ "repo": "gnome-shell",
+ "rev": "ef02db02bf0ff342734d525b5767814770d85b49",
+ "type": "gitlab"
+ },
+ "original": {
+ "host": "gitlab.gnome.org",
+ "owner": "GNOME",
+ "ref": "gnome-49",
+ "repo": "gnome-shell",
+ "type": "gitlab"
+ }
+ },
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -118,11 +258,11 @@
]
},
"locked": {
- "lastModified": 1772985285,
- "narHash": "sha256-wEEmvfqJcl9J0wyMgMrj1TixOgInBW/6tLPhWGoZE3s=",
+ "lastModified": 1773093840,
+ "narHash": "sha256-u/96NoAyN8BSRuM3ZimGf7vyYgXa3pLx4MYWjokuoH4=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "5be5d8245cbc7bc0c09fbb5f38f23f223c543f85",
+ "rev": "bb014746edb2a98d975abde4dd40fa240de4cf86",
"type": "github"
},
"original": {
@@ -281,6 +421,22 @@
"type": "github"
}
},
+ "nixpkgs_4": {
+ "locked": {
+ "lastModified": 1767767207,
+ "narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "5912c1772a44e31bf1c63c0390b90501e5026886",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
"nixvim": {
"inputs": {
"flake-parts": "flake-parts_3",
@@ -303,6 +459,31 @@
"type": "github"
}
},
+ "nur": {
+ "inputs": {
+ "flake-parts": [
+ "stylix",
+ "flake-parts"
+ ],
+ "nixpkgs": [
+ "stylix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1767810917,
+ "narHash": "sha256-ZKqhk772+v/bujjhla9VABwcvz+hB2IaRyeLT6CFnT0=",
+ "owner": "nix-community",
+ "repo": "NUR",
+ "rev": "dead29c804adc928d3a69dfe7f9f12d0eec1f1a4",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "NUR",
+ "type": "github"
+ }
+ },
"root": {
"inputs": {
"comfyui-nix": "comfyui-nix",
@@ -313,7 +494,40 @@
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable",
- "nixvim": "nixvim"
+ "nixvim": "nixvim",
+ "stylix": "stylix"
+ }
+ },
+ "stylix": {
+ "inputs": {
+ "base16": "base16",
+ "base16-fish": "base16-fish",
+ "base16-helix": "base16-helix",
+ "base16-vim": "base16-vim",
+ "firefox-gnome-theme": "firefox-gnome-theme",
+ "flake-parts": "flake-parts_4",
+ "gnome-shell": "gnome-shell",
+ "nixpkgs": "nixpkgs_4",
+ "nur": "nur",
+ "systems": "systems_2",
+ "tinted-foot": "tinted-foot",
+ "tinted-kitty": "tinted-kitty",
+ "tinted-schemes": "tinted-schemes",
+ "tinted-tmux": "tinted-tmux",
+ "tinted-zed": "tinted-zed"
+ },
+ "locked": {
+ "lastModified": 1772296853,
+ "narHash": "sha256-pAtzPsgHRKw/2Kv8HgAjSJg450FDldHPWsP3AKG/Xj0=",
+ "owner": "danth",
+ "repo": "stylix",
+ "rev": "c4b8e80a1020e09a1f081ad0f98ce804a6e85acf",
+ "type": "github"
+ },
+ "original": {
+ "owner": "danth",
+ "repo": "stylix",
+ "type": "github"
}
},
"systems": {
@@ -330,6 +544,102 @@
"repo": "default",
"type": "github"
}
+ },
+ "systems_2": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "tinted-foot": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1726913040,
+ "narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
+ "owner": "tinted-theming",
+ "repo": "tinted-foot",
+ "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "tinted-foot",
+ "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
+ "type": "github"
+ }
+ },
+ "tinted-kitty": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1735730497,
+ "narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=",
+ "owner": "tinted-theming",
+ "repo": "tinted-kitty",
+ "rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "tinted-kitty",
+ "type": "github"
+ }
+ },
+ "tinted-schemes": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1767710407,
+ "narHash": "sha256-+W1EB79Jl0/gm4JqmO0Nuc5C7hRdp4vfsV/VdzI+des=",
+ "owner": "tinted-theming",
+ "repo": "schemes",
+ "rev": "2800e2b8ac90f678d7e4acebe4fa253f602e05b2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "schemes",
+ "type": "github"
+ }
+ },
+ "tinted-tmux": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1767489635,
+ "narHash": "sha256-e6nnFnWXKBCJjCv4QG4bbcouJ6y3yeT70V9MofL32lU=",
+ "owner": "tinted-theming",
+ "repo": "tinted-tmux",
+ "rev": "3c32729ccae99be44fe8a125d20be06f8d7d8184",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "tinted-tmux",
+ "type": "github"
+ }
+ },
+ "tinted-zed": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1767488740,
+ "narHash": "sha256-wVOj0qyil8m+ouSsVZcNjl5ZR+1GdOOAooAatQXHbuU=",
+ "owner": "tinted-theming",
+ "repo": "base16-zed",
+ "rev": "11abb0b282ad3786a2aae088d3a01c60916f2e40",
+ "type": "github"
+ },
+ "original": {
+ "owner": "tinted-theming",
+ "repo": "base16-zed",
+ "type": "github"
+ }
}
},
"root": "root",
diff --git a/flake.nix b/flake.nix
index 36a5162..21ed33f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -29,6 +29,8 @@
url = "github:NixOS/nixos-hardware/master";
#inputs.nixpkgs.follows = "nixpkgs";
};
+
+ stylix.url = "github:danth/stylix";
};
outputs =
@@ -42,6 +44,7 @@
nixpkgs,
nixpkgs-unstable,
nixvim,
+ stylix,
...
}@inputs:
let
@@ -134,6 +137,7 @@
modules = [
./hosts/eva-03/configuration.nix
inputs.home-manager.nixosModules.default
+ comfyui-nix.nixosModules.default
];
};
diff --git a/home-manager/programs/hypr/hyprland.nix b/home-manager/programs/hypr/hyprland.nix
index d5d36c2..a4b6102 100644
--- a/home-manager/programs/hypr/hyprland.nix
+++ b/home-manager/programs/hypr/hyprland.nix
@@ -1,4 +1,4 @@
-{ config, configPath, hostname, ... }:
+{ config, configPath, hostname, lib, ... }:
{
wayland.windowManager.hyprland = {
enable = true;
@@ -43,8 +43,8 @@
gaps_in = 2.5;
gaps_out = 5;
border_size = 2;
- "col.active_border" = "rgb(cdd6f4)";
- "col.inactive_border" = "rgba(595959aa)";
+ "col.active_border" = lib.mkForce "rgb(cdd6f4)";
+ "col.inactive_border" = lib.mkForce "rgba(595959aa)";
layout = "dwindle";
};
diff --git a/home-manager/programs/hypr/hyprlock.nix b/home-manager/programs/hypr/hyprlock.nix
index f1056a3..5ce3232 100644
--- a/home-manager/programs/hypr/hyprlock.nix
+++ b/home-manager/programs/hypr/hyprlock.nix
@@ -1,4 +1,4 @@
-{ configPath, ... }:
+{ configPath, lib, ... }:
{
programs.hyprlock = {
enable = true;
@@ -10,7 +10,7 @@
no_fade_in = false;
};
- background = [
+ background = lib.mkForce [
{
path = "${configPath}/assets/pfp/neonNerv.png";
blur_passes = 3;
@@ -18,7 +18,7 @@
}
];
- image = [
+ image = lib.mkForce [
{
path = "${configPath}/assets/pfp/eva-03.png";
size = 150;
@@ -31,7 +31,7 @@
}
];
- label = [
+ label = lib.mkForce [
# Clock
{
monitor = "";
@@ -67,7 +67,7 @@
}
];
- input-field = [
+ input-field = lib.mkForce [
{
size = "200, 50";
position = "0, -80";
diff --git a/home-manager/programs/hypr/theme.nix b/home-manager/programs/hypr/theme.nix
index 1fb8a4f..5bb6bd9 100644
--- a/home-manager/programs/hypr/theme.nix
+++ b/home-manager/programs/hypr/theme.nix
@@ -16,17 +16,17 @@
gtk = {
enable = true;
theme = {
- name = "Adwaita-dark";
- package = pkgs.gnome-themes-extra;
+ name = lib.mkForce "Adwaita-dark";
+ package = lib.mkForce pkgs.gnome-themes-extra;
};
iconTheme = {
- name = "Papirus-Dark";
- package = pkgs.papirus-icon-theme;
+ name = lib.mkForce "Papirus-Dark";
+ package = lib.mkForce pkgs.papirus-icon-theme;
};
cursorTheme = {
- name = "Bibata-Modern-Classic";
- package = pkgs.bibata-cursors;
- size = 24;
+ name = lib.mkForce "Bibata-Modern-Classic";
+ package = lib.mkForce pkgs.bibata-cursors;
+ size = lib.mkForce 24;
};
gtk3.extraConfig = {
gtk-application-prefer-dark-theme = true;
@@ -47,9 +47,9 @@
dconf.settings."org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
gtk-theme = "Adwaita-dark";
- icon-theme = "Papirus-Dark";
- cursor-theme = "Bibata-Modern-Classic";
- cursor-size = 24;
+ icon-theme = lib.mkForce "Papirus-Dark";
+ cursor-theme = lib.mkForce "Bibata-Modern-Classic";
+ cursor-size = lib.mkForce 24;
};
# Cursor for Wayland/X sessions
diff --git a/home-manager/programs/hypr/waybar/Jerry-waybar.nix b/home-manager/programs/hypr/waybar/Jerry-waybar.nix
new file mode 100644
index 0000000..32bbdff
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/Jerry-waybar.nix
@@ -0,0 +1,376 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}: let
+ terminal = "kitty";
+ base00 = "0F1419";
+ base01 = "131721";
+ base03 = "3E4B59";
+ base05 = "E6E1CF";
+ base06 = "E6E1CF";
+ base07 = "F3F4F5";
+ base08 = "F07178";
+ base09 = "FF8F40";
+ base0A = "FFB454";
+ base0B = "B8CC52";
+ base0C = "95E6CB";
+ base0D = "59C2FF";
+ base0E = "D2A6FF";
+ base0F = "E6B673";
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in
+ with lib; {
+ home.file = builtins.listToAttrs (map
+ (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts);
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+
+ modules-center = ["network" "pulseaudio" "cpu" "hyprland/workspaces" "memory" "disk" "clock" "custom/weather"];
+ modules-left = ["custom/startmenu" "hyprland/window"]; # Eternal: [ "hyprland/workspaces" "cpu" "memory" "network" ]
+ modules-right = ["tray" "idle_inhibitor" "custom/notification" "battery" "custom/power"]; # Eternal: [ "idle_inhibitor" "pulseaudio" "clock" "custom/notification" "tray" ]
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format = '' {:%H:%M}'';
+ /*
+ ''{: %I:%M %p}'';
+ */
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 60;
+ separate-outputs = false;
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ on-click = "${terminal} -e btop";
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ on-click = "${terminal} -e btop";
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ on-click = "${terminal} -e sh -c df -h ; read";
+ };
+ "network" = {
+ format-icons = ["" "" "" "" ""];
+ format-ethernet = " {bandwidthDownBits}";
+ format-wifi = " {bandwidthDownBits}";
+ format-disconnected = "";
+ tooltip = false;
+ on-click = "${terminal} -e btop";
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ on-click = "pavucontrol";
+ };
+ "custom/power" = {
+ tooltip = true;
+ "tooltip-format" = "Left Click: Power Menu (qs-wlogout)\nRight Click: Rofi Power Menu";
+ format = " ";
+ on-click = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ };
+ "custom/startmenu" = {
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ format = "";
+ # on-click = "rofi -show drun";
+ on-click = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = " ";
+ deactivated = " ";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "pavucontrol";
+ escape = true;
+ };
+ "custom/weather" = {
+ return-type = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = ["" "" "" "" "" "" "" "" "" ""];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-size: 16px;
+ font-family: JetBrainsMono Nerd Font, Font Awesome, sans-serif;
+ font-weight: bold;
+ }
+ window#waybar {
+ /*
+
+ background-color: rgba(26,27,38,0);
+ border-bottom: 1px solid rgba(26,27,38,0);
+ border-radius: 0px;
+ color: #${base0F};
+ */
+
+ background-color: rgba(26,27,38,0);
+ border-bottom: 1px solid rgba(26,27,38,0);
+ border-radius: 0px;
+ color: #${base0F};
+ }
+ #workspaces {
+ /*
+ Eternal
+ background: linear-gradient(180deg, #${base00}, #${base01});
+ margin: 5px 5px 5px 0px;
+ padding: 0px 10px;
+ border-radius: 0px 15px 50px 0px;
+ border: 0px;
+ font-style: normal;
+ color: #${base00};
+ */
+ background: linear-gradient(45deg, #${base01}, #${base01});
+ margin: 5px;
+ padding: 0px 1px;
+ border-radius: 15px;
+ border: 0px;
+ font-style: normal;
+ color: #${base00};
+ }
+ #workspaces button {
+ padding: 0px 5px;
+ margin: 4px 3px;
+ border-radius: 15px;
+ border: 0px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 0.5;
+ transition: all 0.3s ease-in-out;
+ }
+ #workspaces button.active {
+ padding: 0px 5px;
+ margin: 4px 3px;
+ border-radius: 15px;
+ border: 0px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 1.0;
+ min-width: 40px;
+ transition: all 0.3s ease-in-out;
+ }
+ #workspaces button:hover {
+ border-radius: 15px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 0.8;
+ }
+ tooltip {
+ background: #${base00};
+ border: 1px solid #${base0E};
+ border-radius: 10px;
+ }
+ tooltip label {
+ color: #${base07};
+ }
+ #window {
+ /*
+ Eternal
+ color: #${base05};
+ background: #${base00};
+ border-radius: 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ margin: 5px;
+ padding: 2px 20px;
+ color: #${base05};
+ background: #${base01};
+ border-radius: 50px 15px 50px 15px;
+ }
+ #memory {
+ color: #${base0F};
+ /*
+ Eternal
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ background: #${base01};
+ margin: 5px;
+ padding: 2px 20px;
+ border-radius: 15px 50px 15px 50px;
+ }
+ #clock {
+ color: #${base0B};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #idle_inhibitor {
+ color: #${base0A};
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #cpu {
+ color: #${base07};
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #disk {
+ color: #${base03};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #battery {
+ color: #${base08};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #network {
+ color: #${base09};
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #tray {
+ color: #${base05};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #pulseaudio {
+ color: #${base0D};
+ /*
+ Eternal
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ background: #${base01};
+ margin: 4px;
+ padding: 2px 20px;
+ border-radius: 50px 15px 50px 15px;
+ }
+ #custom-notification {
+ color: #${base0C};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #custom-startmenu {
+ color: #${base03};
+ background: #${base00};
+ border-radius: 0px 15px 50px 0px;
+ margin: 5px 5px 5px 0px;
+ padding: 2px 20px;
+ }
+ #idle_inhibitor {
+ color: #${base09};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #custom-power {
+ color: #${base08}; /* Red color for power menu */
+ background: #${base00};
+ border-radius: 15px 0px 0px 50px;
+ margin: 5px 0px 5px 5px;
+ padding: 2px 20px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/scripts/Weather.py b/home-manager/programs/hypr/waybar/scripts/Weather.py
new file mode 100644
index 0000000..1783fed
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/Weather.py
@@ -0,0 +1,719 @@
+#!/usr/bin/env python3
+# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ #
+# Rewritten to use Open-Meteo APIs (worldwide, no API key) for robust weather data.
+# Outputs Waybar-compatible JSON and a simple text cache.
+
+import json
+import os
+import sys
+import time
+import html
+import subprocess
+from typing import Any, Dict, List, Optional, Tuple
+from datetime import datetime
+
+import requests
+
+# =============== Configuration ===============
+# You can configure behavior via environment variables OR the constants below.
+# Examples (zsh):
+# # One-off run
+# # WEATHER_UNITS can be "metric" or "imperial"
+# WEATHER_UNITS=imperial WEATHER_PLACE="Concord, NH" python3 ~/.config/waybar/scripts/Weather.py
+#
+# # Persist in current shell session
+# export WEATHER_UNITS=imperial
+# export WEATHER_LAT=43.2229
+# export WEATHER_LON=-71.332
+# export WEATHER_PLACE="Concord, NH"
+# export WEATHER_TOOLTIP_MARKUP=1 # 1 to enable Pango markup, 0 to disable
+# export WEATHER_LOC_ICON="📍" # or "*" for ASCII-only
+#
+CACHE_DIR = os.path.expanduser("~/.cache")
+API_CACHE_PATH = os.path.join(CACHE_DIR, "open_meteo_cache.json")
+SIMPLE_TEXT_CACHE_PATH = os.path.join(CACHE_DIR, ".weather_cache")
+CACHE_TTL_SECONDS = int(os.getenv("WEATHER_CACHE_TTL", "600")) # default 10 minutes
+
+# Units: metric or imperial (default imperial for ddubsos branch)
+UNITS = os.getenv("WEATHER_UNITS", "imperial").strip().lower() # metric|imperial
+
+# Optional manual coordinates
+ENV_LAT = os.getenv("WEATHER_LAT")
+ENV_LON = os.getenv("WEATHER_LON")
+# Optional manual place override for tooltip
+ENV_PLACE = os.getenv("WEATHER_PLACE")
+# Manual place name set inside this file. If set (non-empty), this takes top priority.
+# Example: MANUAL_PLACE = "Concord, NH, US"
+MANUAL_PLACE: Optional[str] = None
+
+# Location icon in tooltip (default to a standard emoji to avoid missing glyphs)
+LOC_ICON = os.getenv("WEATHER_LOC_ICON", "📍")
+# Enable/disable Pango markup in tooltip (1/0, true/false)
+TOOLTIP_MARKUP = os.getenv("WEATHER_TOOLTIP_MARKUP", "1").lower() not in ("0", "false", "no")
+# Optional debug logging to stderr (set WEATHER_DEBUG=1 to enable)
+DEBUG = os.getenv("WEATHER_DEBUG", "0").lower() not in ("0", "false", "no")
+
+# HTTP settings
+UA = (
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
+ "(KHTML, like Gecko) Chrome/128.0 Safari/537.36"
+)
+TIMEOUT = 8
+
+SESSION = requests.Session()
+SESSION.headers.update({"User-Agent": UA})
+
+# =============== Icon and status mapping ===============
+# Icon style: 'emoji' (colorful), 'nerd' (mono glyphs), or 'gnome' (symbolic names, useful for other bars)
+ICON_STYLE = os.getenv("WEATHER_ICON_STYLE", "emoji").strip().lower() # emoji|nerd|gnome
+
+# Nerd Font weather glyphs (mono)
+WEATHER_ICONS_NERD = {
+ "sunnyDay": "",
+ "clearNight": "",
+ "cloudyFoggyDay": "",
+ "cloudyFoggyNight": "",
+ "rainyDay": "",
+ "rainyNight": "",
+ "snowyIcyDay": "",
+ "snowyIcyNight": "",
+ "severe": "",
+ "default": "",
+}
+
+# Colored emoji set (renders with system emoji font, gives the "3D" look)
+WEATHER_ICONS_EMOJI = {
+ "sunnyDay": "☀️",
+ "clearNight": "🌙",
+ "cloudyFoggyDay": "⛅️",
+ "cloudyFoggyNight": "☁️🌙",
+ "rainyDay": "🌦️",
+ "rainyNight": "🌧️",
+ "snowyIcyDay": "🌨️",
+ "snowyIcyNight": "❄️🌙",
+ "severe": "⛈️",
+ "default": "🌥️",
+}
+
+# GNOME symbolic icon names (not used directly by Waybar, here for parity)
+WEATHER_ICONS_GNOME = {
+ "sunnyDay": "Sun-symbolic",
+ "clearNight": "Moon-symbolic",
+ "cloudyFoggyDay": "CloudSun-symbolic",
+ "cloudyFoggyNight": "CloudyMoon-symbolic",
+ "rainyDay": "CloudRain-symbolic",
+ "rainyNight": "CloudRain-symbolic",
+ "snowyIcyDay": "CloudSnowfall-symbolic",
+ "snowyIcyNight": "CloudSnowfall-symbolic",
+ "severe": "CloudBolt-symbolic",
+ "default": "Cloud-symbolic",
+}
+
+# Optional: allow disabling automatic fallback via env
+DISABLE_EMOJI_FALLBACK = os.getenv("WEATHER_DISABLE_EMOJI_FALLBACK", "0").lower() in ("1", "true", "yes")
+
+# Basic detection of color emoji font availability via fontconfig (fc-list)
+EMOJI_FONT_CANDIDATES = [
+ "Noto Color Emoji",
+ "Noto Emoji",
+ "Apple Color Emoji",
+ "Segoe UI Emoji",
+ "Twitter Color Emoji",
+ "Twemoji",
+ "JoyPixels",
+]
+
+def has_color_emoji_font() -> bool:
+ try:
+ # Quick check: list installed fonts; search for any candidate name
+ proc = subprocess.run(
+ ["fc-list"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL,
+ text=True,
+ timeout=1.5,
+ check=False,
+ )
+ out = proc.stdout or ""
+ out_lower = out.lower()
+ for name in EMOJI_FONT_CANDIDATES:
+ if name.lower() in out_lower:
+ return True
+ except Exception:
+ # If detection fails, don't block emoji; assume not available to be safe on minimal setups
+ return False
+ return False
+
+# Determine the active icon style with fallback from emoji -> nerd when no color emoji fonts are present
+if ICON_STYLE == "emoji" and not DISABLE_EMOJI_FALLBACK and not has_color_emoji_font():
+ ACTIVE_ICON_STYLE = "nerd"
+else:
+ ACTIVE_ICON_STYLE = ICON_STYLE
+
+# Choose active set
+WEATHER_ICONS = (
+ WEATHER_ICONS_EMOJI if ACTIVE_ICON_STYLE == "emoji" else WEATHER_ICONS_NERD if ACTIVE_ICON_STYLE == "nerd" else WEATHER_ICONS_GNOME
+)
+
+WMO_STATUS = {
+ 0: "Clear sky",
+ 1: "Mainly clear",
+ 2: "Partly cloudy",
+ 3: "Overcast",
+ 45: "Fog",
+ 48: "Depositing rime fog",
+ 51: "Light drizzle",
+ 53: "Moderate drizzle",
+ 55: "Dense drizzle",
+ 56: "Freezing drizzle",
+ 57: "Freezing drizzle",
+ 61: "Light rain",
+ 63: "Moderate rain",
+ 65: "Heavy rain",
+ 66: "Freezing rain",
+ 67: "Freezing rain",
+ 71: "Slight snow",
+ 73: "Moderate snow",
+ 75: "Heavy snow",
+ 77: "Snow grains",
+ 80: "Rain showers",
+ 81: "Rain showers",
+ 82: "Violent rain showers",
+ 85: "Snow showers",
+ 86: "Heavy snow showers",
+ 95: "Thunderstorm",
+ 96: "Thunderstorm w/ hail",
+ 99: "Thunderstorm w/ hail",
+}
+
+
+def wmo_to_icon(code: int, is_day: int) -> str:
+ day = bool(is_day)
+ if code == 0:
+ return WEATHER_ICONS["sunnyDay" if day else "clearNight"]
+ if code in (1, 2, 3, 45, 48):
+ return WEATHER_ICONS["cloudyFoggyDay" if day else "cloudyFoggyNight"]
+ if code in (51, 53, 55, 61, 63, 65, 80, 81, 82):
+ return WEATHER_ICONS["rainyDay" if day else "rainyNight"]
+ if code in (56, 57, 66, 67, 71, 73, 75, 77, 85, 86):
+ return WEATHER_ICONS["snowyIcyDay" if day else "snowyIcyNight"]
+ if code in (95, 96, 99):
+ return WEATHER_ICONS["severe"]
+ return WEATHER_ICONS["default"]
+
+
+def wmo_to_status(code: int) -> str:
+ return WMO_STATUS.get(code, "Unknown")
+
+
+# =============== Utilities ===============
+
+def esc(s: Optional[str]) -> str:
+ return html.escape(s, quote=False) if s else ""
+
+def log_debug(msg: str) -> None:
+ if DEBUG:
+ print(msg, file=sys.stderr)
+
+
+def temp_color(temp_val: Optional[float]) -> str:
+ """Choose a color for the temperature number based on value and unit set."""
+ if not isinstance(temp_val, (int, float)):
+ return "#cdd6f4" # default text
+ # Work in Fahrenheit for thresholds if imperial, else Celsius
+ t = float(temp_val)
+ if UNITS == "metric":
+ if t <= -5:
+ return "#89dceb" # sky
+ if t <= 5:
+ return "#74c7ec" # sapphire
+ if t <= 15:
+ return "#a6e3a1" # green
+ if t <= 25:
+ return "#f9e2af" # yellow
+ if t <= 32:
+ return "#fab387" # peach
+ return "#f38ba8" # red
+ else:
+ if t <= 25:
+ return "#89dceb"
+ if t <= 41:
+ return "#74c7ec"
+ if t <= 60:
+ return "#a6e3a1"
+ if t <= 77:
+ return "#f9e2af"
+ if t <= 90:
+ return "#fab387"
+ return "#f38ba8"
+
+def ensure_cache_dir() -> None:
+ try:
+ os.makedirs(CACHE_DIR, exist_ok=True)
+ except Exception as e:
+ print(f"Error creating cache dir: {e}", file=sys.stderr)
+
+
+def read_api_cache() -> Optional[Dict[str, Any]]:
+ try:
+ if not os.path.exists(API_CACHE_PATH):
+ return None
+ with open(API_CACHE_PATH, "r", encoding="utf-8") as f:
+ data = json.load(f)
+ if (time.time() - data.get("timestamp", 0)) <= CACHE_TTL_SECONDS:
+ return data
+ return None
+ except Exception as e:
+ print(f"Error reading cache: {e}", file=sys.stderr)
+ return None
+
+
+def write_api_cache(payload: Dict[str, Any]) -> None:
+ try:
+ ensure_cache_dir()
+ payload["timestamp"] = time.time()
+ with open(API_CACHE_PATH, "w", encoding="utf-8") as f:
+ json.dump(payload, f)
+ except Exception as e:
+ print(f"Error writing API cache: {e}", file=sys.stderr)
+
+
+def write_simple_text_cache(text: str) -> None:
+ try:
+ ensure_cache_dir()
+ with open(SIMPLE_TEXT_CACHE_PATH, "w", encoding="utf-8") as f:
+ f.write(text)
+ except Exception as e:
+ print(f"Error writing simple cache: {e}", file=sys.stderr)
+
+
+def get_coords() -> Tuple[float, float]:
+ # 1) Explicit env
+ if ENV_LAT and ENV_LON:
+ try:
+ return float(ENV_LAT), float(ENV_LON)
+ except ValueError:
+ print("Invalid WEATHER_LAT/WEATHER_LON; falling back to IP geolocation", file=sys.stderr)
+
+ # 2) Try cached coordinates from last successful forecast
+ try:
+ cached = read_api_cache()
+ if cached and isinstance(cached, dict):
+ fc = cached.get("forecast") or {}
+ lat = fc.get("latitude")
+ lon = fc.get("longitude")
+ if isinstance(lat, (int, float)) and isinstance(lon, (int, float)):
+ return float(lat), float(lon)
+ except Exception as e:
+ print(f"Reading cached coords failed: {e}", file=sys.stderr)
+
+ # 3) IP-based geolocation with multiple providers (prefer ipwho.is, ipapi.co; ipinfo.io as fallback)
+ # ipwho.is
+ try:
+ resp = SESSION.get("https://ipwho.is/", timeout=TIMEOUT)
+ resp.raise_for_status()
+ data = resp.json()
+ if data.get("success"):
+ lat = data.get("latitude")
+ lon = data.get("longitude")
+ if isinstance(lat, (int, float)) and isinstance(lon, (int, float)):
+ return float(lat), float(lon)
+ except Exception as e:
+ print(f"ipwho.is failed: {e}", file=sys.stderr)
+
+ # ipapi.co
+ try:
+ resp = SESSION.get("https://ipapi.co/json", timeout=TIMEOUT)
+ resp.raise_for_status()
+ data = resp.json()
+ lat = data.get("latitude")
+ lon = data.get("longitude")
+ if isinstance(lat, (int, float)) and isinstance(lon, (int, float)):
+ return float(lat), float(lon)
+ except Exception as e:
+ print(f"ipapi.co failed: {e}", file=sys.stderr)
+
+ # ipinfo.io (fallback)
+ try:
+ resp = SESSION.get("https://ipinfo.io/json", timeout=TIMEOUT)
+ resp.raise_for_status()
+ data = resp.json()
+ loc = data.get("loc")
+ if loc and "," in loc:
+ lat_s, lon_s = loc.split(",", 1)
+ return float(lat_s), float(lon_s)
+ except Exception as e:
+ print(f"ipinfo.io failed: {e}", file=sys.stderr)
+
+ # 4) Last resort
+ print("IP geolocation failed: no providers succeeded", file=sys.stderr)
+ return 0.0, 0.0
+
+
+def units_params(units: str) -> Dict[str, str]:
+ if units == "imperial":
+ return {
+ "temperature_unit": "fahrenheit",
+ "wind_speed_unit": "mph",
+ "precipitation_unit": "inch",
+ }
+ # default metric
+ return {
+ "temperature_unit": "celsius",
+ "wind_speed_unit": "kmh",
+ "precipitation_unit": "mm",
+ }
+
+
+def format_visibility(meters: Optional[float]) -> str:
+ if meters is None:
+ return ""
+ try:
+ if UNITS == "imperial":
+ miles = meters / 1609.344
+ return f"{miles:.1f} mi"
+ else:
+ km = meters / 1000.0
+ return f"{km:.1f} km"
+ except Exception:
+ return ""
+
+
+# =============== API Fetching ===============
+
+def fetch_open_meteo(lat: float, lon: float) -> Dict[str, Any]:
+ base = "https://api.open-meteo.com/v1/forecast"
+ params = {
+ "latitude": lat,
+ "longitude": lon,
+ "current": "temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_direction_10m,weather_code,visibility,precipitation,pressure_msl,is_day",
+ "hourly": "precipitation_probability,weather_code",
+ "daily": "temperature_2m_max,temperature_2m_min",
+ "timezone": "auto",
+ }
+ params.update(units_params(UNITS))
+ resp = SESSION.get(base, params=params, timeout=TIMEOUT)
+ resp.raise_for_status()
+ return resp.json()
+
+
+def fetch_aqi(lat: float, lon: float) -> Optional[Dict[str, Any]]:
+ try:
+ base = "https://air-quality-api.open-meteo.com/v1/air-quality"
+ params = {
+ "latitude": lat,
+ "longitude": lon,
+ "current": "european_aqi",
+ "timezone": "auto",
+ }
+ resp = SESSION.get(base, params=params, timeout=TIMEOUT)
+ resp.raise_for_status()
+ return resp.json()
+ except Exception as e:
+ print(f"AQI fetch failed: {e}", file=sys.stderr)
+ return None
+
+
+def fetch_place(lat: float, lon: float) -> Optional[str]:
+ """Reverse geocode lat/lon to an approximate place. Tries Nominatim first, then Open-Meteo."""
+ lang = os.getenv("WEATHER_LANG", "en")
+
+ # 1) Nominatim (OpenStreetMap)
+ try:
+ base = "https://nominatim.openstreetmap.org/reverse"
+ params = {
+ "lat": lat,
+ "lon": lon,
+ "format": "jsonv2",
+ "accept-language": lang,
+ }
+ headers = {"User-Agent": UA + " Weather.py/1.0"}
+ resp = SESSION.get(base, params=params, headers=headers, timeout=TIMEOUT)
+ resp.raise_for_status()
+ data = resp.json()
+ address = data.get("address", {})
+ name = data.get("name") or address.get("city") or address.get("town") or address.get("village") or address.get("hamlet")
+ admin1 = address.get("state")
+ country = address.get("country")
+ parts = [part for part in [name, admin1, country] if part]
+ if parts:
+ return ", ".join(parts)
+ except Exception as e:
+ log_debug(f"Reverse geocoding (Nominatim) failed: {e}")
+
+ # 2) Open-Meteo reverse (fallback)
+ try:
+ base = "https://geocoding-api.open-meteo.com/v1/reverse"
+ params = {
+ "latitude": lat,
+ "longitude": lon,
+ "language": lang,
+ "format": "json",
+ }
+ resp = SESSION.get(base, params=params, timeout=TIMEOUT)
+ resp.raise_for_status()
+ data = resp.json()
+ results = data.get("results") or []
+ if results:
+ p = results[0]
+ name = p.get("name")
+ admin1 = p.get("admin1")
+ country = p.get("country")
+ parts = [part for part in [name, admin1, country] if part]
+ if parts:
+ return ", ".join(parts)
+ except Exception as e:
+ log_debug(f"Reverse geocoding (Open-Meteo) failed: {e}")
+
+ return None
+
+
+# =============== Build Output ===============
+
+def safe_get(dct: Dict[str, Any], *keys, default=None):
+ cur: Any = dct
+ for k in keys:
+ if isinstance(cur, dict):
+ if k not in cur:
+ return default
+ cur = cur[k]
+ elif isinstance(cur, list):
+ try:
+ cur = cur[k] # type: ignore[index]
+ except Exception:
+ return default
+ else:
+ return default
+ return cur
+
+
+def build_hourly_precip(forecast: Dict[str, Any]) -> str:
+ try:
+ times: List[str] = safe_get(forecast, "hourly", "time", default=[]) or []
+ probs: List[Optional[float]] = safe_get(
+ forecast, "hourly", "precipitation_probability", default=[]
+ ) or []
+ cur_time: Optional[str] = safe_get(forecast, "current", "time")
+ idx = times.index(cur_time) if cur_time in times else 0
+ window = probs[idx : idx + 6]
+ if not window:
+ return ""
+ parts = [f"{int(p)}%" if p is not None else "-" for p in window]
+ return " (next 6h) " + " ".join(parts)
+ except Exception:
+ return ""
+
+
+def build_output(lat: float, lon: float, forecast: Dict[str, Any], aqi: Optional[Dict[str, Any]], place: Optional[str] = None) -> Tuple[Dict[str, Any], str]:
+ cur = forecast.get("current", {})
+ cur_units = forecast.get("current_units", {})
+ daily = forecast.get("daily", {})
+ daily_units = forecast.get("daily_units", {})
+
+ temp_val = cur.get("temperature_2m")
+ temp_unit = cur_units.get("temperature_2m", "")
+ temp_str = f"{int(round(temp_val))}{temp_unit}" if isinstance(temp_val, (int, float)) else "N/A"
+ temp_col = temp_color(temp_val)
+
+ feels_val = cur.get("apparent_temperature")
+ feels_unit = cur_units.get("apparent_temperature", "")
+ feels_str = f"Feels like {int(round(feels_val))}{feels_unit}" if isinstance(feels_val, (int, float)) else ""
+
+ is_day = int(cur.get("is_day", 1) or 1)
+ code = int(cur.get("weather_code", -1) or -1)
+
+ unavailable = False
+
+ # Fallbacks: if current weather_code is missing/invalid
+ if code == -1:
+ try:
+ times: List[str] = safe_get(forecast, "hourly", "time", default=[]) or []
+ codes: List[Optional[int]] = safe_get(forecast, "hourly", "weather_code", default=[]) or []
+ cur_time: Optional[str] = safe_get(forecast, "current", "time")
+
+ idx = 0
+ if cur_time and times:
+ # Find nearest index by absolute time difference
+ try:
+ ct = datetime.fromisoformat(cur_time)
+ diffs = []
+ for t in times:
+ try:
+ diffs.append(abs((datetime.fromisoformat(t) - ct).total_seconds()))
+ except Exception:
+ diffs.append(float("inf"))
+ idx = min(range(len(diffs)), key=lambda i: diffs[i]) if diffs else 0
+ except Exception:
+ # If parsing fails, try exact match fallback
+ idx = times.index(cur_time) if cur_time in times else 0
+
+ # Prefer nearest code if valid, else first non-null code in window
+ hcode = None
+ if isinstance(codes, list) and codes:
+ if idx < len(codes) and isinstance(codes[idx], (int, float)):
+ hcode = int(codes[idx])
+ else:
+ for c in codes:
+ if isinstance(c, (int, float)):
+ hcode = int(c)
+ break
+ if isinstance(hcode, int):
+ code = hcode
+ log_debug(f"Fallback hourly weather_code used: code={code} idx={idx} cur_time={cur_time}")
+ except Exception as e:
+ log_debug(f"Hourly code fallback failed: {e}")
+
+ # Final fallback: no valid code at all
+ if not isinstance(code, int) or code < 0:
+ unavailable = True
+ log_debug("Weather code invalid; setting status to 'Condition Unavailable'")
+
+ # Compute icon/status (override if unavailable)
+ if unavailable:
+ icon = WEATHER_ICONS["default"]
+ status = "Condition Unavailable"
+ code_for_class = "unavailable"
+ else:
+ icon = wmo_to_icon(code, is_day)
+ status = wmo_to_status(code)
+ code_for_class = f"wmo-{code} {'day' if is_day else 'night'}"
+
+ # min/max today (index 0)
+ tmin_val = safe_get(daily, "temperature_2m_min", 0)
+ tmax_val = safe_get(daily, "temperature_2m_max", 0)
+ dtemp_unit = daily_units.get("temperature_2m_min", temp_unit)
+ tmin_str = f"{int(round(tmin_val))}{dtemp_unit}" if isinstance(tmin_val, (int, float)) else ""
+ tmax_str = f"{int(round(tmax_val))}{dtemp_unit}" if isinstance(tmax_val, (int, float)) else ""
+ min_max = f" {tmin_str}\t\t {tmax_str}" if tmin_str and tmax_str else ""
+
+ wind_val = cur.get("wind_speed_10m")
+ wind_unit = cur_units.get("wind_speed_10m", "")
+ wind_text = f" {int(round(wind_val))}{wind_unit}" if isinstance(wind_val, (int, float)) else ""
+
+ hum_val = cur.get("relative_humidity_2m")
+ humidity_text = f" {int(hum_val)}%" if isinstance(hum_val, (int, float)) else ""
+
+ vis_val = cur.get("visibility")
+ visibility_text = f" {format_visibility(vis_val)}" if isinstance(vis_val, (int, float)) else ""
+
+ aqi_val = safe_get(aqi or {}, "current", "european_aqi")
+ aqi_text = f"AQI {int(aqi_val)}" if isinstance(aqi_val, (int, float)) else "AQI N/A"
+
+ hourly_precip = build_hourly_precip(forecast)
+ prediction = f"\n\n{hourly_precip}" if hourly_precip else ""
+
+ # Build place string (priority: MANUAL_PLACE > ENV_PLACE > reverse geocode > lat,lon)
+ place_str = (MANUAL_PLACE or ENV_PLACE or place or f"{lat:.3f}, {lon:.3f}")
+ location_text = f"{LOC_ICON} {place_str}"
+
+ # Build tooltip (markup or plain)
+ if TOOLTIP_MARKUP:
+ # Escape dynamic text to avoid breaking Pango markup
+ tooltip_text = str.format(
+ "\t\t{}\t\t\n{}\n{}\n{}\n{}\n\n{}\n{}\n{}{}",
+ f'{esc(temp_str)}',
+ f" {icon}",
+ f"{esc(status)}",
+ esc(location_text),
+ f"{esc(feels_str)}" if feels_str else "",
+ f"{esc(min_max)}" if min_max else "",
+ f"{esc(wind_text)}\t{esc(humidity_text)}",
+ f"{esc(visibility_text)}\t{esc(aqi_text)}",
+ f" {esc(prediction)}" if prediction else "",
+ )
+ else:
+ lines = [
+ f"{icon} {temp_str}",
+ status,
+ location_text,
+ ]
+ if feels_str:
+ lines.append(feels_str)
+ if min_max:
+ lines.append(min_max)
+ lines.append(f"{wind_text} {humidity_text}".strip())
+ lines.append(f"{visibility_text} {aqi_text}".strip())
+ if prediction:
+ lines.append(hourly_precip)
+ tooltip_text = "\n".join([ln for ln in lines if ln])
+
+ # Build main text with colorful icon and colored temp; prefer larger icon if emoji
+ if ACTIVE_ICON_STYLE == "emoji":
+ icon_text = f"{icon}"
+ else:
+ # Colorize mono icons subtly
+ icon_text = f"{icon}"
+
+ temp_text = f"{esc(temp_str)}"
+
+ out_data = {
+ "text": f"{icon_text} {temp_text}",
+ "alt": status,
+ "tooltip": tooltip_text,
+ "class": code_for_class,
+ }
+
+ simple_weather = (
+ f"{icon} {status}\n"
+ + f" {temp_str} ({feels_str})\n"
+ + (f"{wind_text} \n" if wind_text else "")
+ + (f"{humidity_text} \n" if humidity_text else "")
+ + f"{visibility_text} {aqi_text}\n"
+ )
+
+ return out_data, simple_weather
+
+
+def main() -> None:
+ lat, lon = get_coords()
+
+ # Try cache first
+ cached = read_api_cache()
+ if cached and isinstance(cached, dict):
+ forecast = cached.get("forecast")
+ aqi = cached.get("aqi")
+ cached_place = cached.get("place") if isinstance(cached.get("place"), str) else None
+ place_effective = MANUAL_PLACE or ENV_PLACE or cached_place
+ try:
+ out, simple = build_output(lat, lon, forecast, aqi, place_effective)
+ print(json.dumps(out, ensure_ascii=False))
+ write_simple_text_cache(simple)
+ return
+ except Exception as e:
+ print(f"Cached data build failed, refetching: {e}", file=sys.stderr)
+
+ # Fetch fresh
+ try:
+ forecast = fetch_open_meteo(lat, lon)
+ aqi = fetch_aqi(lat, lon)
+ # Use manual/env place if provided; otherwise reverse geocode
+ place_effective = MANUAL_PLACE or ENV_PLACE or fetch_place(lat, lon)
+ write_api_cache({"forecast": forecast, "aqi": aqi, "place": place_effective})
+ out, simple = build_output(lat, lon, forecast, aqi, place_effective)
+ print(json.dumps(out, ensure_ascii=False))
+ write_simple_text_cache(simple)
+ except Exception as e:
+ print(f"Open-Meteo fetch failed: {e}", file=sys.stderr)
+ # Last resort: try stale cache without TTL
+ try:
+ if os.path.exists(API_CACHE_PATH):
+ with open(API_CACHE_PATH, "r", encoding="utf-8") as f:
+ stale = json.load(f)
+ out, simple = build_output(lat, lon, stale.get("forecast", {}), stale.get("aqi"), stale.get("place") if isinstance(stale.get("place"), str) else None)
+ print(json.dumps(out, ensure_ascii=False))
+ write_simple_text_cache(simple)
+ return
+ except Exception as e2:
+ print(f"Failed to use stale cache: {e2}", file=sys.stderr)
+ # Fallback minimal output
+ fallback = {
+ "text": f"{WEATHER_ICONS['default']} N/A",
+ "alt": "Unavailable",
+ "tooltip": "Weather unavailable",
+ "class": "unavailable",
+ }
+ print(json.dumps(fallback, ensure_ascii=False))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/home-manager/programs/hypr/waybar/scripts/battery-level.sh b/home-manager/programs/hypr/waybar/scripts/battery-level.sh
new file mode 100755
index 0000000..ddde6ea
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/battery-level.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+
+# Original script by Eric Murphy
+# https://github.com/ericmurphyxyz/dotfiles/blob/master/.local/bin/battery-alert
+#
+# Modified by Jesse Mirabel (@sejjy)
+# https://github.com/sejjy/mechabar
+
+# This script sends a notification when the battery is full, low, or critical.
+# icon theme used: tela-circle-icon-theme-dracula
+#
+# (see the bottom of the script for more information)
+
+export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
+
+# battery levels
+WARNING_LEVEL=20
+CRITICAL_LEVEL=10
+
+# get the battery state and percentage using upower (waybar dependency)
+BAT_PATH=$(upower -e | grep BAT | head -n 1)
+BATTERY_STATE=$(upower -i "$BAT_PATH" | awk '/state:/ {print $2}')
+BATTERY_LEVEL=$(upower -i "$BAT_PATH" | awk '/percentage:/ {print $2}' | tr -d '%')
+
+# prevent multiple notifications
+FILE_FULL=/tmp/battery-full
+FILE_WARNING=/tmp/battery-warning
+FILE_CRITICAL=/tmp/battery-critical
+
+# remove the files if the battery is no longer in that state
+if [ "$BATTERY_STATE" == "discharging" ]; then
+ rm -f $FILE_FULL
+elif [ "$BATTERY_STATE" == "charging" ]; then
+ rm -f "$FILE_WARNING" "$FILE_CRITICAL"
+fi
+
+# if the battery is full and is plugged in
+if [ "$BATTERY_LEVEL" -eq 100 ] && [ "$BATTERY_STATE" == "fully-charged" ] && [ ! -f $FILE_FULL ]; then
+ notify-send -a "state" "Battery Charged (${BATTERY_LEVEL}%)" "You might want to unplug your PC." -i "battery-full" -r 9991
+ touch $FILE_FULL
+
+# if the battery is low and is discharging
+elif [ "$BATTERY_LEVEL" -le $WARNING_LEVEL ] && [ "$BATTERY_STATE" == "discharging" ] && [ ! -f $FILE_WARNING ]; then
+ notify-send -a "state" "Battery Low (${BATTERY_LEVEL}%)" "You might want to plug in your PC." -u critical -i "battery-caution" -r 9991 -h string:fgcolor:\#fab387 -h string:frcolor:\#fab387
+ touch $FILE_WARNING
+
+# if the battery is critical and is discharging
+elif [ "$BATTERY_LEVEL" -le $CRITICAL_LEVEL ] && [ "$BATTERY_STATE" == "discharging" ] && [ ! -f $FILE_CRITICAL ]; then
+ notify-send -a "state" "Battery Critical (${BATTERY_LEVEL}%)" "Plug in your PC now." -u critical -i "battery-empty" -r 9991
+ touch $FILE_CRITICAL
+fi
+
+# systemd service
+# Add the following to ~/.config/systemd/user/battery-level.service:
+
+# [Unit]
+# Description=Battery Level Checker
+# After=graphical.target
+#
+# [Service]
+# ExecStart=%h/.config/waybar/scripts/battery-level.sh
+# Type=oneshot
+
+# systemd timer
+# Add the following to ~/.config/systemd/user/battery-level.timer:
+
+# [Unit]
+# Description=Run Battery Level Checker
+#
+# [Timer]
+# OnBootSec=1min
+# OnUnitActiveSec=1min
+# Unit=battery-level.service
+#
+# [Install]
+# WantedBy=timers.target
+
+# enable the timer by running the following commands:
+# systemctl --user daemon-reload
+# systemctl --user enable --now battery-level.timer
diff --git a/home-manager/programs/hypr/waybar/scripts/battery-state.sh b/home-manager/programs/hypr/waybar/scripts/battery-state.sh
new file mode 100755
index 0000000..d7cf5fc
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/battery-state.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+# Original script by Eric Murphy
+# https://github.com/ericmurphyxyz/dotfiles/blob/master/.local/bin/battery-alert
+#
+# Modified by Jesse Mirabel (@sejjy)
+# https://github.com/sejjy/mechabar
+
+# This script sends a notification when the battery is charging or discharging.
+# icon theme used: tela-circle-icon-theme-dracula
+#
+# (see the bottom of the script for more information)
+
+export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
+
+# get the battery state from the udev rule
+BATTERY_STATE=$1
+
+# get the battery percentage using upower (waybar dependency)
+BAT_PATH=$(upower -e | grep BAT | head -n 1)
+BATTERY_LEVEL=$(upower -i "$BAT_PATH" | awk '/percentage:/ {print $2}' | tr -d '%')
+
+# set the battery charging state and icon
+case "$BATTERY_STATE" in
+"charging")
+ BATTERY_CHARGING="Charging"
+ BATTERY_ICON="090-charging"
+ ;;
+"discharging")
+ BATTERY_CHARGING="Disharging"
+ BATTERY_ICON="090"
+ ;;
+esac
+
+# send the notification
+notify-send -a "state" "Battery ${BATTERY_CHARGING} (${BATTERY_LEVEL}%)" -u normal -i "battery-${BATTERY_ICON}" -r 9991
+
+# udev rule
+# Add the following to /etc/udev/rules.d/60-power.rules:
+
+# ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="0", ENV{DISPLAY}=":0", RUN+="/usr/bin/su -c '$HOME/.config/waybar/scripts/battery-state.sh discharging'"
+# ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="1", ENV{DISPLAY}=":0", RUN+="/usr/bin/su -c '$HOME/.config/waybar/scripts/battery-state.sh charging'"
+
+# the number 60 in the udev rule can be changed to any number between 0 and 99.
+# the lower the number, the higher the priority.
+#
+# $USER does not work, so you have to replace "" with your username.
+
+# reload udev rules by running the following command:
+# sudo udevadm control --reload-rules
diff --git a/home-manager/programs/hypr/waybar/scripts/brightness-control.sh b/home-manager/programs/hypr/waybar/scripts/brightness-control.sh
new file mode 100755
index 0000000..28fa223
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/brightness-control.sh
@@ -0,0 +1,92 @@
+#!/usr/bin/env bash
+
+# Print error message for invalid arguments
+print_error() {
+ cat <<"EOF"
+Usage: ./brightnesscontrol.sh
+Valid actions are:
+ i -- ncrease brightness [+2%]
+ d -- ecrease brightness [-2%]
+EOF
+}
+
+# Send a notification with brightness info
+send_notification() {
+ brightness=$(brightnessctl info | grep -oP "(?<=\()\d+(?=%)")
+ notify-send -a "state" -r 91190 -i "gpm-brightness-lcd" -h int:value:"$brightness" "Brightness: ${brightness}%" -u low
+}
+
+# Get the current brightness percentage and device name
+get_brightness() {
+ brightness=$(brightnessctl -m | grep -o '[0-9]\+%' | head -c-2)
+ device=$(brightnessctl -m | head -n 1 | awk -F',' '{print $1}' | sed 's/_/ /g; s/\<./\U&/g') # Get device name
+ current_brightness=$(brightnessctl -m | head -n 1 | awk -F',' '{print $3}') # Get current brightness
+ max_brightness=$(brightnessctl -m | head -n 1 | awk -F',' '{print $5}') # Get max brightness
+}
+get_brightness
+
+# Handle options
+while getopts o: opt; do
+ case "${opt}" in
+ o)
+ case $OPTARG in
+ i) # Increase brightness
+ if [[ $brightness -lt 10 ]]; then
+ brightnessctl set +1%
+ else
+ brightnessctl set +2%
+ fi
+ send_notification
+ ;;
+ d) # Decrease brightness
+ if [[ $brightness -le 1 ]]; then
+ brightnessctl set 1%
+ elif [[ $brightness -le 10 ]]; then
+ brightnessctl set 1%-
+ else
+ brightnessctl set 2%-
+ fi
+ send_notification
+ ;;
+ *)
+ print_error
+ ;;
+ esac
+ ;;
+ *)
+ print_error
+ ;;
+ esac
+done
+
+# Determine the icon based on brightness level
+get_icon() {
+ if ((brightness <= 5)); then
+ icon=""
+ elif ((brightness <= 15)); then
+ icon=""
+ elif ((brightness <= 30)); then
+ icon=""
+ elif ((brightness <= 45)); then
+ icon=""
+ elif ((brightness <= 55)); then
+ icon=""
+ elif ((brightness <= 65)); then
+ icon=""
+ elif ((brightness <= 80)); then
+ icon=""
+ elif ((brightness <= 95)); then
+ icon=""
+ else
+ icon=""
+ fi
+}
+
+# Backlight module and tooltip
+get_icon
+module="${icon} ${brightness}%"
+
+tooltip="Device Name: ${device}"
+tooltip+="\nBrightness: ${current_brightness} / ${max_brightness}"
+
+echo "{\"text\": \"${module}\", \"tooltip\": \"${tooltip}\"}"
diff --git a/home-manager/programs/hypr/waybar/scripts/cpu-temp.sh b/home-manager/programs/hypr/waybar/scripts/cpu-temp.sh
new file mode 100755
index 0000000..b6f2355
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/cpu-temp.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+
+model=$(awk -F ': ' '/model name/{print $2}' /proc/cpuinfo | head -n 1 | sed 's/@.*//; s/ *\((R)\|(TM)\)//g; s/^[ \t]*//; s/[ \t]*$//')
+
+# get CPU clock speeds
+get_cpu_frequency() {
+ freqlist=$(awk '/cpu MHz/ {print $4}' /proc/cpuinfo)
+ maxfreq=$(sed 's/...$//' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
+ if [ -z "$freqlist" ] || [ -z "$maxfreq" ]; then
+ echo "--"
+ return
+ fi
+ average_freq=$(echo "$freqlist" | tr ' ' '\n' | awk "{sum+=\$1} END {printf \"%.0f/%s MHz\", sum/NR, $maxfreq}")
+ echo "$average_freq"
+}
+
+# get CPU temp
+get_cpu_temperature() {
+ temp=$(sensors | awk '/Package id 0/ {print $4}' | awk -F '[+.]' '{print $2}')
+ if [[ -z "$temp" ]]; then
+ temp=$(sensors | awk '/Tctl/ {print $2}' | tr -d '+°C')
+ fi
+ if [[ -z "$temp" ]]; then
+ temp="--"
+ temp_f="--"
+ else
+ temp=${temp%.*}
+ temp_f=$(awk "BEGIN {printf \"%.1f\", ($temp * 9 / 5) + 32}")
+ fi
+ # Celsius and Fahrenheit
+ echo "${temp:---} ${temp_f:---}"
+}
+
+get_temperature_icon() {
+ temp_value=$1
+ if [ "$temp_value" = "--" ]; then
+ icon="" # none
+ elif [ "$temp_value" -ge 80 ]; then
+ icon="" # high
+ elif [ "$temp_value" -ge 70 ]; then
+ icon="" # medium
+ elif [ "$temp_value" -ge 60 ]; then
+ icon="" # normal
+ else
+ icon="" # low
+ fi
+ echo "$icon"
+}
+
+cpu_frequency=$(get_cpu_frequency)
+read -r temp_info < <(get_cpu_temperature)
+temp=$(echo "$temp_info" | awk '{print $1}')
+temp_f=$(echo "$temp_info" | awk '{print $2}')
+thermo_icon=$(get_temperature_icon "$temp")
+
+# high temp warning
+if [ "$temp" == "--" ] || [ "$temp" -ge 80 ]; then
+ text_output="${thermo_icon} ${temp}°C"
+else
+ text_output="${thermo_icon} ${temp}°C"
+fi
+
+tooltip=":: ${model}\n"
+tooltip+="Clock Speed: ${cpu_frequency}\nTemperature: ${temp_f}°F"
+
+# module and tooltip
+echo "{\"text\": \"$text_output\", \"tooltip\": \"$tooltip\"}"
diff --git a/home-manager/programs/hypr/waybar/scripts/power-menu.sh b/home-manager/programs/hypr/waybar/scripts/power-menu.sh
new file mode 100755
index 0000000..d330c3d
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/power-menu.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+# Use a dedicated narrow dark theme for the power menu
+config="$HOME/.config/rofi/power-menu.rasi"
+
+actions=$(echo -e " Lock\n Shutdown\n Reboot\n Suspend\n Hibernate\n Logout")
+
+# Display logout menu
+selected_option=$(echo -e "$actions" | rofi -dmenu -i -p "Power Menu" -config "${config}" || pkill -x rofi)
+
+# Perform actions based on the selected option
+case "$selected_option" in
+*Lock)
+ loginctl lock-session
+ ;;
+*Shutdown)
+ systemctl poweroff
+ ;;
+*Reboot)
+ systemctl reboot
+ ;;
+*Suspend)
+ systemctl suspend
+ ;;
+*Hibernate)
+ systemctl hibernate
+ ;;
+*Logout)
+ loginctl kill-session "$XDG_SESSION_ID"
+ ;;
+esac
diff --git a/home-manager/programs/hypr/waybar/scripts/volume-control.sh b/home-manager/programs/hypr/waybar/scripts/volume-control.sh
new file mode 100755
index 0000000..76bb2f7
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/volume-control.sh
@@ -0,0 +1,123 @@
+#!/usr/bin/env bash
+
+# Define functions
+print_error() {
+ cat <<"EOF"
+Usage: ./volumecontrol.sh -[device]
+...valid devices are...
+ i -- input device
+ o -- output device
+ p -- player application
+...valid actions are...
+ i -- increase volume [+2]
+ d -- decrease volume [-2]
+ m -- mute [x]
+EOF
+ exit 1
+}
+
+icon() {
+ vol=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}' | sed 's/%//')
+ mute=$(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}')
+
+ if [ "$mute" = "yes" ] || [ "$vol" -eq 0 ]; then
+ icon="volume-level-muted"
+ elif [ "$vol" -lt 33 ]; then
+ icon="volume-level-low"
+ elif [ "$vol" -lt 66 ]; then
+ icon="volume-level-medium"
+ else
+ icon="volume-level-high"
+ fi
+}
+
+send_notification() {
+ icon
+ notify-send -a "state" -r 91190 -i "$icon" -h int:value:"$vol" "Volume: ${vol}%" -u low
+}
+
+notify_mute() {
+ mute=$(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}')
+ if [ "$mute" = "yes" ]; then
+ notify-send -a "state" -r 91190 -i "volume-level-muted" "Volume: Muted" -u low
+ else
+ icon
+ notify-send -a "state" -r 91190 -i "$icon" "Volume: Unmuted" -u low
+ fi
+}
+
+action_volume() {
+ case "${1}" in
+ i)
+ # Increase volume if below 100
+ current_vol=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}' | sed 's/%//')
+ if [ "$current_vol" -lt 100 ]; then
+ new_vol=$((current_vol + 2))
+ [ "$new_vol" -gt 100 ] && new_vol=100
+ pactl set-sink-volume @DEFAULT_SINK@ "${new_vol}%"
+ fi
+ ;;
+ d)
+ # Decrease volume if above 0
+ current_vol=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}' | sed 's/%//')
+ new_vol=$((current_vol - 2))
+ [ "$new_vol" -lt 0 ] && new_vol=0
+ pactl set-sink-volume @DEFAULT_SINK@ "${new_vol}%"
+ ;;
+ esac
+}
+
+select_output() {
+ if [ "$@" ]; then
+ desc="$*"
+ device=$(pactl list sinks | grep -C2 -F "Description: $desc" | grep Name | cut -d: -f2 | xargs)
+ if pactl set-default-sink "$device"; then
+ notify-send -r 91190 "Activated: $desc"
+ else
+ notify-send -r 91190 "Error activating $desc"
+ fi
+ else
+ pactl list sinks | grep -ie "Description:" | awk -F ': ' '{print $2}' | sort
+ fi
+}
+
+# Evaluate device option
+while getopts iops: DeviceOpt; do
+ case "${DeviceOpt}" in
+ i)
+ nsink=$(pactl list sources short | awk '{print $2}')
+ [ -z "${nsink}" ] && echo "ERROR: Input device not found..." && exit 0
+ srce="--default-source"
+ ;;
+ o)
+ nsink=$(pactl list sinks short | awk '{print $2}')
+ [ -z "${nsink}" ] && echo "ERROR: Output device not found..." && exit 0
+ srce=""
+ ;;
+ p)
+ nsink=$(playerctl --list-all | grep -w "${OPTARG}")
+ [ -z "${nsink}" ] && echo "ERROR: Player ${OPTARG} not active..." && exit 0
+ # shellcheck disable=SC2034
+ srce="${nsink}"
+ ;;
+ s)
+ # Select an output device
+ select_output "$@"
+ exit
+ ;;
+ *) print_error ;;
+ esac
+done
+
+# Set default variables
+shift $((OPTIND - 1))
+
+# Execute action
+case "${1}" in
+i) action_volume i ;;
+d) action_volume d ;;
+m) pactl set-sink-mute @DEFAULT_SINK@ toggle && notify_mute && exit 0 ;;
+*) print_error ;;
+esac
+
+send_notification
diff --git a/home-manager/programs/hypr/waybar/scripts/wifi-status.sh b/home-manager/programs/hypr/waybar/scripts/wifi-status.sh
new file mode 100755
index 0000000..2485268
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/scripts/wifi-status.sh
@@ -0,0 +1,177 @@
+#!/usr/bin/env bash
+
+# This script gathers detailed Wi-Fi connection information.
+# It collects the following fields:
+#
+# - SSID (Service Set Identifier): The name of the Wi-Fi network you
+# are currently connected to. Example: "My_Network"
+#
+# - IP Address: The IP address assigned to the device by the router.
+# This is typically a private IP within the local network. Example:
+# "192.168.1.29/24" (with subnet mask)
+#
+# - Router (Gateway): The IP address of the router (default gateway)
+# that your device uses to communicate outside the local network.
+# Example: "192.168.1.1"
+#
+# - MAC Address: The unique Media Access Control address of the local
+# device's Wi-Fi adapter. Example: "F8:34:41:07:1B:65"
+#
+# - Security: The encryption protocol being used to secure your Wi-Fi
+# connection. Common security protocols include:
+# - WPA2 (Wi-Fi Protected Access 2): The most commonly used security
+# standard, offering strong encryption (AES).
+# - WPA3: The latest version, providing even stronger security,
+# especially in public or open networks.
+# - WEP (Wired Equivalent Privacy): An outdated and insecure protocol
+# that should not be used.
+# Example: "WPA2" indicates that the connection is secured using WPA2
+# with AES encryption.
+#
+# - BSSID (Basic Service Set Identifier): The MAC address of the Wi-Fi
+# access point you are connected to. Example: "A4:22:49:DA:91:A0"
+#
+# - Channel: The wireless channel your Wi-Fi network is using. This is
+# associated with the frequency band. Example: "100 (5500 MHz)"
+# indicates the channel number (100) and the frequency (5500 MHz),
+# which is within the 5 GHz band.
+#
+# - RSSI (Received Signal Strength Indicator): The strength of the
+# Wi-Fi signal, typically in dBm (decibels relative to 1 milliwatt).
+# Closer to 0 means stronger signal, with values like -40 dBm being
+# very good. Example: "-40 dBm"
+#
+# - Signal: The signal quality, which is represented as a percentage,
+# where higher numbers mean better signal. Example: "100"
+# indicates perfect signal strength.
+#
+# - Rx Rate (Receive Rate): The maximum data rate (in Mbit/s) at which
+# the device can receive data from the Wi-Fi access point. Example:
+# "866.7 MBit/s" indicates a high-speed connection on a modern
+# standard.
+#
+# - Tx Rate (Transmit Rate): The maximum data rate (in Mbit/s) at
+# which the device can send data to the Wi-Fi access point. Example:
+# "866.7 MBit/s"
+#
+# - PHY Mode (Physical Layer Mode): The Wi-Fi protocol or standard in
+# use. Common modes include 802.11n, 802.11ac, and 802.11ax (Wi-Fi
+# 6). Example: "802.11ac" indicates you're using the 5 GHz band with
+# a modern high-speed standard.
+
+if ! command -v nmcli &>/dev/null; then
+ echo "{\"text\": \"\", \"tooltip\": \"nmcli utility is missing\"}"
+ exit 1
+fi
+
+# Check if Wi-Fi is enabled
+wifi_status=$(nmcli radio wifi)
+
+if [ "$wifi_status" = "disabled" ]; then
+ echo "{\"text\": \"\", \"tooltip\": \"Wi-Fi Disabled\"}"
+ exit 0
+fi
+
+wifi_info=$(nmcli -t -f active,ssid,signal,security dev wifi | grep "^yes")
+
+# If no ESSID is found, set a default value
+if [ -z "$wifi_info" ]; then
+ essid="No Connection"
+ signal=0
+ tooltip="No Connection"
+else
+ # Some defaults
+ ip_address="127.0.0.1"
+ # gateway="127.0.0.1"
+ # mac_address="N/A"
+ security=$(echo "$wifi_info" | awk -F: '{print $4}')
+ # bssid="N/A"
+ chan="N/A"
+ # rssi="N/A"
+ # rx_bitrate=""
+ # tx_bitrate=""
+ # phy_mode=""
+ signal=$(echo "$wifi_info" | awk -F: '{print $3}')
+
+ active_device=$(nmcli -t -f DEVICE,STATE device status |
+ grep -w "connected" |
+ grep -v -E "^(dummy|lo:|virbr0)" |
+ awk -F: '{print $1}' |
+ head -n 1)
+
+ if [ -n "$active_device" ]; then
+ output=$(nmcli -e no -g ip4.address,ip4.gateway,general.hwaddr device show "$active_device")
+
+ ip_address=$(echo "$output" | sed -n '1p')
+ # gateway=$(echo "$output" | sed -n '2p')
+ # mac_address=$(echo "$output" | sed -n '3p')
+
+ line=$(nmcli -e no -t -f active,bssid,chan,freq device wifi | grep "^yes")
+
+ # bssid=$(echo "$line" | awk -F':' '{print $2":"$3":"$4":"$5":"$6":"$7}')
+ chan=$(echo "$line" | awk -F':' '{print $8}')
+ freq=$(echo "$line" | awk -F':' '{print $9}')
+ chan="$chan ($freq)"
+
+ # if command -v iw &>/dev/null; then
+ # iw_output=$(iw dev "$active_device" station dump)
+ # rssi=$(echo "$iw_output" | grep "signal:" | awk '{print $2 " dBm"}')
+
+ # Upload speed
+ # rx_bitrate=$(echo "$iw_output" | grep "rx bitrate:" | awk '{print $3 " " $4}')
+
+ # Download speed
+ # tx_bitrate=$(echo "$iw_output" | grep "tx bitrate:" | awk '{print $3 " " $4}')
+
+ # Physical Layer Mode
+ # if echo "$iw_output" | grep -E -q "rx bitrate:.* VHT"; then
+ # phy_mode="802.11ac" # Wi-Fi 5
+ # elif echo "$iw_output" | grep -E -q "rx bitrate:.* HT"; then
+ # phy_mode="802.11n" # Wi-Fi 4
+ # elif echo "$iw_output" | grep -E -q "rx bitrate:.* HE"; then
+ # phy_mode="802.11ax" # Wi-Fi 6
+ # fi
+ # fi
+
+ # Get the current Wi-Fi ESSID
+ essid=$(echo "$wifi_info" | awk -F: '{print $2}')
+
+ tooltip=":: ${essid}"
+ tooltip+="\nIP Address: ${ip_address}"
+ # tooltip+="\nRouter: ${gateway}"
+ # tooltip+="\nMAC Address: ${mac_address}"
+ tooltip+="\nSecurity: ${security}"
+ # tooltip+="\nBSSID: ${bssid}"
+ tooltip+="\nChannel: ${chan}"
+ # tooltip+="\nRSSI: ${rssi}"
+ tooltip+="\nStrength: ${signal} / 100"
+
+ # if [ -n "$rx_bitrate" ]; then
+ # tooltip+="\nRx Rate: ${rx_bitrate}"
+ # fi
+
+ # if [ -n "$tx_bitrate" ]; then
+ # tooltip+="\nTx Rate: ${tx_bitrate}"
+ # fi
+
+ # if [ -n "$phy_mode" ]; then
+ # tooltip+="\nPHY Mode: ${phy_mode}"
+ # fi
+ fi
+fi
+
+# Determine Wi-Fi icon based on signal strength
+if [ "$signal" -ge 80 ]; then
+ icon="" # Strong signal
+elif [ "$signal" -ge 60 ]; then
+ icon="" # Good signal
+elif [ "$signal" -ge 40 ]; then
+ icon="" # Weak signal
+elif [ "$signal" -ge 20 ]; then
+ icon="" # Very weak signal
+else
+ icon="" # No signal
+fi
+
+# Module and tooltip
+echo "{\"text\": \"${icon}\", \"tooltip\": \"${tooltip}\"}"
diff --git a/home-manager/programs/hypr/waybar/waybar-TheBlackDon.nix b/home-manager/programs/hypr/waybar/waybar-TheBlackDon.nix
new file mode 100644
index 0000000..fbab96c
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-TheBlackDon.nix
@@ -0,0 +1,563 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ clock24h = false;
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in
+ with lib; {
+ # Install any helper scripts shipped in modules/home/waybar/scripts into ~/.config/waybar/scripts
+ home.file = builtins.listToAttrs (map
+ (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts);
+
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ exclusive = true;
+ passthrough = false;
+ "fixed-center" = true;
+ ipc = true;
+
+ height = 34;
+ spacing = 0;
+ margin = 2;
+ "margin-top" = 0;
+ "margin-bottom" = 0;
+ "margin-left" = 0;
+ "margin-right" = 0;
+
+ modules-left = [
+ "custom/startmenu"
+ "custom/qs_wallpapers_apply"
+ "custom/qs_vid_wallpapers_apply"
+ "hyprland/workspaces"
+ "idle_inhibitor"
+ "tray"
+ "mpd#2"
+ "mpd#3"
+ "mpd#4"
+ "mpd"
+ ];
+ modules-center = ["cpu" "cpu#2" "memory" "memory#2" "disk" "disk#2"];
+ modules-right = [
+ "custom/themes"
+ "pulseaudio"
+ "pulseaudio#2"
+ "backlight"
+ "backlight#2"
+ "battery"
+ "battery#2"
+ "bluetooth"
+ "bluetooth#2"
+ "network"
+ "network#2"
+ "clock"
+ "clock#2"
+ "custom/power"
+ ];
+
+ # --- Modules (ported from provided BlackDog config) ---
+ backlight = {
+ interval = 2;
+ format = "{icon}";
+ "format-icons" = ["" "" "" "" "" "" ""];
+ "on-scroll-up" = "light -A 5%";
+ "on-scroll-down" = "light -U 5%";
+ "smooth-scrolling-threshold" = 1;
+ };
+ "backlight#2" = {
+ interval = 2;
+ format = "{percent}%";
+ "on-scroll-up" = "light -A 5%";
+ "on-scroll-down" = "light -U 5%";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ battery = {
+ interval = 60;
+ "full-at" = 100;
+ "design-capacity" = false;
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon}";
+ "format-charging" = "";
+ "format-plugged" = "ﮣ";
+ "format-full" = "";
+ "format-icons" = ["" "" "" "" "" "" "" "" ""];
+ "format-time" = "{H}h {M}min";
+ tooltip = true;
+ };
+ "battery#2" = {
+ interval = 60;
+ "full-at" = 100;
+ "design-capacity" = false;
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 15;
+ };
+ format = "{capacity}%";
+ "format-charging" = "{capacity}%";
+ "format-plugged" = "{capacity}%";
+ "format-full" = "Full";
+ "format-alt" = "{time}";
+ "format-time" = "{H}h {M}min";
+ tooltip = true;
+ };
+
+ bluetooth = {
+ format = "";
+ "format-on" = "";
+ "format-off" = "";
+ "format-disabled" = "";
+ "format-connected" = "";
+ "format-connected-battery" = "";
+ tooltip = true;
+ "tooltip-format" = "{controller_alias}\t{controller_address}";
+ "tooltip-format-connected" = "{controller_alias}\t{controller_address}\n\n{device_enumerate}";
+ "tooltip-format-enumerate-connected" = "{device_alias}\t{device_address}";
+ "on-click" = "$HOME/.config/hypr/scripts/rofi_bluetooth";
+ "on-click-right" = "blueman-manager";
+ };
+ "bluetooth#2" = {
+ format = "{status}";
+ "format-on" = "{status}";
+ "format-off" = "{status}";
+ "format-disabled" = "{status}";
+ "format-connected" = "{device_alias}";
+ "format-connected-battery" = "{device_alias}, {device_battery_percentage}%";
+ tooltip = true;
+ "tooltip-format" = "{controller_alias}\t{controller_address}";
+ "tooltip-format-connected" = "{controller_alias}\t{controller_address}\n\n{device_enumerate}";
+ "tooltip-format-enumerate-connected" = "{device_alias}\t{device_address}";
+ "on-click" = "$HOME/.config/hypr/scripts/rofi_bluetooth";
+ "on-click-right" = "blueman-manager";
+ };
+
+ clock = {
+ "tooltip-format" = "{:%B %Y}\n{calendar}";
+ format = "";
+ };
+ "clock#2" = {
+ interval = 60;
+ "tooltip-format" = "{:%B %Y}\n{calendar}";
+ format =
+ if clock24h
+ then "{:%H:%M}"
+ else "{:%I:%M %p}";
+ "format-alt" = "{:%a %b %d, %G}";
+ };
+
+ cpu = {
+ interval = 5;
+ format = "";
+ };
+ "cpu#2" = {
+ interval = 5;
+ format = "{usage}%";
+ };
+
+ "custom/themes" = {
+ format = "";
+ tooltip = false;
+ "on-click" = "$HOME/.config/hypr/theme/theme.sh --pywal";
+ "on-click-right" = "$HOME/.config/hypr/theme/theme.sh --default";
+ };
+
+ # Start menu aligned to project standard
+ "custom/startmenu" = {
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ format = "";
+ on-click = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+
+ # Power menu aligned to project standard (qs-wlogout + rofi fallback)
+ "custom/power" = {
+ tooltip = true;
+ "tooltip-format" = "Left Click: Power Menu (qs-wlogout)\nRight Click: Rofi Power Menu";
+ format = " ⏻ ";
+ on-click = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ };
+
+ disk = {
+ interval = 30;
+ format = "";
+ };
+ "disk#2" = {
+ interval = 30;
+ format = "{free}";
+ };
+
+ memory = {
+ interval = 10;
+ format = "";
+ };
+ "memory#2" = {
+ interval = 10;
+ format = "{used:0.1f}G";
+ };
+
+ # Optional Spotify module (kept from source; may require script)
+ "custom/spotify" = {
+ exec = "$HOME/.config/hypr/waybar/spotify";
+ interval = 1;
+ format = "{}";
+ tooltip = true;
+ "max-length" = 40;
+ "on-click" = "playerctl play-pause";
+ "on-click-middle" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "on-scroll-up" = "playerctl position 05+";
+ "on-scroll-down" = "playerctl position 05-";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ # MPD transport cluster
+ mpd = {
+ interval = 2;
+ "unknown-tag" = "N/A";
+ format = "{artist} - {title} | 祥 {elapsedTime:%M:%S}";
+ "format-disconnected" = "Disconnected";
+ "format-paused" = "{artist} - {title}";
+ "format-stopped" = "Stopped";
+ "tooltip-format" = "MPD (connected)";
+ "tooltip-format-disconnected" = "MPD (disconnected)";
+ "on-click" = "mpc toggle";
+ "on-scroll-up" = "mpc seek +00:00:01";
+ "on-scroll-down" = "mpc seek -00:00:01";
+ "smooth-scrolling-threshold" = 1;
+ };
+ "mpd#2" = {
+ format = "玲";
+ "format-disconnected" = "玲";
+ "format-paused" = "玲";
+ "format-stopped" = "玲";
+ "on-click" = "mpc prev";
+ };
+ "mpd#3" = {
+ interval = 1;
+ format = "{stateIcon}";
+ "format-disconnected" = "";
+ "format-paused" = "{stateIcon}";
+ "format-stopped" = "";
+ "state-icons" = {
+ paused = "";
+ playing = "";
+ };
+ "on-click" = "mpc toggle";
+ };
+ "mpd#4" = {
+ format = "怜";
+ "format-disconnected" = "怜";
+ "format-paused" = "怜";
+ "format-stopped" = "怜";
+ "on-click" = "mpc next";
+ };
+
+ network = {
+ interval = 5;
+ "format-wifi" = "直";
+ "format-ethernet" = "";
+ "format-linked" = "";
+ "format-disconnected" = "睊";
+ "format-disabled" = "睊";
+ "tooltip-format" = " {ifname} via {gwaddr}";
+ "on-click" = "$HOME/.config/hypr/scripts/rofi_network";
+ };
+ "network#2" = {
+ interval = 5;
+ "format-wifi" = "{essid}";
+ "format-ethernet" = "{ipaddr}/{cidr}";
+ "format-linked" = "{ifname} (No IP)";
+ "format-disconnected" = "Disconnected";
+ "format-disabled" = "Disabled";
+ "format-alt" = " {bandwidthUpBits} | {bandwidthDownBits}";
+ "tooltip-format" = " {ifname} via {gwaddr}";
+ };
+
+ pulseaudio = {
+ format = "{icon}";
+ "format-muted" = "";
+ "format-bluetooth" = "";
+ "format-bluetooth-muted" = "";
+ "format-source" = "";
+ "format-source-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ "hands-free" = "ﳌ";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ "scroll-step" = 5.0;
+ "on-click" = "pulsemixer --toggle-mute";
+ "on-click-right" = "pulsemixer --toggle-mute";
+ "smooth-scrolling-threshold" = 1;
+ };
+ "pulseaudio#2" = {
+ format = "{volume}%";
+ "format-muted" = "Mute";
+ "format-bluetooth" = "{volume}%";
+ "format-bluetooth-muted" = "Mute";
+ "format-source" = "{volume}%";
+ "scroll-step" = 5.0;
+ "on-click" = "pulsemixer --toggle-mute";
+ "on-click-right" = "pulsemixer --toggle-mute";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ idle_inhibitor = {
+ format = "{icon}";
+ "format-icons" = {
+ activated = "";
+ deactivated = "";
+ };
+ timeout = 30;
+ };
+
+ "hyprland/workspaces" = {
+ format = "{icon}";
+ "sort-by-number" = true;
+ "active-only" = false;
+ "format-icons" = {
+ "1" = "1";
+ "2" = "2";
+ "3" = "3";
+ "4" = "4";
+ "5" = "5";
+ "6" = "6";
+ "7" = "7";
+ "8" = "8";
+ "9" = "9";
+ "10" = "10";
+ urgent = "";
+ focused = "";
+ default = "";
+ };
+ on-click = "activate";
+ };
+
+ tray = {
+ "icon-size" = 16;
+ spacing = 10;
+ };
+
+ # ddubs wallpaper quick actions
+ "custom/qs_wallpapers_apply" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "Set image wallpaper";
+ on-click = "qs-wallpapers-apply";
+ };
+ "custom/qs_vid_wallpapers_apply" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "Set video wallpaper";
+ on-click = "qs-vid-wallpapers-apply";
+ };
+ }
+ ];
+
+ # --- CSS (colors + styles from provided BlackDog theme, with startmenu selector updated) ---
+ style = concatStrings [
+ ''
+ /** Colors (from colors.css) **/
+ @define-color background #0a0a0a;
+ @define-color background-alt1 #181818;
+ @define-color background-alt2 #232323;
+ @define-color foreground #ddd8d0;
+ @define-color selected #E29E5D;
+ @define-color black #0a0a0a;
+ @define-color red #C53A31;
+ @define-color green #867971;
+ @define-color yellow #8F847B;
+ @define-color blue #E29E5D;
+ @define-color magenta #7C7987;
+ @define-color cyan #A19993;
+ @define-color white #ddd8d0;
+
+ /** Fonts **/
+ * {
+ font-family: "JetBrains Mono", "Symbols Nerd Font", Iosevka, archcraft, sans-serif;
+ font-size: 14px;
+ }
+
+ /** Waybar Window **/
+ window#waybar {
+ background-color: @background;
+ color: @foreground;
+ border-bottom: 2px solid @background-alt1;
+ transition-property: background-color;
+ transition-duration: .5s;
+ }
+ window#waybar.hidden { opacity: 0.5; }
+
+ /** Custom **/
+ #custom-startmenu {
+ background-color: @background-alt1;
+ color: @magenta;
+ font-size: 18px;
+ border-radius: 0px 14px 0px 0px;
+ margin: 0px 0px 0px 0px;
+ padding: 2px 8px 2px 8px;
+ }
+ #custom-themes { background-color: @selected; }
+ #custom-power {
+ background-color: @red;
+ font-size: 16px;
+ }
+ #custom-power, #custom-themes {
+ color: @background;
+ border-radius: 10px;
+ margin: 6px 6px 6px 0px;
+ padding: 2px 8px 2px 8px;
+ }
+
+ /** Idle Inhibitor **/
+ #idle_inhibitor {
+ background-color: @green;
+ color: @background;
+ border-radius: 10px;
+ margin: 6px 0px 6px 6px;
+ padding: 4px 6px;
+ }
+ #idle_inhibitor.deactivated { background-color: @red; }
+
+ /** Tray **/
+ #tray {
+ background-color: @background-alt1;
+ border-radius: 10px;
+ margin: 6px 0px 6px 6px;
+ padding: 4px 6px;
+ }
+ #tray > .passive { -gtk-icon-effect: dim; }
+ #tray > .needs-attention { -gtk-icon-effect: highlight; }
+
+ /** MPD **/
+ @keyframes gradient {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+ }
+ #mpd { color: @foreground; font-size: 12px; font-weight: bold; }
+ #mpd.disconnected, #mpd.stopped { color: @red; }
+ #mpd.playing { color: @cyan; }
+ #mpd.2 { border-radius: 10px 0px 0px 10px; margin: 6px 0px 6px 6px; padding: 4px 6px 4px 10px; }
+ #mpd.3 { margin: 6px 0px 6px 0px; padding: 4px; }
+ #mpd.4 { border-radius: 0px 10px 10px 0px; margin: 6px 6px 6px 0px; padding: 4px 10px 4px 6px; }
+ #mpd.2,#mpd.3,#mpd.4 { background-color: @background-alt1; font-size: 14px; }
+
+ /** Spotify **/
+ #custom-spotify {
+ background-color: @background-alt1;
+ color: @foreground;
+ border-radius: 10px;
+ margin: 6px 0px 6px 6px;
+ padding: 4px 8px;
+ font-size: 12px;
+ font-weight: bold;
+ }
+ #custom-spotify.paused { color: @foreground; }
+ #custom-spotify.playing {
+ background: linear-gradient(90deg, @magenta 25%, @red 50%, @yellow 75%, @cyan 100%);
+ background-size: 300% 300%;
+ animation: gradient 10s ease infinite;
+ color: @background;
+ }
+ #custom-spotify.offline { color: @red; }
+
+ /** CPU/Memory/Disk **/
+ #cpu { color: @red; }
+ #memory { color: @green; }
+ #disk { color: @yellow; }
+
+ /** Pulseaudio **/
+ #pulseaudio { color: @blue; }
+ #pulseaudio.bluetooth { color: @cyan; }
+ #pulseaudio.muted { color: @red; }
+
+ /** Backlight **/
+ #backlight { color: @magenta; }
+
+ /** Battery **/
+ #battery { color: @cyan; }
+ @keyframes blink { to { color: @foreground; } }
+ #battery.critical:not(.charging) { background-color: @background-alt2; }
+ #battery.2.critical:not(.charging) {
+ background-color: @background-alt1;
+ color: @red;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ /** Network **/
+ #network { color: @yellow; }
+ #network.disconnected, #network.disabled { color: @red; }
+
+ /** Bluetooth **/
+ #bluetooth { color: @green; }
+ #bluetooth.disabled, #bluetooth.off { color: @red; }
+
+ /** Clock **/
+ #clock { color: @blue; }
+
+ /** Workspaces **/
+ #workspaces {
+ background-color: @background;
+ border-radius: 10px;
+ margin-left: 6px;
+ margin-bottom: 2px;
+ padding: 0px;
+ }
+ #workspaces button { color: @foreground; }
+ #workspaces button.active { color: @red; }
+ #workspaces button.urgent { color: @green; }
+ #workspaces button.hidden { color: @yellow; }
+
+ /** Common style **/
+ #backlight, #battery, #clock, #cpu, #disk, #memory, #pulseaudio, #network, #bluetooth {
+ background-color: @background-alt2;
+ border-radius: 10px 0px 0px 10px;
+ margin: 6px 0px 6px 0px;
+ padding: 4px 6px;
+ }
+ #backlight.2, #battery.2, #clock.2, #cpu.2, #disk.2, #memory.2, #pulseaudio.2, #network.2, #bluetooth.2 {
+ background-color: @background-alt1;
+ color: @foreground;
+ font-size: 12px;
+ font-weight: bold;
+ border-radius: 0px 10px 10px 0px;
+ margin: 6px 6px 6px 0px;
+ padding: 5px 6px 4px 6px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-curved.nix b/home-manager/programs/hypr/waybar/waybar-curved.nix
new file mode 100644
index 0000000..2ef065b
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-curved.nix
@@ -0,0 +1,277 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ betterTransition = "all 0.3s cubic-bezier(.55,-0.68,.48,1.682)";
+ clock24h = false; # replaces variables.nix import
+in
+ with lib; {
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ modules-center = ["hyprland/workspaces"];
+ modules-left = [
+ "custom/startmenu"
+ "hyprland/window"
+ "pulseaudio"
+ "cpu"
+ "memory"
+ "idle_inhibitor"
+ ];
+ modules-right = [
+ "custom/hyprbindings"
+ "custom/notification"
+ "custom/exit"
+ "battery"
+ "tray"
+ "clock"
+ ];
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format =
+ if clock24h == true
+ then '' {:L%H:%M}''
+ else '' {:L%I:%M %p}'';
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }\n{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 22;
+ separate-outputs = false;
+ rewrite = {
+ "" = " 🙈 No Windows? ";
+ };
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ };
+ "network" = {
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ format-ethernet = " {bandwidthDownOctets}";
+ format-wifi = "{icon} {signalStrength}%";
+ format-disconnected = "";
+ tooltip = false;
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ on-click = "sleep 0.1 && pavucontrol";
+ };
+ "custom/exit" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && wlogout";
+ };
+ "custom/startmenu" = {
+ tooltip = false;
+ format = "";
+ # exec = "rofi -show drun";
+ on-click = "sleep 0.1 && rofi-launcher";
+ };
+ "custom/hyprbindings" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && list-keybinds";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = "";
+ deactivated = "";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "sleep 0.1 && task-waybar";
+ escape = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-family: JetBrainsMono Nerd Font Mono;
+ font-size: 16px;
+ border-radius: 0px;
+ border: none;
+ min-height: 0px;
+ }
+ window#waybar {
+ background: rgba(0,0,0,0);
+ }
+ #workspaces {
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base01};
+ margin: 4px 4px;
+ padding: 5px 5px;
+ border-radius: 16px;
+ }
+ #workspaces button {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ opacity: 0.5;
+ transition: ${betterTransition};
+ }
+ #workspaces button.active {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ transition: ${betterTransition};
+ opacity: 1.0;
+ min-width: 40px;
+ }
+ #workspaces button:hover {
+ font-weight: bold;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ opacity: 0.8;
+ transition: ${betterTransition};
+ }
+ tooltip {
+ background: #${config.lib.stylix.colors.base00};
+ border: 1px solid #${config.lib.stylix.colors.base08};
+ border-radius: 12px;
+ }
+ tooltip label {
+ color: #${config.lib.stylix.colors.base08};
+ }
+ #window, #pulseaudio, #cpu, #memory, #idle_inhibitor {
+ font-weight: bold;
+ margin: 4px 0px;
+ margin-left: 7px;
+ padding: 0px 18px;
+ background: #${config.lib.stylix.colors.base04};
+ color: #${config.lib.stylix.colors.base00};
+ border-radius: 24px 10px 24px 10px;
+ }
+ #custom-startmenu {
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base02};
+ font-size: 28px;
+ margin: 0px;
+ padding: 0px 30px 0px 15px;
+ border-radius: 0px 0px 40px 0px;
+ }
+ #custom-hyprbindings, #network, #battery,
+ #custom-notification, #tray, #custom-exit {
+ font-weight: bold;
+ background: #${config.lib.stylix.colors.base0F};
+ color: #${config.lib.stylix.colors.base00};
+ margin: 4px 0px;
+ margin-right: 7px;
+ border-radius: 10px 24px 10px 24px;
+ padding: 0px 18px;
+ }
+ #clock {
+ font-weight: bold;
+ color: #0D0E15;
+ background: linear-gradient(90deg, #${config.lib.stylix.colors.base0E}, #${config.lib.stylix.colors.base0C});
+ margin: 0px;
+ padding: 0px 15px 0px 30px;
+ border-radius: 0px 0px 0px 40px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-ddubs-2.nix b/home-manager/programs/hypr/waybar/waybar-ddubs-2.nix
new file mode 100644
index 0000000..2cce101
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-ddubs-2.nix
@@ -0,0 +1,356 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}: let
+ terminal = "kitty";
+ base00 = "0F1419";
+ base01 = "131721";
+ base03 = "3E4B59";
+ base05 = "E6E1CF";
+ base06 = "E6E1CF";
+ base07 = "F3F4F5";
+ base08 = "F07178";
+ base09 = "FF8F40";
+ base0A = "FFB454";
+ base0B = "B8CC52";
+ base0C = "95E6CB";
+ base0D = "59C2FF";
+ base0E = "D2A6FF";
+ base0F = "E6B673";
+in
+ with lib; {
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+
+ modules-left = ["custom/startmenu" "tray" "hyprland/window"];
+ modules-center = ["hyprland/workspaces"];
+ modules-right = ["idle_inhibitor" "custom/notification" "pulseaudio" "battery" "clock" "custom/exit"];
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format = '' {:%H:%M}'';
+ /*
+ ''{: %I:%M %p}'';
+ */
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 60;
+ separate-outputs = false;
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ on-click = "${terminal} -e btop";
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ on-click = "${terminal} -e btop";
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ # Not working with zaneyos window open then closes
+ #on-click = "${terminal} -e sh -c df -h ; read";
+ };
+ "network" = {
+ format-icons = ["" "" "" "" ""];
+ format-ethernet = " {bandwidthDownBits}";
+ format-wifi = " {bandwidthDownBits}";
+ format-disconnected = "";
+ tooltip = false;
+ on-click = "${terminal} -e btop";
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ on-click = "pavucontrol";
+ };
+ "custom/exit" = {
+ tooltip = false;
+ format = "⏻";
+ on-click = "sleep 0.1 && wlogout";
+ };
+ "custom/startmenu" = {
+ tooltip = false;
+ format = " ";
+ # exec = "rofi -show drun";
+ on-click = "rofi -show drun";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = " ";
+ deactivated = " ";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "swaync-client -t";
+ escape = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = ["" "" "" "" "" "" "" "" "" ""];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-size: 16pt;
+ font-family: JetBrainsMono Nerd Font, Font Awesome, sans-serif;
+ font-weight: bold;
+ }
+ window#waybar {
+ /*
+
+ background-color: rgba(26,27,38,0);
+ border-bottom: 1px solid rgba(26,27,38,0);
+ border-radius: 0px;
+ color: #${base0F};
+ */
+
+ background-color: rgba(26,27,38,0);
+ border-bottom: 1px solid rgba(26,27,38,0);
+ border-radius: 0px;
+ color: #${base0F};
+ }
+ #workspaces {
+ /*
+ Eternal
+ background: linear-gradient(180deg, #${base00}, #${base01});
+ margin: 5px 5px 5px 0px;
+ padding: 0px 10px;
+ border-radius: 0px 15px 15px 0px;
+ border: 0px;
+ font-style: normal;
+ color: #${base00};
+ */
+ background: linear-gradient(45deg, #${base01}, #${base01});
+ margin: 5px;
+ padding: 0px 1px;
+ border-radius: 15px;
+ border: 0px;
+ font-style: normal;
+ color: #${base00};
+ }
+ #workspaces button {
+ padding: 0px 5px;
+ margin: 4px 3px;
+ border-radius: 15px;
+ border: 0px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 0.5;
+ transition: all 0.3s ease-in-out;
+ }
+ #workspaces button.active {
+ padding: 0px 5px;
+ margin: 4px 3px;
+ border-radius: 15px;
+ border: 0px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 1.0;
+ min-width: 40px;
+ transition: all 0.3s ease-in-out;
+ }
+ #workspaces button:hover {
+ border-radius: 15px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 0.8;
+ }
+ tooltip {
+ background: #${base00};
+ border: 1px solid #${base0E};
+ border-radius: 10px;
+ }
+ tooltip label {
+ color: #${base07};
+ }
+ #window {
+ /*
+ Eternal
+ color: #${base05};
+ background: #${base00};
+ border-radius: 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ margin: 5px;
+ padding: 2px 20px;
+ color: #${base05};
+ background: #${base01};
+ border-radius: 15px 15px 15px 15px;
+ }
+ #memory {
+ color: #${base0F};
+ /*
+ Eternal
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ background: #${base01};
+ margin: 5px;
+ padding: 2px 20px;
+ border-radius: 15px 15px 15px 15px;
+ }
+ #clock {
+ color: #${base0B};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #idle_inhibitor {
+ color: #${base0A};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 3px;
+ padding: 2px 20px;
+ }
+ #cpu {
+ color: #${base07};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #disk {
+ color: #${base0F};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #battery {
+ color: #${base08};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #network {
+ color: #${base09};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #tray {
+ color: #${base05};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 15px;
+ }
+ #pulseaudio {
+ color: #${base0D};
+ /*
+ Eternal
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ background: #${base01};
+ margin: 4px;
+ padding: 2px 20px;
+ border-radius: 15px 15px 15px 15px;
+ }
+ #custom-notification {
+ color: #${base0C};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #custom-startmenu {
+ color: #${base0E};
+ background: #${base00};
+ border-radius: 0px 15px 15px 0px;
+ margin: 5px 5px 5px 0px;
+ padding: 2px 20px;
+ }
+ #idle_inhibitor {
+ color: #${base09};
+ background: #${base00};
+ border-radius: 15px 15px 15px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #custom-exit {
+ color: #${base0E};
+ background: #${base00};
+ border-radius: 15px 0px 0px 15px;
+ margin: 5px 0px 5px 5px;
+ padding: 2px 20px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-ddubs.nix b/home-manager/programs/hypr/waybar/waybar-ddubs.nix
new file mode 100644
index 0000000..46f74fd
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-ddubs.nix
@@ -0,0 +1,283 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ betterTransition = "all 0.3s cubic-bezier(.55,-0.68,.48,1.682)";
+ clock24h = false;
+in
+ with lib; {
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ modules-center = ["hyprland/workspaces"];
+ modules-left = [
+ "custom/startmenu"
+ "hyprland/window"
+ "pulseaudio"
+ "cpu"
+ "memory"
+ "idle_inhibitor"
+ ];
+ modules-right = [
+ "custom/hyprbindings"
+ "custom/notification"
+ "custom/exit"
+ "battery"
+ "tray"
+ "clock"
+ ];
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format =
+ if clock24h == true
+ then '' {:L%H:%M}''
+ else '' {:L%I:%M %p}'';
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }\n{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 22;
+ separate-outputs = false;
+ rewrite = {
+ "" = " 🙈 No Windows? ";
+ };
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ };
+ "network" = {
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ format-ethernet = " {bandwidthDownOctets}";
+ format-wifi = "{icon} {signalStrength}%";
+ format-disconnected = "";
+ tooltip = false;
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ on-click = "sleep 0.1 && pavucontrol";
+ };
+ "custom/exit" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && wlogout";
+ };
+ "custom/startmenu" = {
+ tooltip = false;
+ format = "";
+ # exec = "rofi -show drun";
+ #on-click = "sleep 0.1 && rofi-launcher";
+ on-click = "sleep 0.1 && nwg-drawer -mb 200 -mt 200 -mr 200 -ml 200";
+ };
+ "custom/hyprbindings" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && list-keybinds";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = "";
+ deactivated = "";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "sleep 0.1 && task-waybar";
+ escape = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-family: JetBrainsMono Nerd Font Mono;
+ font-size: 18px;
+ border-radius: 0px;
+ border: none;
+ min-height: 0px;
+ }
+ window#waybar {
+ background: rgba(0,0,0,0);
+ }
+ #workspaces {
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base01};
+ margin: 4px 4px;
+ padding: 5px 5px;
+ border-radius: 16px;
+ }
+ #workspaces button {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ opacity: 0.5;
+ transition: ${betterTransition};
+ }
+ #workspaces button.active {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ transition: ${betterTransition};
+ opacity: 1.0;
+ min-width: 40px;
+ }
+ #workspaces button:hover {
+ font-weight: bold;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ opacity: 0.8;
+ transition: ${betterTransition};
+ }
+ tooltip {
+ background: #${config.lib.stylix.colors.base00};
+ border: 1px solid #${config.lib.stylix.colors.base08};
+ border-radius: 12px;
+ }
+ tooltip label {
+ color: #${config.lib.stylix.colors.base08};
+ }
+ #window, #pulseaudio, #cpu, #memory, #idle_inhibitor {
+ font-weight: bold;
+ margin: 4px 0px;
+ margin-left: 7px;
+ padding: 0px 18px;
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base08};
+ border-radius: 8px 8px 8px 8px;
+ }
+ #idle_inhibitor {
+ font-size: 28px;
+ }
+ #custom-startmenu {
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base02};
+ font-size: 22px;
+ margin: 0px;
+ padding: 0px 5px 0px 5px;
+ border-radius: 16px 16px 16px 16px;
+ }
+ #custom-hyprbindings, #network, #battery,
+ #custom-notification, #tray, #custom-exit {
+ /* font-weight: bold; */
+ font-size: 20px;
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base08};
+ margin: 4px 0px;
+ margin-right: 7px;
+ border-radius: 8px 8px 8px 8px;
+ padding: 0px 18px;
+ }
+ #clock {
+ font-weight: bold;
+ font-size: 16px;
+ color: #0D0E15;
+ background: linear-gradient(90deg, #${config.lib.stylix.colors.base0B}, #${config.lib.stylix.colors.base02});
+ margin: 0px;
+ padding: 0px 5px 0px 5px;
+ border-radius: 16px 16px 16px 16px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-ddubsos-v1.nix b/home-manager/programs/hypr/waybar/waybar-ddubsos-v1.nix
new file mode 100644
index 0000000..510548f
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-ddubsos-v1.nix
@@ -0,0 +1,295 @@
+{
+ pkgs,
+ config,
+ lib,
+ host,
+ ...
+}: let
+ betterTransition = "all 0.3s cubic-bezier(.55,-0.68,.48,1.682)";
+ clock24h = false;
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in
+ with lib; {
+ home.file = builtins.listToAttrs (map
+ (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts);
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+
+ modules-center = ["hyprland/workspaces" "custom/weather"];
+ modules-left = ["custom/startmenu" "clock" "hyprland/window" "custom/sep_left" "custom/cava_mviz" "custom/sep_right"];
+ modules-right = [
+ "pulseaudio"
+ "cpu"
+ "memory"
+ "custom/notification"
+ "idle_inhibitor"
+ "custom/themeselector"
+ "battery"
+ "tray"
+ "custom/power"
+ ];
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format =
+ if clock24h == true
+ then " {:L%H:%M}"
+ else " {:L%I:%M %p}";
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 25;
+ separate-outputs = false;
+ rewrite = {
+ "" = " 🙈 No Windows? ";
+ };
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ };
+ "network" = {
+ format-icons = ["" "" "" "" ""];
+ format-ethernet = " {bandwidthDownOctets}";
+ format-wifi = "{icon} {signalStrength}%";
+ format-disconnected = "";
+ tooltip = false;
+ };
+ "tray" = {spacing = 12;};
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ on-click = "sleep 0.1 && pavucontrol";
+ };
+ "custom/cava_mviz" = {
+ "exec" = "WaybarCava";
+ "format" = "{}";
+ };
+ "custom/sep_left" = {
+ format = " [";
+ tooltip = false;
+ };
+ "custom/sep_right" = {
+ format = "] ";
+ tooltip = false;
+ };
+ "custom/themeselector" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && theme-selector";
+ };
+ "custom/power" = {
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ format = " ⏻ ";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ };
+ "custom/startmenu" = {
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ format = "";
+ # on-click = "rofi -show drun";
+ on-click = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+ "custom/hyprbindings" = {
+ tooltip = false;
+ format = " Bindings";
+ on-click = "sleep 0.1 && list-keybinds";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = " ";
+ deactivated = " ";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "sleep 0.1 && task-waybar";
+ escape = true;
+ };
+ "custom/weather" = {
+ return-type = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = ["" "" "" "" "" "" "" "" "" ""];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-family: JetBrainsMono Nerd Font Mono;
+ font-size: 18px;
+ border-radius: 0px;
+ border: none;
+ min-height: 0px;
+ }
+ window#waybar {
+ background: rgba(0,0,0,0);
+ }
+ #workspaces {
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base01};
+ margin: 4px 4px;
+ padding: 5px 5px;
+ border-radius: 16px;
+ }
+ #workspaces button {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ opacity: 0.5;
+ transition: ${betterTransition};
+ }
+ #workspaces button.active {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ transition: ${betterTransition};
+ opacity: 1.0;
+ min-width: 40px;
+ }
+ #workspaces button:hover {
+ font-weight: bold;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base00};
+ background: linear-gradient(45deg, #${config.lib.stylix.colors.base08}, #${config.lib.stylix.colors.base0D});
+ opacity: 0.8;
+ transition: ${betterTransition};
+ }
+ tooltip {
+ background: #${config.lib.stylix.colors.base00};
+ border: 1px solid #${config.lib.stylix.colors.base08};
+ border-radius: 12px;
+ }
+ tooltip label {
+ color: #${config.lib.stylix.colors.base08};
+ }
+ #window, #pulseaudio, #cpu, #memory, #idle_inhibitor {
+ font-weight: bold;
+ margin: 4px 0px;
+ margin-left: 7px;
+ padding: 0px 18px;
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base08};
+ border-radius: 8px 8px 8px 8px;
+ }
+ #idle_inhibitor {
+ font-size: 28px;
+ }
+ #custom-startmenu {
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base02};
+ font-size: 22px;
+ margin: 0px;
+ padding: 0px 5px 0px 5px;
+ border-radius: 16px 16px 16px 16px;
+ }
+ #custom-hyprbindings, #network, #battery,
+ #custom-notification, #tray, #custom-power {
+ /* font-weight: bold; */
+ font-size: 20px;
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base08};
+ margin: 4px 0px;
+ margin-right: 7px;
+ border-radius: 8px 8px 8px 8px;
+ padding: 0px 18px;
+ }
+ #clock {
+ font-weight: bold;
+ font-size: 16px;
+ color: #0D0E15;
+ background: linear-gradient(90deg, #${config.lib.stylix.colors.base0B}, #${config.lib.stylix.colors.base02});
+ margin: 0px;
+ padding: 0px 5px 0px 5px;
+ border-radius: 16px 16px 16px 16px;
+ }
+
+ } ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-dwm-2.nix b/home-manager/programs/hypr/waybar/waybar-dwm-2.nix
new file mode 100644
index 0000000..2ec4d4e
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-dwm-2.nix
@@ -0,0 +1,479 @@
+{
+ config,
+ pkgs,
+ ...
+}: {
+ home.packages = with pkgs; [waybar];
+
+ programs.waybar = {
+ enable = true;
+ settings = {
+ mainBar = {
+ layer = "top";
+ "modules-left" = ["hyprland/workspaces" "temperature" "hyprland/window"];
+ "modules-center" = ["custom/spacer"];
+ "modules-right" = ["tray" "cpu" "memory" "idle_inhibitor" "clock" "pulseaudio" "bluetooth"];
+ "hyprland/window" = {
+ format = "{title}";
+ "max-length" = 333;
+ "seperate-outputs" = true;
+ };
+ clock = {
+ format = " {:%I:%M %a %d}";
+ "tooltip-format" = "{calendar}";
+ calendar = {
+ mode = "month";
+ "mode-mon-col" = 3;
+ "on-scroll" = 1;
+ "on-click-right" = "mode";
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "{%W}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ "on-click-middle" = "mode";
+ "on-click-right" = "shift_up";
+ "on-click" = "shift_down";
+ };
+ };
+ cpu = {
+ format = " {usage}%";
+ };
+ memory = {
+ format = " {}%";
+ interval = 1;
+ };
+ "custom/gpu-util" = {
+ exec = "./scripts/gpu-util";
+ format = " {}";
+ interval = 1;
+ };
+ "custom/gpu-temp" = {
+ exec = "./scripts/gpu-temp";
+ format = " {}";
+ interval = 1;
+ };
+ temperature = {
+ "hwmon-path" = "/sys/class/hwmon/hwmon1/temp1_input";
+ "critical-threshold" = 80;
+ format = " {temperatureC}°C";
+ interval = 1;
+ };
+ "hyprland/workspaces" = {
+ format = "{icon}";
+ "active-only" = false;
+ "sort-by-number" = false;
+ "on-click" = "activate";
+ "all-outputs" = false;
+ "format-icons" = {
+ "1" = "1";
+ "2" = "2";
+ "3" = "3";
+ "4" = "4";
+ "5" = "5";
+ "6" = "6";
+ "7" = "7";
+ "8" = "8";
+ "9" = "9";
+ "10" = "10";
+ };
+ };
+ network = {
+ format = " Off";
+ "format-wifi" = "{essid} ({signalStrength}%)";
+ "format-ethernet" = "";
+ "format-disconnected" = " Disconnected";
+ "tooltip-format" = "{ifname} via {gwaddr} ";
+ "tooltip-format-wifi" = "{essid}({signalStrength}%) ";
+ "tooltip-format-ethernet" = " {ifname}";
+ "tooltip-format-disconnected" = "Disconnected";
+ };
+ pulseaudio = {
+ format = "{icon} {volume}% {format_source}";
+ "format-bluetooth" = "{icon} {volume}% {format_source}";
+ "format-bluetooth-muted" = " {format_source}";
+ "format-muted" = " {format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ phone = "";
+ portable = "";
+ default = ["" "" ""];
+ };
+ "on-click-left" = "pavucontrol";
+ input = true;
+ };
+ "custom/playerctl" = {
+ format = "{icon} {}";
+ "return-type" = "json";
+ "max-length" = 333;
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} ~ {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "format-icons" = {
+ Playing = "";
+ Paused = "";
+ };
+ };
+ tray = {
+ format = "{icon}";
+ "icon-size" = 14;
+ spacing = 5;
+ };
+ idle_inhibitor = {
+ format = "{icon}";
+ "format-icons" = {
+ activated = "";
+ deactivated = "";
+ };
+ };
+ "custom/subs" = {
+ format = " {}";
+ exec = "/usr/local/bin/subsfile.sh";
+ "on-click" = "vivaldi-stable https://youtube.com/thelinuxcast";
+ "restart-interval" = 1;
+ };
+ "custom/spacer" = {
+ format = " ";
+ };
+ "wlr/taskbar" = {
+ format = "{name}";
+ "icon-size" = 14;
+ "icon-theme" = "Numix-Circle";
+ "tooltip-format" = "{title}";
+ "on-click" = "activate";
+ "on-click-middle" = "close";
+ "ignore-list" = ["Alacritty"];
+ "app_ids-mapping" = {
+ firefoxdeveloperedition = "firefox-developer-edition";
+ };
+ rewrite = {
+ "Firefox Web Browser" = "Firefox";
+ "Foot Server" = "Terminal";
+ };
+ };
+ bluetooth = {
+ "on-click" = "./scripts/bluetooth-control";
+ "on-click-right" = "./scripts/rofi-bluetooth";
+ "on-click-middle" = "./scripts/rofi-bluetooth";
+ format = "{icon}";
+ interval = 15;
+ "format-icons" = {
+ on = "";
+ off = "";
+ disabled = "";
+ connected = "";
+ };
+ "tooltip-format" = "{device_alias} {status}";
+ };
+ };
+ };
+ style = ''
+ @define-color background #${config.stylix.base16Scheme.base00};
+ @define-color foreground #${config.stylix.base16Scheme.base05};
+ @define-color border #${config.stylix.base16Scheme.base02};
+ @define-color color1 #${config.stylix.base16Scheme.base01};
+ @define-color color2 #${config.stylix.base16Scheme.base02};
+ @define-color color3 #${config.stylix.base16Scheme.base03};
+ @define-color color4 #${config.stylix.base16Scheme.base04};
+ @define-color color5 #${config.stylix.base16Scheme.base05};
+ @define-color color6 #${config.stylix.base16Scheme.base06};
+ @define-color color7 #${config.stylix.base16Scheme.base07};
+ @define-color color8 #${config.stylix.base16Scheme.base08};
+ @define-color color9 #${config.stylix.base16Scheme.base09};
+ @define-color color10 #${config.stylix.base16Scheme.base0A};
+ @define-color color11 #${config.stylix.base16Scheme.base0B};
+ @define-color color12 #${config.stylix.base16Scheme.base0C};
+ @define-color color13 #${config.stylix.base16Scheme.base0D};
+ @define-color color14 #${config.stylix.base16Scheme.base0E};
+ @define-color color15 #${config.stylix.base16Scheme.base0F};
+
+ * {
+ min-height: 0;
+ margin: 0;
+ padding: 0;
+ font-family: "JetBrains Mono Nerd Font";
+ font-size: 14pt;
+ font-weight: 700;
+ padding-bottom: 0px;
+ }
+
+ tooltip {
+ background: @background;
+ border: 2px solid @border;
+ }
+
+ #window {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 7px;
+ background-color: @color14;
+ color: #282828;
+ }
+
+ window#waybar.empty #window {
+ background-color: transparent;
+ border-bottom: none;
+ border-right: none;
+ }
+
+ window#waybar {
+ background-color:@color14;
+ color: @color2;
+ }
+
+ /* Workspaces */
+
+ #workspaces {
+ margin: 0px 0px 0px 0px;
+ padding: 0px;
+ background-color: @background;
+ color: @color7;
+ }
+
+ #workspaces button {
+ margin: 0px 0px 0px 0px;
+ padding-left: 3px;
+ padding-right: 9px;
+ background-color: @background;
+ color: @color7;
+ }
+
+ #workspaces button.active {
+ padding: 0 2px 0 1px;
+ color: @color3;
+ }
+
+ #workspaces button.urgent {
+ color: @color9;
+ }
+
+ #custom-gpu-util {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @background;
+ color: @foreground;
+ }
+
+ #tray {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @background;
+ color: @foreground;
+ }
+
+ #idle_inhibitor {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 12px;
+ background-color: @background;
+ color: @foreground;
+ }
+
+ #idle_inhibitor.activated {
+ color: @color9;
+ }
+
+ #network {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 12px;
+ background-color: @background;
+ color: @color11;
+ }
+
+ #network.linked {
+ color: @color6;
+ }
+ #network.disconnected,
+ #network.disabled {
+ color: @color4;
+ }
+
+ #custom-subs {
+ color: @foreground;
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ border-bottom: 2px solid @background;
+ border-right: 2px solid @background;
+ border-color: @color8;
+ background-color: @color13;
+ }
+
+ #custom-cliphist {
+ color: @color14;
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ background-color: @background;
+ }
+
+ #custom-gpu-temp,
+ #custom-clipboard {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #cpu {
+ margin: 0px 0px 0px 0px;
+ padding-left: 6px;
+ padding-right: 6px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #custom-cpuicon {
+ margin: 0px 0px 0px 0px;
+ padding: 0px 10px 0px 10px;
+ color: @color14;
+ background-color: @background;
+ }
+
+ #custom-diskicon {
+ margin: 0px 0px 0px 0;
+ padding: 0 10px 0 10px;
+ color: @color2;
+ background-color: @background;
+ }
+
+ #disk {
+ margin: 0px 0px 0px 0;
+ padding-left: 0px;
+ padding-right: 0px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #custom-notification {
+ background-color: @background;
+ color: @color15;
+ padding: 0 12px;
+ margin-right: 0px;
+ font-size: 14px;
+ font-family: "JetBrainsMono Nerd Font";
+ }
+
+ #custom-memoryicon {
+ margin: 0px 0px 0px 0px;
+ color: @color4;
+ padding: 0 11px 0 7px;
+ background-color: @background;
+ }
+
+ #memory {
+ margin: 0px 0px 0px 0px;
+ padding-left: 5px;
+ padding-right: 10px;
+ color: @color4;
+ background-color: @background;
+ }
+
+ #custom-tempicon {
+ margin: 0px 0px 0px 0px;
+ color: @color10;
+ padding: 0 11px 0 8px;
+ background-color: @background;
+ }
+
+ #temperature {
+ margin: 0px 0px 0px 0px;
+ padding-left: 5px;
+ padding-right: 10px;
+ color: @color10;
+ background-color: @background;
+ }
+
+ #custom-playerctl {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #battery,
+ #backlight,
+ #bluetooth,
+ #pulseaudio {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #pulseaudio {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ color: @color15;
+ background-color: @background;
+ }
+
+ #battery,
+ #bluetooth {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 0px;
+ padding-right: 2px;
+ }
+
+ #backlight,
+ #pulseaudio {
+ margin-right: 0px;
+ margin-left: 0px;
+ padding-left: 10px;
+ padding-right: 7.5px;
+ }
+
+ #clock {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ color: @color6;
+ background-color: @background;
+ }
+
+ #custom-clockicon {
+ margin: 0px 0 0px 0px;
+ color: @color6;
+ padding: 0 5px 0 10px;
+ background-color: @background;
+ }
+
+ #taskbar {
+ padding: 0 3px;
+ margin: 0 0px;
+ color: #ffffff;
+ background-color: rgba(120,118,117,0.3);
+ }
+ #taskbar button {
+ padding: 0 0 0 3px;
+ margin: 0px 0px;
+ color: #ffffff;
+ background-color: rgba(120,118,117,0.1);
+ }
+ #taskbar button.active {
+ background-color: rgba(120,118,117,0.8);
+ }
+
+ #mode {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @background;
+ color: @color9;
+ }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-dwm.nix b/home-manager/programs/hypr/waybar/waybar-dwm.nix
new file mode 100644
index 0000000..5eb4d1b
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-dwm.nix
@@ -0,0 +1,429 @@
+{
+ config,
+ pkgs,
+ ...
+}: {
+ home.packages = with pkgs; [waybar];
+
+ programs.waybar = {
+ enable = true;
+ settings = {
+ mainBar = {
+ layer = "top";
+ "modules-left" = ["hyprland/workspaces" "hyprland/window"];
+ "modules-center" = ["clock"];
+ "modules-right" = ["tray" "cpu" "memory" "idle_inhibitor" "pulseaudio" "bluetooth"];
+ "hyprland/window" = {
+ format = "{title}";
+ "max-length" = 333;
+ "seperate-outputs" = true;
+ };
+ clock = {
+ format = " {:%I:%M %a %d}";
+ "tooltip-format" = "{calendar}";
+ calendar = {
+ mode = "month";
+ "mode-mon-col" = 3;
+ "on-scroll" = 1;
+ "on-click-right" = "mode";
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "{%W}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ "on-click-middle" = "mode";
+ "on-click-right" = "shift_up";
+ "on-click" = "shift_down";
+ };
+ };
+ cpu = {
+ format = " {usage}%";
+ };
+ memory = {
+ format = " {}%";
+ interval = 1;
+ };
+ "custom/gpu-util" = {
+ exec = "./scripts/gpu-util";
+ format = " {}";
+ interval = 1;
+ };
+ "custom/gpu-temp" = {
+ exec = "./scripts/gpu-temp";
+ format = " {}";
+ interval = 1;
+ };
+ temperature = {
+ "hwmon-path" = "/sys/class/hwmon/hwmon1/temp1_input";
+ "critical-threshold" = 80;
+ format = " {temperatureC}°C";
+ interval = 1;
+ };
+ "hyprland/workspaces" = {
+ format = "{icon}";
+ "active-only" = false;
+ "sort-by-number" = true;
+ "on-click" = "activate";
+ "all-outputs" = false;
+ "format-icons" = {
+ "1" = "1";
+ "2" = "2";
+ "3" = "3";
+ "4" = "4";
+ "5" = "5";
+ "6" = "6";
+ "7" = "7";
+ "8" = "8";
+ "9" = "9";
+ "10" = "10";
+ };
+ };
+ network = {
+ format = " Off";
+ "format-wifi" = "{essid} ({signalStrength}%)";
+ "format-ethernet" = "";
+ "format-disconnected" = " Disconnected";
+ "tooltip-format" = "{ifname} via {gwaddr} ";
+ "tooltip-format-wifi" = "{essid}({signalStrength}%) ";
+ "tooltip-format-ethernet" = " {ifname}";
+ "tooltip-format-disconnected" = "Disconnected";
+ };
+ pulseaudio = {
+ format = "{icon} {volume}% {format_source}";
+ "format-bluetooth" = "{icon} {volume}% {format_source}";
+ "format-bluetooth-muted" = " {format_source}";
+ "format-muted" = " {format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ phone = "";
+ portable = "";
+ default = ["" "" ""];
+ };
+ "on-click-left" = "pavucontrol";
+ input = true;
+ };
+ "custom/playerctl" = {
+ format = "{icon} {}";
+ "return-type" = "json";
+ "max-length" = 333;
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} ~ {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "format-icons" = {
+ Playing = "";
+ Paused = "";
+ };
+ };
+ tray = {
+ format = "{icon}";
+ "icon-size" = 14;
+ spacing = 5;
+ };
+ idle_inhibitor = {
+ format = "{icon}";
+ "format-icons" = {
+ activated = "";
+ deactivated = "";
+ };
+ };
+ "custom/subs" = {
+ format = " {}";
+ exec = "/usr/local/bin/subsfile.sh";
+ "on-click" = "vivaldi-stable https://youtube.com/thelinuxcast";
+ "restart-interval" = 1;
+ };
+ "custom/spacer" = {
+ format = " ";
+ };
+ "wlr/taskbar" = {
+ format = "{name}";
+ "icon-size" = 14;
+ "icon-theme" = "Numix-Circle";
+ "tooltip-format" = "{title}";
+ "on-click" = "activate";
+ "on-click-middle" = "close";
+ "ignore-list" = ["Alacritty"];
+ "app_ids-mapping" = {
+ firefoxdeveloperedition = "firefox-developer-edition";
+ };
+ rewrite = {
+ "Firefox Web Browser" = "Firefox";
+ "Foot Server" = "Terminal";
+ };
+ };
+ bluetooth = {
+ "on-click" = "./scripts/bluetooth-control";
+ "on-click-right" = "./scripts/rofi-bluetooth";
+ "on-click-middle" = "./scripts/rofi-bluetooth";
+ format = "{icon}";
+ interval = 15;
+ "format-icons" = {
+ on = "";
+ off = "";
+ disabled = "";
+ connected = "";
+ };
+ "tooltip-format" = "{device_alias} {status}";
+ };
+ };
+ };
+ style = ''
+ @define-color bg #${config.stylix.base16Scheme.base00};
+ @define-color fg #${config.stylix.base16Scheme.base05};
+ @define-color lbg #${config.stylix.base16Scheme.base01};
+ @define-color yellow #${config.stylix.base16Scheme.base0A};
+ @define-color lavender #${config.stylix.base16Scheme.base0E};
+ @define-color peach #${config.stylix.base16Scheme.base0A};
+ @define-color red #${config.stylix.base16Scheme.base08};
+ @define-color green #${config.stylix.base16Scheme.base0B};
+ @define-color blue #${config.stylix.base16Scheme.base0D};
+ @define-color border #${config.stylix.base16Scheme.base02};
+
+ * {
+ min-height: 0;
+ margin: 0px 0px 0px 0px;
+ padding: 0;
+ border-radius: 7px;
+ font-family: "JetBrains Mono Nerd Font";
+ font-size: 14pt;
+ font-weight: 700;
+ padding-bottom: 0px;
+ }
+
+ tooltip {
+ background: @bg;
+ border-radius: 7px;
+ border: 2px solid @border;
+ }
+
+ #window {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 7px;
+ border-radius: 3px;
+ border-color: @lbg;
+ background-color: @yellow;
+ color: @bg;
+ }
+
+ window#waybar.empty #window {
+ background-color: @bg;
+ border-bottom: none;
+ border-right: none;
+ }
+
+ window#waybar {
+ background-color: @bg;
+ color: @lavender;
+ }
+
+ /* Workspaces */
+ @keyframes button_activate {
+ from { opacity: .3 }
+ to { opacity: 1.; }
+ }
+
+ #workspaces {
+ margin: 0px 0px 0px 0px;
+ border-radius: 3px;
+ padding: 1px;
+ background-color: @bg;
+ color: @bg;
+ }
+
+ #workspaces button {
+ margin: 0px 0px 0px 0px;
+ border-radius: 3px;
+ padding-left: 3px;
+ padding-right: 9px;
+ background-color: @bg;
+ color: @fg;
+ }
+
+ #workspaces button.active {
+ background-color:@blue;
+ color: @bg;
+ }
+
+ #workspaces button.urgent {
+ color: #F38BA8;
+ }
+
+ #workspaces button:hover {
+ border: solid transparent;
+ }
+
+ #custom-gpu-util {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-radius: 7px;
+ background-color: @bg;
+ color: @fg;
+ }
+
+ #tray {
+ margin: 0px 0px 0px 0px;
+ border-radius: 3px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @bg;
+ color: @fg;
+ }
+
+ #idle_inhibitor {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 12px;
+ border-radius: 3px;
+ background-color: @bg;
+ color: @fg;
+ }
+
+ #network {
+ margin: 5px 5px 2px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ border-radius: 7px;
+ background-color: @bg;
+ color: @lavender;
+ }
+
+ #network.linked {
+ color: @peach;
+ }
+ #network.disconnected,
+ #network.disabled {
+ color: @red;
+ }
+
+ #custom-subs {
+ color: @fg;
+ margin: 5px 5px 2px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ border-radius: 3px;
+ border-bottom: 2px solid @bg;
+ border-right: 2px solid @bg;
+ border-color: @lbg;
+ background-color: @red;
+ }
+
+ #custom-spacer {
+ background-color: @yellow;
+ }
+
+ #custom-cliphist {
+ color: @peach;
+ margin: 5px 5px 2px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ border-radius: 3px;
+ background-color: @bg;
+ }
+
+ #custom-gpu-temp,
+ #cpu,
+ #memory,
+ #custom-clipboard,
+ #temperature {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-radius: 3px;
+ color: @fg;
+ background-color: @bg;
+ }
+
+ #custom-playerctl {
+ margin: 5px 5px 2px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-radius: 3px;
+ color: @fg;
+ background-color: @bg;
+ }
+
+ #battery,
+ #backlight,
+ #bluetooth,
+ #pulseaudio {
+ margin-top: 5px;
+ margin-bottom: 2px;
+ color: @fg;
+ background-color: @bg;
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+
+ #battery,
+ #bluetooth {
+ margin-left: 0px;
+ margin-right: 5px;
+ padding-left: 7.5px;
+ padding-right: 10px;
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ }
+
+ #backlight,
+ #pulseaudio {
+ margin-right: 0px;
+ margin-left: 5px;
+ padding-left: 10px;
+ padding-right: 7.5px;
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+
+ #clock {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-radius: 3px;
+ color: @bg;
+ background-color: @green;
+ }
+
+ #taskbar {
+ border-radius: 0px 0px 0px 0;
+ padding: 0 3px;
+ margin: 0 0px;
+ color: #ffffff;
+ background-color: rgba(120,118,117,0.3);
+ }
+ #taskbar button {
+ border-radius: 0px 0px 0px 0px;
+ padding: 0 0 0 3px;
+ margin: 3px 1;
+ color: #ffffff;
+ background-color: rgba(120,118,117,0.1);
+ }
+ #taskbar button.active {
+ background-color: rgba(120,118,117,0.8);
+ }
+
+ #mode {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-radius: 3px;
+ background-color: @bg;
+ color: @peach;
+ }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-dwm2.nix b/home-manager/programs/hypr/waybar/waybar-dwm2.nix
new file mode 100644
index 0000000..bd98a34
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-dwm2.nix
@@ -0,0 +1,532 @@
+{
+ config,
+ pkgs,
+ ...
+}: let
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in {
+ home.packages = with pkgs; [waybar];
+
+ home.file = builtins.listToAttrs (
+ map (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts
+ );
+
+ programs.waybar = {
+ enable = true;
+ settings = {
+ mainBar = {
+ layer = "top";
+ "modules-left" = [
+ "custom/startmenu"
+ "hyprland/workspaces"
+ "temperature"
+ "hyprland/window"
+ ];
+ "modules-center" = ["custom/spacer" "custom/weather"];
+ "modules-right" = [
+ "tray"
+ "cpu"
+ "memory"
+ "idle_inhibitor"
+ "clock"
+ "pulseaudio"
+ "bluetooth"
+ "custom/power"
+ ];
+ "hyprland/window" = {
+ format = "{title}";
+ "max-length" = 333;
+ "seperate-outputs" = true;
+ };
+ clock = {
+ format = " {:%I:%M %a %d}";
+ "tooltip-format" = "{calendar}";
+ calendar = {
+ mode = "month";
+ "mode-mon-col" = 3;
+ "on-scroll" = 1;
+ "on-click-right" = "mode";
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "{%W}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ "on-click-middle" = "mode";
+ "on-click-right" = "shift_up";
+ "on-click" = "shift_down";
+ };
+ };
+ cpu = {
+ format = " {usage}%";
+ };
+ memory = {
+ format = " {}%";
+ interval = 1;
+ };
+ "custom/gpu-util" = {
+ exec = "./scripts/gpu-util";
+ format = " {}";
+ interval = 1;
+ };
+ "custom/gpu-temp" = {
+ exec = "./scripts/gpu-temp";
+ format = " {}";
+ interval = 1;
+ };
+ temperature = {
+ "hwmon-path" = "/sys/class/hwmon/hwmon1/temp1_input";
+ "critical-threshold" = 80;
+ format = " {temperatureC}°C";
+ interval = 1;
+ };
+ "custom/startmenu" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ # "on-click" = "rofi -show drun";
+ "on-click" = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+ "hyprland/workspaces" = {
+ format = "{icon}";
+ "active-only" = false;
+ "sort-by-number" = false;
+ "on-click" = "activate";
+ "all-outputs" = false;
+ "format-icons" = {
+ "1" = "1";
+ "2" = "2";
+ "3" = "3";
+ "4" = "4";
+ "5" = "5";
+ "6" = "6";
+ "7" = "7";
+ "8" = "8";
+ "9" = "9";
+ "10" = "10";
+ };
+ };
+ network = {
+ format = " Off";
+ "format-wifi" = "{essid} ({signalStrength}%)";
+ "format-ethernet" = "";
+ "format-disconnected" = " Disconnected";
+ "tooltip-format" = "{ifname} via {gwaddr} ";
+ "tooltip-format-wifi" = "{essid}({signalStrength}%) ";
+ "tooltip-format-ethernet" = " {ifname}";
+ "tooltip-format-disconnected" = "Disconnected";
+ };
+ pulseaudio = {
+ format = "{icon} {volume}% {format_source}";
+ "format-bluetooth" = "{icon} {volume}% {format_source}";
+ "format-bluetooth-muted" = " {format_source}";
+ "format-muted" = " {format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ phone = "";
+ portable = "";
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ "on-click-left" = "pavucontrol";
+ input = true;
+ };
+ "custom/playerctl" = {
+ format = "{icon} {}";
+ "return-type" = "json";
+ "max-length" = 333;
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} ~ {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "format-icons" = {
+ Playing = "";
+ Paused = "";
+ };
+ };
+ "custom/weather" = {
+ "return-type" = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+ tray = {
+ format = "{icon}";
+ "icon-size" = 14;
+ spacing = 5;
+ };
+ idle_inhibitor = {
+ format = "{icon}";
+ "format-icons" = {
+ activated = " ";
+ deactivated = " ";
+ };
+ };
+ "custom/subs" = {
+ format = " {}";
+ exec = "/usr/local/bin/subsfile.sh";
+ "on-click" = "vivaldi-stable https://youtube.com/thelinuxcast";
+ "restart-interval" = 1;
+ };
+ "custom/spacer" = {
+ format = " ";
+ };
+ "wlr/taskbar" = {
+ format = "{name}";
+ "icon-size" = 14;
+ "icon-theme" = "Numix-Circle";
+ "tooltip-format" = "{title}";
+ "on-click" = "activate";
+ "on-click-middle" = "close";
+ "ignore-list" = ["Alacritty"];
+ "app_ids-mapping" = {
+ firefoxdeveloperedition = "firefox-developer-edition";
+ };
+ rewrite = {
+ "Firefox Web Browser" = "Firefox";
+ "Foot Server" = "Terminal";
+ };
+ };
+ bluetooth = {
+ "on-click" = "./scripts/bluetooth-control";
+ "on-click-right" = "./scripts/rofi-bluetooth";
+ "on-click-middle" = "./scripts/rofi-bluetooth";
+ format = "{icon}";
+ interval = 15;
+ "format-icons" = {
+ on = "";
+ off = "";
+ disabled = "";
+ connected = "";
+ };
+ "tooltip-format" = "{device_alias} {status}";
+ };
+ "custom/power" = {
+ format = " ⏻ ";
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ };
+ };
+ };
+ style = ''
+ @define-color background #${config.stylix.base16Scheme.base00};
+ @define-color foreground #${config.stylix.base16Scheme.base05};
+ @define-color border #${config.stylix.base16Scheme.base02};
+ @define-color color1 #${config.stylix.base16Scheme.base01};
+ @define-color color2 #${config.stylix.base16Scheme.base02};
+ @define-color color3 #${config.stylix.base16Scheme.base03};
+ @define-color color4 #${config.stylix.base16Scheme.base04};
+ @define-color color5 #${config.stylix.base16Scheme.base05};
+ @define-color color6 #${config.stylix.base16Scheme.base06};
+ @define-color color7 #${config.stylix.base16Scheme.base07};
+ @define-color color8 #${config.stylix.base16Scheme.base08};
+ @define-color color9 #${config.stylix.base16Scheme.base09};
+ @define-color color10 #${config.stylix.base16Scheme.base0A};
+ @define-color color11 #${config.stylix.base16Scheme.base0B};
+ @define-color color12 #${config.stylix.base16Scheme.base0C};
+ @define-color color13 #${config.stylix.base16Scheme.base0D};
+ @define-color color14 #${config.stylix.base16Scheme.base0E};
+ @define-color color15 #${config.stylix.base16Scheme.base0F};
+
+ * {
+ min-height: 0;
+ margin: 0;
+ padding: 0;
+ font-family: "JetBrains Mono Nerd Font";
+ font-size: 14pt;
+ font-weight: 700;
+ padding-bottom: 0px;
+ }
+
+ tooltip {
+ background: @background;
+ border: 2px solid @border;
+ }
+
+ #window {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 7px;
+ background-color: @color14;
+ color: #282828;
+ }
+
+ window#waybar.empty #window {
+ background-color: transparent;
+ border-bottom: none;
+ border-right: none;
+ }
+
+ window#waybar {
+ background-color:@color14;
+ color: @color2;
+ }
+
+ /* Workspaces */
+
+ #workspaces {
+ margin: 0px 0px 0px 0px;
+ padding: 0px;
+ background-color: @background;
+ color: @color7;
+ }
+
+ #workspaces button {
+ margin: 0px 0px 0px 0px;
+ padding-left: 3px;
+ padding-right: 9px;
+ background-color: @background;
+ color: @color7;
+ }
+
+ #workspaces button.active {
+ padding: 0 2px 0 1px;
+ color: @color3;
+ }
+
+ #workspaces button.urgent {
+ color: @color9;
+ }
+
+ #custom-gpu-util {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @background;
+ color: @foreground;
+ }
+
+ #tray {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @background;
+ color: @foreground;
+ }
+
+ #idle_inhibitor {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 12px;
+ background-color: @background;
+ color: @foreground;
+ }
+
+ #idle_inhibitor.activated {
+ color: @color9;
+ }
+
+ #network {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 12px;
+ background-color: @background;
+ color: @color11;
+ }
+
+ #network.linked {
+ color: @color6;
+ }
+ #network.disconnected,
+ #network.disabled {
+ color: @color4;
+ }
+
+ #custom-subs {
+ color: @foreground;
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ border-bottom: 2px solid @background;
+ border-right: 2px solid @background;
+ border-color: @color8;
+ background-color: @color13;
+ }
+
+ #custom-cliphist {
+ color: @color14;
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 12px;
+ background-color: @background;
+ }
+
+ #custom-gpu-temp,
+ #custom-clipboard {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #cpu {
+ margin: 0px 0px 0px 0px;
+ padding-left: 6px;
+ padding-right: 6px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #custom-cpuicon {
+ margin: 0px 0px 0px 0px;
+ padding: 0px 10px 0px 10px;
+ color: @color14;
+ background-color: @background;
+ }
+
+ #custom-diskicon {
+ margin: 0px 0px 0px 0;
+ padding: 0 10px 0 10px;
+ color: @color2;
+ background-color: @background;
+ }
+
+ #disk {
+ margin: 0px 0px 0px 0;
+ padding-left: 0px;
+ padding-right: 0px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #custom-notification {
+ background-color: @background;
+ color: @color15;
+ padding: 0 12px;
+ margin-right: 0px;
+ font-size: 14px;
+ font-family: "JetBrainsMono Nerd Font";
+ }
+
+ #custom-memoryicon {
+ margin: 0px 0px 0px 0px;
+ color: @color4;
+ padding: 0 11px 0 7px;
+ background-color: @background;
+ }
+
+ #memory {
+ margin: 0px 0px 0px 0px;
+ padding-left: 5px;
+ padding-right: 10px;
+ color: @color4;
+ background-color: @background;
+ }
+
+ #custom-tempicon {
+ margin: 0px 0px 0px 0px;
+ color: @color10;
+ padding: 0 11px 0 8px;
+ background-color: @background;
+ }
+
+ #temperature {
+ margin: 0px 0px 0px 0px;
+ padding-left: 5px;
+ padding-right: 10px;
+ color: @color10;
+ background-color: @background;
+ }
+
+ #custom-playerctl {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #battery,
+ #backlight,
+ #bluetooth,
+ #pulseaudio {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ color: @foreground;
+ background-color: @background;
+ }
+
+ #pulseaudio {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ color: @color15;
+ background-color: @background;
+ }
+
+ #battery,
+ #bluetooth {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 0px;
+ padding-right: 2px;
+ }
+
+ #backlight,
+ #pulseaudio {
+ margin-right: 0px;
+ margin-left: 0px;
+ padding-left: 10px;
+ padding-right: 7.5px;
+ }
+
+ #clock {
+ margin: 0px 0px 0px 0px;
+ padding-left: 10px;
+ padding-right: 10px;
+ color: @color6;
+ background-color: @background;
+ }
+
+ #custom-clockicon {
+ margin: 0px 0 0px 0px;
+ color: @color6;
+ padding: 0 5px 0 10px;
+ background-color: @background;
+ }
+
+ #taskbar {
+ padding: 0 3px;
+ margin: 0 0px;
+ color: #ffffff;
+ background-color: rgba(120,118,117,0.3);
+ }
+ #taskbar button {
+ padding: 0 0 0 3px;
+ margin: 0px 0px;
+ color: #ffffff;
+ background-color: rgba(120,118,117,0.1);
+ }
+ #taskbar button.active {
+ background-color: rgba(120,118,117,0.8);
+ }
+
+ #mode {
+ margin: 0px 5px 0px 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: @background;
+ color: @color9;
+ }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-jak-catppuccin.nix b/home-manager/programs/hypr/waybar/waybar-jak-catppuccin.nix
new file mode 100644
index 0000000..aaa5e29
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jak-catppuccin.nix
@@ -0,0 +1,959 @@
+{pkgs, ...}: let
+ # Install any helper scripts shipped in modules/home/waybar/scripts into ~/.config/waybar/scripts
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ # Inline, improved Cava script packaged via Nix so we don't rely on an external bash file
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+
+ # Ensure cava exists
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+
+ # Characters for vertical bars (0..7)
+ bar="▁▂▃▄▅▆▇█"
+
+ # Build sed script that:
+ # - strips semicolons (cava RAW ASCII delimiter)
+ # - maps digits 0..7 to the corresponding glyph in $bar
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+
+ # Single-instance guard (kill prior instance cleanly)
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ # Give the old pipeline a moment to exit
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+
+ # Use a unique temporary config and clean it up on exit
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() {
+ rm -f "$config_file" "$pidfile"
+ }
+ trap cleanup EXIT INT TERM
+
+ cat >"$config_file" <{calendar}";
+ calendar = {
+ mode = "year";
+ "mode-mon-col" = 3;
+ "weeks-pos" = "right";
+ "on-scroll" = 1;
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "W{:%V}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ "on-click-right" = "mode";
+ "on-click-forward" = "tz_up";
+ "on-click-backward" = "tz_down";
+ "on-scroll-up" = "shift_up";
+ "on-scroll-down" = "shift_down";
+ };
+ };
+
+ cpu = {
+ format = "{usage}% ";
+ interval = 1;
+ "min-length" = 5;
+ "format-alt-click" = "click";
+ "format-alt" = "{icon0}{icon1}{icon2}{icon3} {usage:>2}% ";
+ "format-icons" = [
+ "▁"
+ "▂"
+ "▃"
+ "▄"
+ "▅"
+ "▆"
+ "▇"
+ "█"
+ ];
+ "on-click-right" = "gnome-system-monitor";
+ };
+
+ disk = {
+ interval = 30;
+ path = "/";
+ format = "{percentage_used}% ";
+ "tooltip-format" = "{used} used out of {total} on {path} ({percentage_used}%)";
+ };
+
+ "hyprland/window" = {
+ format = "{}";
+ "max-length" = 25;
+ "separate-outputs" = true;
+ "offscreen-css" = true;
+ "offscreen-css-text" = "(inactive)";
+ rewrite = {
+ "(.*) — Mozilla Firefox" = " $1";
+ "(.*) - fish" = "> [$1]";
+ "(.*) - zsh" = "> [$1]";
+ };
+ };
+
+ idle_inhibitor = {
+ tooltip = true;
+ "tooltip-format-activated" = "Idle_inhibitor active";
+ "tooltip-format-deactivated" = "Idle_inhibitor not active";
+ format = "{icon}";
+ # Requested change: coffee mug icon for both states
+ "format-icons" = {
+ activated = " ";
+ deactivated = " ";
+ };
+ };
+
+ "keyboard-state" = {
+ capslock = true;
+ format = {
+ numlock = "N {icon}";
+ capslock = " {icon}";
+ };
+ "format-icons" = {
+ locked = "";
+ unlocked = "";
+ };
+ };
+
+ memory = {
+ interval = 10;
+ format = "{used:0.1f}G ";
+ "format-alt" = "{percentage}% ";
+ "format-alt-click" = "click";
+ tooltip = true;
+ "tooltip-format" = "{used:0.1f}GB/{total:0.1f}G";
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --btop";
+ };
+
+ network = {
+ format = "{ifname}";
+ "format-wifi" = "{icon}";
+ "format-ethernet" = "";
+ "format-disconnected" = "";
+ "tooltip-format" = "{ipaddr} {bandwidthUpBits} {bandwidthDownBits}";
+ "format-linked" = " {ifname} (No IP)";
+ "tooltip-format-wifi" = "{essid} {icon} {signalStrength}%";
+ "tooltip-format-ethernet" = "{ifname} ";
+ "tooltip-format-disconnected" = " Disconnected";
+ "max-length" = 30;
+ "format-icons" = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --nmtui";
+ };
+
+ "network#speed" = {
+ interval = 1;
+ format = "{ifname}";
+ "format-wifi" = "{icon} {bandwidthUpBytes} {bandwidthDownBytes}";
+ "format-ethernet" = " {bandwidthUpBytes} {bandwidthDownBytes}";
+ "format-disconnected" = "";
+ "tooltip-format" = "{ipaddr}";
+ "format-linked" = " {ifname} (No IP)";
+ "tooltip-format-wifi" = "{essid} {icon} {signalStrength}%";
+ "tooltip-format-ethernet" = "{ifname} ";
+ "tooltip-format-disconnected" = " Disconnected";
+ "min-length" = 24;
+ "max-length" = 24;
+ "format-icons" = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+
+ "power-profiles-daemon" = {
+ format = "{icon} ";
+ "tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
+ tooltip = true;
+ "format-icons" = {
+ default = "";
+ performance = "";
+ balanced = "";
+ "power-saver" = "";
+ };
+ };
+
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ "format-bluetooth" = "{icon} {volume}%";
+ "format-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ "hands-free" = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ""
+ ];
+ "ignored-sinks" = ["Easy Effects Sink"];
+ };
+ "scroll-step" = 5.0;
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle";
+ "on-click-right" = "pavucontrol -t 3";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "tooltip-format" = "{icon} {desc} | {volume}%";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "pulseaudio#microphone" = {
+ format = "{format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic";
+ "on-click-right" = "pavucontrol -t 4";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --mic-inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --mic-dec";
+ "tooltip-format" = "{source_desc} | {source_volume}%";
+ "scroll-step" = 5;
+ };
+
+ tray = {
+ "icon-size" = 20;
+ spacing = 4;
+ };
+
+ # ---------- Workspaces variants (from ModulesWorkspaces) ----------
+ "hyprland/workspaces#rw" = {
+ "disable-scroll" = true;
+ "all-outputs" = true;
+ "warp-on-scroll" = false;
+ "sort-by-number" = true;
+ "show-special" = false;
+ "on-click" = "activate";
+ "on-scroll-up" = "hyprctl dispatch workspace e+1";
+ "on-scroll-down" = "hyprctl dispatch workspace e-1";
+ "persistent-workspaces" = {
+ "*" = 5;
+ };
+ format = "{icon} {windows}";
+ "format-window-separator" = " ";
+ "window-rewrite-default" = " ";
+ "window-rewrite" = {
+ "title<.*amazon.*>" = " ";
+ "title<.*reddit.*>" = " ";
+ "title<.*[Hh]elium.*>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = "🦁 ";
+ "class" = " ";
+ "class" = "🦊 ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class<[Tt]hunderbird|[Tt]hunderbird-esr>" = " ";
+ "class" = " ";
+ "title<.*gmail.*>" = " ";
+ "class<[Tt]elegram-desktop|org.telegram.desktop|io.github.tdesktop_x64.TDesktop>" = " ";
+ "class" = " ";
+ "title<.*whatsapp.*>" = " ";
+ "title<.*zapzap.*>" = " ";
+ "title<.*messenger.*>" = " ";
+ "title<.*facebook.*>" = " ";
+ "class<[Ss]ignal|signal-desktop|org.signal.Signal>" = " ";
+ "title<.*Signal.*>" = " ";
+ "title<.*ChatGPT.*>" = " ";
+ "title<.*deepseek.*>" = " ";
+ "title<.*qwen.*>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "title<.*Picture-in-Picture.*>" = " ";
+ "title<.*youtube.*>" = " ";
+ "class" = " ";
+ "class<[Kk]denlive|org.kde.kdenlive>" = "🎬 ";
+ "title<.*Kdenlive.*>" = "🎬 ";
+ "title<.*cmus.*>" = " ";
+ "class<[Ss]potify>" = " ";
+ "class" = " ";
+ "class<.virt-manager-wrapped>" = " ";
+ "class" = " ";
+ "class" = "💽 ";
+ "title" = "💽 ";
+ "class" = "🖥️ ";
+ "class" = " ";
+ "class" = "";
+ "class" = " ";
+ "title<.*github.*>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "title<.*nvim ~.*>" = " ";
+ "title<.*vim.*>" = " ";
+ "title<.*nvim.*>" = " ";
+ "title<.*Discord.*>" = " ";
+ "title<.*figma.*>" = " ";
+ "title<.*jira.*>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class<[Pp]avucontrol|org.pulseaudio.pavucontrol>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = "";
+ "class" = " ";
+ "class" = "📱 ";
+ "class" = " ";
+ "class" = "";
+ "class" = "";
+ "class" = "";
+
+ "class" = " ";
+ "title<^Bazaar$>" = " ";
+
+ "class" = " ";
+ "title<^satty$>" = " ";
+
+ "class<[Bb]ox[Bb]uddy|io.github.dvlv.boxbuddy|io.github.dvlv.BoxBuddy>" = " ";
+ "title<.*BoxBuddy.*>" = " ";
+
+ # qs-* apps
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title<^Wallpapers$>" = " ";
+ "title<^Video Wallpapers$>" = " ";
+ "title<^qs-wlogout$>" = " ";
+ };
+ };
+
+ # ---------- Groups (from ModulesGroups) ----------
+ "group/app_drawer" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "custom/menu";
+ "transition-left-to-right" = true;
+ };
+ modules = [
+ "custom/menu"
+ "custom/file_manager"
+ "custom/tty"
+ "custom/browser"
+ ];
+ };
+
+ "group/mobo_drawer" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "cpu";
+ "transition-left-to-right" = true;
+ };
+ modules = [
+ "temperature"
+ "cpu"
+ "power-profiles-daemon"
+ "memory"
+ "disk"
+ ];
+ };
+
+ "group/laptop" = {
+ orientation = "inherit";
+ modules = ["battery"];
+ };
+
+ "group/audio" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "pulseaudio";
+ "transition-left-to-right" = true;
+ };
+ modules = [
+ "pulseaudio"
+ "pulseaudio#microphone"
+ ];
+ };
+
+ "group/status" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "custom/power";
+ "transition-left-to-right" = false;
+ };
+ modules = [
+ "custom/power"
+ "custom/lock"
+ "keyboard-state"
+ ];
+ };
+
+ # ---------- Custom modules (from ModulesCustom) ----------
+ "custom/weather" = {
+ return-type = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+ "custom/qs_wallpapers_apply" = {
+ # Image wallpaper apply (qs-wallpapers-apply)
+ format = " ";
+ "on-click" = "qs-wallpapers-apply";
+ tooltip = true;
+ "tooltip-format" = "Set wallpaper";
+ };
+ "custom/qs_vid_wallpapers_apply" = {
+ # Video wallpaper apply (qs-vid-wallpapers-apply)
+ format = " ";
+ "on-click" = "qs-vid-wallpapers-apply";
+ tooltip = true;
+ "tooltip-format" = "Set video wallpaper";
+ };
+ "custom/hypridle" = {
+ format = " ";
+ "return-type" = "json";
+ escape = true;
+ "exec-on-event" = true;
+ interval = 60;
+ exec = "$HOME/.config/hypr/scripts/Hypridle.sh status";
+ "on-click" = "$HOME/.config/hypr/scripts/Hypridle.sh toggle";
+ "on-click-right" = "hyprlock";
+ };
+ "custom/lock" = {
+ format = "";
+ "on-click" = "$HOME/.config/hypr/scripts/LockScreen.sh";
+ tooltip = true;
+ "tooltip-format" = " Screen Lock";
+ };
+ "custom/startmenu" = {
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ format = "";
+ # on-click = "rofi -show drun";
+ on-click = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+
+ # Integrated CAVA visualizer using the inline script above
+ "custom/cava_mviz" = {
+ exec = "${waybarCava}/bin/WaybarCava";
+ format = "[ {} ]";
+ };
+
+ "custom/playerctl" = {
+ format = "{}";
+ "return-type" = "json";
+ "max-length" = 25;
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "scroll-step" = 5.0;
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "custom/power" = {
+ format = " ⏻ ";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ };
+ "custom/reboot" = {
+ format = "";
+ "on-click" = "systemctl reboot";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Reboot";
+ };
+ "custom/quit" = {
+ format = "";
+ "on-click" = "hyprctl dispatch exit";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Exit Hyprland";
+ };
+
+ "custom/swaync" = {
+ tooltip = true;
+ "tooltip-format" = "Left Click: Launch Notification Center\nRight Click: Do not Disturb";
+ format = "{} {icon} ";
+ "format-icons" = {
+ notification = "";
+ none = "";
+ "dnd-notification" = "";
+ "dnd-none" = "";
+ "inhibited-notification" = "";
+ "inhibited-none" = "";
+ "dnd-inhibited-notification" = "";
+ "dnd-inhibited-none" = "";
+ };
+ "return-type" = "json";
+ "exec-if" = "which swaync-client";
+ exec = "swaync-client -swb";
+ "on-click" = "systemctl --user start swaync.service; swaync-client -t";
+ "on-click-right" = "systemctl --user start swaync.service; swaync-client -d";
+ escape = true;
+ };
+
+ # Separators
+ "custom/separator#dot" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#dot-line" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#line" = {
+ format = "|";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank_2" = {
+ format = " ";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank_3" = {
+ format = " ";
+ interval = "once";
+ tooltip = false;
+ };
+ }
+ ];
+
+ # Consolidated style (Catppuccin Mocha) inlined
+ style = let
+ c = catppuccinColors;
+ in ''
+ @define-color rosewater ${c.rosewater};
+ @define-color flamingo ${c.flamingo};
+ @define-color pink ${c.pink};
+ @define-color mauve ${c.mauve};
+ @define-color red ${c.red};
+ @define-color maroon ${c.maroon};
+ @define-color peach ${c.peach};
+ @define-color yellow ${c.yellow};
+ @define-color green ${c.green};
+ @define-color teal ${c.teal};
+ @define-color sky ${c.sky};
+ @define-color sapphire ${c.sapphire};
+ @define-color blue ${c.blue};
+ @define-color lavender ${c.lavender};
+ @define-color text ${c.text};
+ @define-color subtext1 ${c.subtext1};
+ @define-color subtext0 ${c.subtext0};
+ @define-color overlay2 ${c.overlay2};
+ @define-color overlay1 ${c.overlay1};
+ @define-color overlay0 ${c.overlay0};
+ @define-color surface2 ${c.surface2};
+ @define-color surface1 ${c.surface1};
+ @define-color surface0 ${c.surface0};
+ @define-color base ${c.base};
+ @define-color mantle ${c.mantle};
+ @define-color crust ${c.crust};
+
+ * {
+ font-family: "JetBrainsMono Nerd Font";
+ font-weight: bold;
+ min-height: 0;
+ font-size: 101%;
+ font-feature-settings: '"zero", "ss01", "ss02", "ss03", "ss04", "ss05", "cv31"';
+ }
+
+ window#waybar {
+ background-color: @base;
+ border-radius: 5px;
+ }
+
+ tooltip {
+ background: @base;
+ opacity: 1;
+ border-radius: 10px;
+ border-width: 2px;
+ border-style: solid;
+ border-color: @sapphire;
+ }
+ tooltip label { color: @blue; }
+
+ /* Extra spacing between NixOS start menu and CAVA */
+ #custom-startmenu { margin-left: 4px; margin-right: 8px; }
+ #custom-cava_mviz { margin-left: 4px; }
+
+ #taskbar button, #workspaces button {
+ color: @surface2;
+ background-color: transparent;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-right: 6px;
+ padding-left: 4px;
+ }
+ #taskbar button.active { color: @maroon; }
+ #workspaces button.active { color: @green; }
+ #taskbar button.focused, #workspaces button.focused {
+ color: @rosewater;
+ background: transparent;
+ border-radius: 15px;
+ }
+ #workspaces button.urgent {
+ color: #11111b;
+ background: transparent;
+ border-radius: 15px;
+ }
+ #taskbar button:hover, #workspaces button:hover {
+ background: transparent;
+ color: @flamingo;
+ border-radius: 15px;
+ }
+ /* Workspaces colors: inactive= @sapphire (pale blue), active= @green, empty= @red */
+ #workspaces button { color: @sapphire; }
+ #workspaces button.empty { color: @red; }
+
+ #backlight,
+ #backlight-slider,
+ #battery,
+ #bluetooth,
+ #clock,
+ #cpu,
+ #disk,
+ #idle_inhibitor,
+ #keyboard-state,
+ #memory,
+ #mode,
+ #mpris,
+ #network,
+ #power-profiles-daemon,
+ #pulseaudio,
+ #pulseaudio-slider,
+ #taskbar button,
+ #taskbar,
+ #temperature,
+ #tray,
+ #window,
+ #wireplumber,
+ #workspaces,
+ #custom-backlight,
+ #custom-browser,
+ #custom-cava_mviz,
+ #custom-cycle_wall,
+ #custom-dot_update,
+ #custom-file_manager,
+ #custom-keybinds,
+ #custom-keyboard,
+ #custom-light_dark,
+ #custom-lock,
+ #custom-hint,
+ #custom-hypridle,
+ #custom-menu,
+ #custom-playerctl,
+ #custom-power_vertical,
+ #custom-power,
+ #custom-quit,
+ #custom-reboot,
+ #custom-settings,
+ #custom-spotify,
+ #custom-swaync,
+ #custom-tty,
+ #custom-updater,
+ #custom-weather,
+ #custom-weather.clearNight,
+ #custom-weather.cloudyFoggyDay,
+ #custom-weather.cloudyFoggyNight,
+ #custom-weather.default,
+ #custom-weather.rainyDay,
+ #custom-weather.rainyNight,
+ #custom-weather.severe,
+ #custom-weather.showyIcyDay,
+ #custom-weather.snowyIcyNight,
+ #custom-weather.sunnyDay {
+ opacity: 1;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-right: 6px;
+ padding-left: 6px;
+ }
+
+ #idle_inhibitor.activated { color: @green; }
+ #idle_inhibitor.deactivated { color: @red; }
+ #mpris { color: @rosewater; }
+ #battery { color: @green; padding-left: 15px; border-radius: 15px 0 0 15px; }
+ @keyframes blink { to { background-color: #ffffff; color: #333333; } }
+ #battery.critical:not(.charging) {
+ color: #f53c3c;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+ #custom-lock, #custom-power { color: @red; border-radius: 15px; font-weight: bolder; padding-left: 1px; }
+ #network { background-color: transparent; color: @mauve; }
+ #backlight { color: @flamingo; }
+ #custom-weather { color: @green; border-radius: 15px; background-color: transparent; }
+ #custom-menu { color: #89b4fa; }
+ #pulseaudio { background-color: transparent; color: @blue; }
+ #clock, #clock-calender { color: @green; }
+ /* Use the same pale blue as clock for these icons */
+ #custom-qs_wallpapers_apply,
+ #custom-qs_vid_wallpapers_apply { color: @sapphire; }
+
+ /* Focused window title */
+ #window { color: @lavender; }
+ /* When offscreen (offscreen-css = true) */
+ #window.offscreen { color: @overlay1; }
+ /* Subtle hover effect */
+ #window:hover { color: @rosewater; transition: color 120ms ease-in-out; }
+
+ /* Playerctl track text */
+ #custom-playerctl { color: @lavender; }
+ #custom-playerctl:hover { color: @rosewater; transition: color 120ms ease-in-out; }
+
+ /* Start menu and notifications in green; turn red on new alerts */
+ #custom-startmenu { color: @green; }
+ #custom-swaync { color: @green; }
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification { color: @red; }
+ /* Group drawer button color */
+ #group-mobo_drawer { color: @green; }
+
+ #backlight-slider slider, #pulseaudio-slider slider {
+ min-height: 7px; min-width: 15px; opacity: 0; background-color: @text; border-radius: 3px; box-shadow: 1px 5px 6px 1px #272727;
+ }
+ #backlight-slider trough, #pulseaudio-slider trough {
+ min-height: 100px; min-width: 7px; border-radius: 5px; background-color: @surface0;
+ }
+ #backlight-slider highlight, #pulseaudio-slider highlight { min-width: 5px; border-radius: 5px; background-color: @blue; }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-jak-ml4w-modern.nix b/home-manager/programs/hypr/waybar/waybar-jak-ml4w-modern.nix
new file mode 100644
index 0000000..0074853
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jak-ml4w-modern.nix
@@ -0,0 +1,1161 @@
+{
+ pkgs,
+ lib,
+ config,
+ ...
+}:
+with lib; let
+ c = config.lib.stylix.colors;
+ # Install helper scripts and provide an inline Waybar CAVA script like in Catppuccin config
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+
+ bar="▁▂▃▄▅▆▇█"
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() {
+ rm -f "$config_file" "$pidfile"
+ }
+ trap cleanup EXIT INT TERM
+
+ cat >"$config_file" <{calendar}";
+ calendar = {
+ mode = "year";
+ "mode-mon-col" = 3;
+ "weeks-pos" = "right";
+ "on-scroll" = 1;
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "W{:%V}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ };
+
+ "actions" = {
+ "on-click-right" = "mode";
+ "on-click-forward" = "tz_up";
+ "on-click-backward" = "tz_down";
+ "on-scroll-up" = "shift_up";
+ "on-scroll-down" = "shift_down";
+ };
+
+ "cpu" = {
+ format = "{usage}% ";
+ interval = 1;
+ "min-length" = 5;
+ "format-alt-click" = "click";
+ "format-alt" = "{icon0}{icon1}{icon2}{icon3} {usage:>2}% ";
+ "format-icons" = [
+ "▁"
+ "▂"
+ "▃"
+ "▄"
+ "▅"
+ "▆"
+ "▇"
+ "█"
+ ];
+ "on-click-right" = "gnome-system-monitor";
+ };
+
+ disk = {
+ interval = 30;
+ path = "/";
+ format = "{percentage_used}% ";
+ "tooltip-format" = "{used} used out of {total} on {path} ({percentage_used}%)";
+ };
+
+ "hyprland/language" = {
+ format = "Lang: {}";
+ "format-en" = "US";
+ "format-tr" = "Korea";
+ "keyboard-name" = "at-translated-set-2-keyboard";
+ "on-click" = "hyprctl switchxkblayout $SET_KB next";
+ };
+
+ "hyprland/submap" = {
+ format = '' {}'';
+ tooltip = false;
+ };
+
+ "hyprland/window" = {
+ format = "{}";
+ "max-length" = 25;
+ "separate-outputs" = true;
+ "offscreen-css" = true;
+ "offscreen-css-text" = "(inactive)";
+ rewrite = {
+ "(.*) — Mozilla Firefox" = " $1";
+ "(.*) - fish" = "> [$1]";
+ "(.*) - zsh" = "> [$1]";
+ "(.*) - $term" = "> [$1]";
+ };
+ };
+
+ idle_inhibitor = {
+ tooltip = true;
+ "tooltip-format-activated" = "Idle_inhibitor active";
+ "tooltip-format-deactivated" = "Idle_inhibitor not active";
+ format = "{icon}";
+ "format-icons" = {
+ activated = " ";
+ deactivated = " ";
+ };
+ };
+
+ "keyboard-state" = {
+ capslock = true;
+ format = {
+ numlock = "N {icon}";
+ capslock = " {icon}";
+ };
+ "format-icons" = {
+ locked = "";
+ unlocked = "";
+ };
+ };
+
+ memory = {
+ interval = 10;
+ format = "{used:0.1f}G ";
+ "format-alt" = "{percentage}% ";
+ "format-alt-click" = "click";
+ tooltip = true;
+ "tooltip-format" = "{used:0.1f}GB/{total:0.1f}G";
+ "on-click-right" = "kitty -e btop";
+ };
+
+ mpris = {
+ interval = 10;
+ format = "{player_icon} ";
+ "format-paused" = "{status_icon} {dynamic}";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "scroll-step" = 5.0;
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "smooth-scrolling-threshold" = 1;
+ tooltip = true;
+ "tooltip-format" = "{status_icon} {dynamic}\nLeft Click: previous\nMid Click: Pause\nRight Click: Next";
+ "player-icons" = {
+ chromium = "";
+ default = "";
+ firefox = "";
+ kdeconnect = "";
+ mopidy = "";
+ mpv = "";
+ spotify = "";
+ vlc = "";
+ };
+ "status-icons" = {
+ paused = "";
+ playing = "";
+ stopped = "";
+ };
+ # "ignored-players" = [ "firefox" ];
+ "max-length" = 30;
+ };
+
+ network = {
+ format = "{ifname}";
+ "format-wifi" = "{icon}";
+ "format-ethernet" = "";
+ "format-disconnected" = "";
+ "tooltip-format" = "{ipaddr} {bandwidthUpBits} {bandwidthDownBits}";
+ "format-linked" = " {ifname} (No IP)";
+ "tooltip-format-wifi" = "{essid} {icon} {signalStrength}%";
+ "tooltip-format-ethernet" = "{ifname} ";
+ "tooltip-format-disconnected" = " Disconnected";
+ "max-length" = 30;
+ "format-icons" = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ "on-click-right" = " kitty -e nmtui";
+ };
+
+ "network#speed" = {
+ interval = 1;
+ format = "{ifname}";
+ "format-wifi" = "{icon} {bandwidthUpBytes} {bandwidthDownBytes}";
+ "format-ethernet" = " {bandwidthUpBytes} {bandwidthDownBytes}";
+ "format-disconnected" = "";
+ "tooltip-format" = "{ipaddr}";
+ "format-linked" = " {ifname} (No IP)";
+ "tooltip-format-wifi" = "{essid} {icon} {signalStrength}%";
+ "tooltip-format-ethernet" = "{ifname} ";
+ "tooltip-format-disconnected" = " Disconnected";
+ "min-length" = 24;
+ "max-length" = 24;
+ "format-icons" = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+
+ "power-profiles-daemon" = {
+ format = "{icon} ";
+ "tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
+ tooltip = true;
+ "format-icons" = {
+ default = "";
+ performance = "";
+ balanced = "";
+ "power-saver" = "";
+ };
+ };
+
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ "format-bluetooth" = "{icon} {volume}%";
+ "format-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ "hands-free" = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ""
+ ];
+ "ignored-sinks" = ["Easy Effects Sink"];
+ };
+ "scroll-step" = 5.0;
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle";
+ "on-click-right" = "pavucontrol -t 3";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "tooltip-format" = "{icon} {desc} | {volume}%";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "pulseaudio#microphone" = {
+ format = "{format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic";
+ "on-click-right" = "pavucontrol -t 4";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --mic-inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --mic-dec";
+ "tooltip-format" = "{source_desc} | {source_volume}%";
+ "scroll-step" = 5;
+ };
+
+ tray = {
+ "icon-size" = 20;
+ spacing = 4;
+ };
+
+ "wlr/taskbar" = {
+ format = "{icon} {name}";
+ "icon-size" = 16;
+ "all-outputs" = false;
+ "tooltip-format" = "{title}";
+ "on-click" = "activate";
+ "on-click-middle" = "close";
+ "ignore-list" = [
+ "wofi"
+ "rofi"
+ "kitty"
+ "kitty-dropterm"
+ ];
+ };
+
+ # Modules (from ModulesCustom)
+ "custom/weather" = {
+ format = "{}";
+ "format-alt" = "{alt}: {}";
+ "format-alt-click" = "click";
+ interval = 3600;
+ "return-type" = "json";
+ exec = "$HOME/.config/hypr/UserScripts/Weather.py";
+ tooltip = true;
+ };
+
+ "custom/hyprpicker" = {
+ format = "";
+ "on-click" = "hyprpicker | wl-copy";
+ tooltip = true;
+ "tooltip-format" = "Hyprpicker";
+ };
+
+ "custom/hypridle" = {
+ format = " ";
+ "return-type" = "json";
+ escape = true;
+ "exec-on-event" = true;
+ interval = 60;
+ exec = "$HOME/.config/hypr/scripts/Hypridle.sh status";
+ "on-click" = "$HOME/.config/hypr/scripts/Hypridle.sh toggle";
+ "on-click-right" = "hyprlock";
+ };
+
+ "custom/lock" = {
+ format = "";
+ "on-click" = "$HOME/.config/hypr/scripts/LockScreen.sh";
+ tooltip = true;
+ "tooltip-format" = " Screen Lock";
+ };
+
+ "custom/menu" = {
+ format = " ";
+ # "on-click" = "pkill rofi || rofi -show drun -modi run,drun,filebrowser,window";
+ "on-click" = "launch-nwg-menu";
+ "on-click-middle" = "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh";
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarLayout.sh";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Rofi Menu\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Layout Menu";
+ };
+
+ "custom/cava_mviz" = {
+ exec = "${waybarCava}/bin/WaybarCava";
+ format = "{}";
+ };
+
+ "custom/playerctl" = {
+ format = "{}";
+ "return-type" = "json";
+ "max-length" = 25;
+ exec = ''playerctl -a metadata --format '{"text": "{{artist}} {{markup_escape(title)}}", "tooltip": "{{playerName}} : {{markup_escape(title)}}", "alt": "{{status}}", "class": "{{status}}"}' -F'';
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "scroll-step" = 5.0;
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "custom/power" = {
+ format = " ⏻ ";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Power Menu (qs-wlogout)\nRight Click: Rofi Power Menu";
+ };
+
+ "custom/reboot" = {
+ format = "";
+ "on-click" = "systemctl reboot";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Reboot";
+ };
+
+ "custom/quit" = {
+ format = "";
+ "on-click" = "hyprctl dispatch exit";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Exit Hyprland";
+ };
+
+ "custom/swaync" = {
+ tooltip = true;
+ "tooltip-format" = "Left Click: Launch Notification Center\nRight Click: Do not Disturb";
+ format = "{} {icon} ";
+ "format-icons" = {
+ notification = '''';
+ none = "";
+ "dnd-notification" = '''';
+ "dnd-none" = "";
+ "inhibited-notification" = '''';
+ "inhibited-none" = "";
+ "dnd-inhibited-notification" = '''';
+ "dnd-inhibited-none" = "";
+ };
+ "return-type" = "json";
+ "exec-if" = "which swaync-client";
+ exec = "swaync-client -swb";
+ "on-click" = "sleep 0.1 && swaync-client -t -sw";
+ "on-click-right" = "swaync-client -d -sw";
+ escape = true;
+ };
+
+ # Separators
+ "custom/separator#dot" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#dot-line" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#line" = {
+ format = "|";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank_2" = {
+ format = " ";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank_3" = {
+ format = " ";
+ interval = "once";
+ tooltip = false;
+ };
+
+ # Groups (from ModulesGroups)
+ "group/app_drawer" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "custom/menu";
+ "transition-left-to-right" = true;
+ };
+ modules = [
+ "custom/menu"
+ "custom/file_manager"
+ "custom/tty"
+ "custom/browser"
+ ];
+ };
+
+ "group/motherboard" = {
+ orientation = "horizontal";
+ modules = [
+ "cpu"
+ "power-profiles-daemon"
+ "memory"
+ "temperature"
+ "disk"
+ ];
+ };
+
+ "group/mobo_drawer" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "cpu";
+ "transition-left-to-right" = true;
+ };
+ modules = [
+ "temperature"
+ "cpu"
+ "power-profiles-daemon"
+ "memory"
+ "disk"
+ ];
+ };
+
+ "group/laptop" = {
+ orientation = "inherit";
+ modules = [
+ "backlight"
+ "battery"
+ ];
+ };
+
+ "group/audio" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "pulseaudio";
+ "transition-left-to-right" = true;
+ };
+ modules = [
+ "pulseaudio"
+ "pulseaudio#microphone"
+ ];
+ };
+
+ "group/status" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "custom/power";
+ "transition-left-to-right" = false;
+ };
+ modules = [
+ "custom/power"
+ "custom/lock"
+ "keyboard-state"
+ "custom/keyboard"
+ ];
+ };
+
+ "group/notify" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "custom/swaync";
+ "transition-left-to-right" = false;
+ };
+ modules = [
+ "custom/swaync"
+ ];
+ };
+
+ # Workspaces (from ModulesWorkspaces)
+ "hyprland/workspaces#rw" = {
+ "disable-scroll" = true;
+ "all-outputs" = true;
+ "warp-on-scroll" = false;
+ "sort-by-number" = true;
+ "show-special" = false;
+ "on-click" = "activate";
+ "on-scroll-up" = "hyprctl dispatch workspace e+1";
+ "on-scroll-down" = "hyprctl dispatch workspace e-1";
+ "persistent-workspaces" = {
+ "*" = 5;
+ };
+ format = "{icon} {windows}";
+ "format-window-separator" = " ";
+ "window-rewrite-default" = " ";
+ "window-rewrite" = {
+ "title<.*amazon.*>" = " ";
+ "title<.*reddit.*>" = " ";
+ "title<.*[Hh]elium.*>" = " ";
+
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = "🦁 ";
+ "class" = " ";
+ "class" = "🦊 ";
+
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+
+ "class<[Tt]hunderbird|[Tt]hunderbird-esr>" = " ";
+ "class" = " ";
+ "title<.*gmail.*>" = " ";
+
+ "class<[Tt]elegram-desktop|org.telegram.desktop|io.github.tdesktop_x64.TDesktop>" = " ";
+ "class" = " ";
+ "title<.*whatsapp.*>" = " ";
+ "title<.*zapzap.*>" = " ";
+ "title<.*messenger.*>" = " ";
+ "title<.*facebook.*>" = " ";
+ "class<[Ss]ignal|signal-desktop|org.signal.Signal>" = " ";
+ "title<.*Signal.*>" = " ";
+
+ "title<.*ChatGPT.*>" = " ";
+ "title<.*deepseek.*>" = " ";
+ "title<.*qwen.*>" = " ";
+ "class" = " ";
+ "class" = " ";
+
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "title<.*Picture-in-Picture.*>" = " ";
+ "title<.*youtube.*>" = " ";
+ "class" = " ";
+ "class<[Kk]denlive|org.kde.kdenlive>" = "🎬 ";
+ "title<.*Kdenlive.*>" = "🎬 ";
+
+ "class<[Bb]ox[Bb]uddy|io.github.dvlv.boxbuddy|io.github.dvlv.BoxBuddy>" = " ";
+ "title<.*BoxBuddy.*>" = " ";
+
+ # qs-* apps
+ "class" = " ";
+
+ "class" = " ";
+ "class<.virt-manager-wrapped>" = " ";
+ "class" = " ";
+ "class" = "💽 ";
+ "title" = "💽 ";
+ "class" = "🖥️ ";
+
+ "class" = " ";
+ "class" = "";
+ "class" = " ";
+ "title<.*github.*>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "title<.*nvim ~.*>" = " ";
+ "title<.*vim.*>" = " ";
+ "title<.*nvim.*>" = " ";
+ "title<.*Discord.*>" = " ";
+ "title<.*figma.*>" = " ";
+ "title<.*jira.*>" = " ";
+ "class" = " ";
+
+ "class" = " ";
+
+ "class" = " ";
+ "class" = " ";
+ "class<[Pp]avucontrol|org.pulseaudio.pavucontrol>" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = "";
+ "class" = " ";
+ "class" = "📱 ";
+ "class" = " ";
+ "class" = "";
+ "class" = "";
+ "class" = "";
+
+ "class" = " ";
+ "title<^Bazaar$>" = " ";
+
+ "class" = " ";
+ "title<^satty$>" = " ";
+
+ # qs-* apps
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title<^Wallpapers$>" = " ";
+ "title<^Video Wallpapers$>" = " ";
+ "title<^qs-wlogout$>" = " ";
+ };
+ };
+ }
+ ];
+
+ # Stylix-based CSS (replaces Wallust)
+ style = ''
+ /* ---- 💫 JakooLit ml4w-modern (Stylix) 💫 ---- */
+
+ /* Define palette from Stylix base16 */
+ @define-color backgroundlight #${c.base00};
+ @define-color backgrounddark #${c.base02};
+ @define-color workspacesbackground1 #${c.base00};
+ @define-color workspacesbackground2 #${c.base02};
+ @define-color bordercolor #${c.base0D};
+ @define-color textcolor1 #${c.base05};
+ @define-color textcolor2 #${c.base05};
+ @define-color textcolor3 #${c.base05};
+ @define-color iconcolor #${c.base05};
+ @define-color accentgreen #${c.base0B};
+ @define-color accentred #${c.base08};
+
+ * {
+ font-family: "JetBrainsMono Nerd Font";
+ font-weight: bold;
+ min-height: 0;
+ font-size: 97%;
+ font-feature-settings: '"zero", "ss01", "ss02", "ss03", "ss04", "ss05", "cv31"';
+ }
+
+ window#waybar {
+ background-color: rgba(0,0,0,0.8);
+ border-bottom: 0px solid #ffffff;
+ background: transparent;
+ transition-property: background-color;
+ transition-duration: .5s;
+ }
+
+ #workspaces {
+ background: @workspacesbackground1;
+ margin: 2px 18px 3px 1px;
+ margin-left: 6px;
+ padding: 0px 2px;
+ border-radius: 5px;
+ border: 0px;
+ font-style: normal;
+ color: @textcolor1;
+ }
+
+ #workspaces button {
+ padding: 0px 6px;
+ margin: 3px 2px;
+ border-radius: 3px;
+ color: @textcolor1;
+ background-color: @workspacesbackground1;
+ transition: all 0.1s linear;
+ }
+
+ #workspaces button.active {
+ color: @textcolor1;
+ background: @workspacesbackground2;
+ border-radius: 3px;
+ min-width: 30px;
+ transition: all 0.1s linear;
+ }
+
+ #workspaces button:hover {
+ color: @textcolor1;
+ background: @workspacesbackground2;
+ border-radius: 5px;
+ opacity: 0.7;
+ }
+
+ tooltip {
+ border-radius: 16px;
+ background-color: @backgroundlight;
+ opacity: 0.9;
+ padding: 20px;
+ margin: 0px;
+ }
+
+ tooltip label { color: @textcolor2; }
+
+ #window {
+ margin: 3px 15px 3px 0px;
+ padding: 2px 10px 0px 10px;
+ border-radius: 5px;
+ color: white;
+ font-weight: normal;
+ }
+
+ window#waybar.empty #window { background-color: transparent; }
+
+ #taskbar {
+ background: @backgroundlight;
+ margin: 3px 15px 3px 0px;
+ padding: 0px;
+ border-radius: 5px;
+ font-weight: normal;
+ font-style: normal;
+ border: 3px solid @backgroundlight;
+ }
+
+ #taskbar button { margin: 0; border-radius: 5px; padding: 0px 5px; }
+ #taskbar.empty { background: transparent; border: 0; padding: 0; margin: 0; }
+
+ .modules-left > widget:first-child > #workspaces { margin-left: 0; }
+ .modules-right > widget:last-child > #workspaces { margin-right: 0; }
+
+ #backlight,
+ #backlight-slider,
+ #battery,
+ #bluetooth,
+ #clock,
+ #cpu,
+ #disk,
+ #idle_inhibitor,
+ #keyboard-state,
+ #memory,
+ #mode,
+ #mpris,
+ #network,
+ #power-profiles-daemon,
+ #pulseaudio,
+ #pulseaudio-slider,
+ #taskbar button,
+ #taskbar,
+ #temperature,
+ #tray,
+ #window,
+ #wireplumber,
+ #workspaces,
+ #custom-backlight,
+ #custom-browser,
+ #custom-cava_mviz,
+ #custom-cycle_wall,
+ #custom-dot_update,
+ #custom-file_manager,
+ #custom-keybinds,
+ #custom-keyboard,
+ #custom-light_dark,
+ #custom-lock,
+ #custom-hint,
+ #custom-hypridle,
+ #custom-menu,
+ #custom-playerctl,
+ #custom-power_vertical,
+ #custom-power,
+ #custom-quit,
+ #custom-reboot,
+ #custom-settings,
+ #custom-spotify,
+ #custom-swaync,
+ #custom-tty,
+ #custom-updater,
+ #custom-hyprpicker,
+ #custom-weather,
+ #custom-weather.clearNight,
+ #custom-weather.cloudyFoggyDay,
+ #custom-weather.cloudyFoggyNight,
+ #custom-weather.default,
+ #custom-weather.rainyDay,
+ #custom-weather.rainyNight,
+ #custom-weather.severe,
+ #custom-weather.showyIcyDay,
+ #custom-weather.snowyIcyNight,
+ #custom-weather.sunnyDay {
+ margin-right: 8px;
+ margin-left: 6px;
+ font-size: 100%;
+ color: @iconcolor;
+ }
+
+ #custom-swaync { margin-left: 12px; color: @accentgreen; }
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification { color: @accentred; }
+
+ #idle_inhibitor {
+ margin-right: 15px;
+ font-size: 102%;
+ font-weight: bold;
+ color: @iconcolor;
+ }
+
+ #idle_inhibitor.activated {
+ margin-right: 15px;
+ font-size: 100%;
+ font-weight: bold;
+ color: @accentgreen;
+ }
+
+ #idle_inhibitor.deactivated {
+ color: @accentred;
+ }
+
+ #custom-menu {
+ background-color: @backgrounddark;
+ color: @textcolor1;
+ border-radius: 5px;
+ padding: 0px 10px;
+ margin: 2px 17px 2px 0px;
+ border: 3px solid @bordercolor;
+ }
+
+ #custom-power {
+ background-color: @backgrounddark;
+ color: @textcolor1;
+ border-radius: 5px;
+ padding: 0px 0px 0px 6px;
+ border: 3px solid @bordercolor;
+ }
+
+ #custom-keybinds { margin: 0px 13px 0px 0px; padding: 0px; color: @iconcolor; }
+
+ #custom-updater {
+ background-color: @backgroundlight;
+ color: @textcolor2;
+ border-radius: 5px;
+ padding: 2px 10px 0px 10px;
+ margin: 3px 15px 3px 0px;
+ }
+
+ #custom-updates.green { background-color: @backgroundlight; }
+ #custom-updates.yellow { background-color: #ff9a3c; color: #FFFFFF; }
+ #custom-updates.red { background-color: #dc2f2f; color: #FFFFFF; }
+
+ #keyboard-state { margin-right: 10px; }
+
+ #clock {
+ background-color: @backgrounddark;
+ color: @textcolor1;
+ border-radius: 3px 5px 3px 5px;
+ padding: 1px 10px 0px 10px;
+ margin: 3px 0px 3px 0px;
+ border: 3px solid @bordercolor;
+ }
+
+ #backlight {
+ background-color: @backgroundlight;
+ margin-left: 6px;
+ color: @textcolor2;
+ border-radius: 5px;
+ padding: 2px 10px 0px 10px;
+ margin: 3px 15px 3px 0px;
+ }
+
+ #pulseaudio {
+ background-color: @backgroundlight;
+ color: @textcolor2;
+ border-radius: 5px;
+ padding: 2px 10px 0px 10px;
+ margin: 3px 15px 3px 0px;
+ }
+
+ #pulseaudio.muted { background-color: @backgrounddark; color: @textcolor1; }
+
+ #network,
+ #network.ethernet,
+ #network.wifi,
+ #bluetooth,
+ #bluetooth.on,
+ #bluetooth.connected,
+ #battery {
+ background-color: @backgroundlight;
+ color: @textcolor2;
+ border-radius: 5px;
+ padding: 2px 10px 0px 10px;
+ margin: 3px 15px 3px 0px;
+ }
+
+ #bluetooth.off { background-color: transparent; padding: 0px; margin: 0px; }
+
+ #battery.charging, #battery.plugged { color: @textcolor2; background-color: @backgroundlight; }
+
+ @keyframes blink { to { background-color: @backgroundlight; color: @textcolor2; } }
+ #battery.critical:not(.charging) {
+ background-color: #f53c3c;
+ color: @textcolor3;
+ animation-name: blink;
+ animation-duration: 3.0s;
+ animation-timing-function: steps(12);
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ #tray { padding: 0px 15px 0px 0px; }
+ #tray > .passive { -gtk-icon-effect: dim; }
+ #tray > .needs-attention { -gtk-icon-effect: highlight; }
+
+ #backlight-slider slider,
+ #pulseaudio-slider slider {
+ min-width: 0px;
+ min-height: 0px;
+ opacity: 0;
+ background-image: none;
+ border: none;
+ box-shadow: none;
+ }
+
+ #backlight-slider trough,
+ #pulseaudio-slider trough { min-width: 80px; min-height: 5px; border-radius: 5px; }
+ #backlight-slider highlight,
+ #pulseaudio-slider highlight { min-height: 10px; border-radius: 5px; }
+
+ /* --- Explicit color overrides to ensure correct states --- */
+ /* SwayNC: green when no notifications, red when any notification state */
+ #custom-swaync { color: #00f769; }
+ #custom-swaync.none,
+ #custom-swaync.dnd-none,
+ #custom-swaync.inhibited-none { color: #00f769; }
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification { color: #f38ba8; }
+
+ /* Idle inhibitor: red when deactivated, green when activated */
+ #idle_inhibitor { color: #f38ba8; }
+ #idle_inhibitor.deactivated { color: #f38ba8; }
+ #idle_inhibitor.activated { color: #00f769; }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-jak-oglo-simple.nix b/home-manager/programs/hypr/waybar/waybar-jak-oglo-simple.nix
new file mode 100644
index 0000000..d84c8e3
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jak-oglo-simple.nix
@@ -0,0 +1,846 @@
+{
+ pkgs,
+ lib,
+ ...
+}:
+with lib; let
+ # Install Waybar helper scripts under ~/.config/waybar/scripts (needed for power-menu.sh)
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ # Import upstream wallust color variables and base style from the source theme
+ wallustColors = ''
+ /* ---- 💫 https://github.com/JaKooLit 💫 ---- */
+ /* wallust template - colors-waybar */
+
+ @define-color foreground #DADDF8;
+ @define-color background #1A1921;
+ @define-color background-alt rgba(26,25,33,0.25);
+ @define-color cursor #7B7EA0;
+
+ @define-color color0 #413F48;
+ @define-color color1 #0F102E;
+ @define-color color2 #151636;
+ @define-color color3 #3F3683;
+ @define-color color4 #404470;
+ @define-color color5 #646AA1;
+ @define-color color6 #7177B1;
+ @define-color color7 #C2C7ED;
+ @define-color color8 #888BA6;
+ @define-color color9 #13153E;
+ @define-color color10 #1C1E49;
+ @define-color color11 #5448AF;
+ @define-color color12 #555A95;
+ @define-color color13 #868ED6;
+ @define-color color14 #969FEC;
+ @define-color color15 #C2C7ED;
+ '';
+
+ baseStyle = ''
+ /* ---- 💫 https://github.com/JaKooLit 💫 ---- */
+ /* Oglo Chicklets */
+
+ * {
+ font-family: "JetBrainsMono Nerd Font", FontAwesome, Roboto, Helvetica, Arial, sans-serif;
+ font-size: 97%;
+ font-weight: bold;
+ }
+
+ window#waybar {
+ background-color: #232a2e;
+ border-bottom: 8px solid #1d2327;
+ color: #d3c6aa;
+ transition-property: background-color;
+ transition-duration: .5s;
+ }
+
+ window#waybar.hidden {
+ opacity: 0.2;
+ }
+
+ /*
+ window#waybar.empty {
+ background-color: transparent;
+ }
+ window#waybar.solo {
+ background-color: #FFFFFF;
+ }
+ */
+
+ button {
+ all: unset;
+ background-color: #778f52;
+ color: #2d353b;
+ border: none;
+ border-bottom: 8px solid #5d743e;
+ border-radius: 5px;
+ padding-left: 15px;
+ padding-right: 15px;
+ transition: transform 0.1s ease-in-out;
+ }
+
+ button:hover {
+ background: inherit;
+ background-color: #92ab6c;
+ border-bottom: 8px solid #788f57;
+ }
+
+ button.active {
+ background: inherit;
+ background-color: #a5be7e;
+ border-bottom: 8px solid #8aa168;
+ }
+
+ #mode {
+ background-color: #64727D;
+ border-bottom: 3px solid #ffffff;
+ }
+
+ #backlight,
+ #backlight-slider,
+ #battery,
+ #bluetooth,
+ #clock,
+ #cpu,
+ #disk,
+ #idle_inhibitor,
+ #keyboard-state,
+ #memory,
+ #mode,
+ #mpris,
+ #network,
+ #power-profiles-daemon,
+ #pulseaudio,
+ #pulseaudio-slider,
+ #taskbar,
+ #temperature,
+ #tray,
+ #window,
+ #wireplumber,
+ #workspaces,
+ #custom-backlight,
+ #custom-browser,
+ #custom-cava_mviz,
+ #custom-cycle_wall,
+ #custom-dot_update,
+ #custom-file_manager,
+ #custom-keybinds,
+ #custom-keyboard,
+ #custom-light_dark,
+ #custom-lock,
+ #custom-hint,
+ #custom-hypridle,
+ #custom-menu,
+ #custom-playerctl,
+ #custom-power_vertical,
+ #custom-power,
+ #custom-quit,
+ #custom-reboot,
+ #custom-settings,
+ #custom-spotify,
+ #custom-swaync,
+ #custom-tty,
+ #custom-updater,
+ #custom-hyprpicker,
+ #custom-weather,
+ #custom-weather.clearNight,
+ #custom-weather.cloudyFoggyDay,
+ #custom-weather.cloudyFoggyNight,
+ #custom-weather.default,
+ #custom-weather.rainyDay,
+ #custom-weather.rainyNight,
+ #custom-weather.severe,
+ #custom-weather.showyIcyDay,
+ #custom-weather.snowyIcyNight,
+ #custom-weather.sunnyDay{
+ color: #ffffff;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ border-radius: 5px;
+ padding-left: 5px;
+ padding-right: 5px;
+ }
+
+ #window,
+ #workspaces {
+ margin: 0 4px;
+ }
+
+ /* If workspaces is the leftmost module, omit left margin */
+ .modules-left > widget:first-child > #workspaces {
+ margin-left: 0;
+ }
+
+ /* If workspaces is the rightmost module, omit right margin */
+ .modules-right > widget:last-child > #workspaces {
+ margin-right: 0;
+ }
+
+ #window {
+ background-color: #343f44;
+ color: #d3c6aa;
+ border-bottom: 8px solid #2b3539;
+ }
+
+ #custom-swaync {
+ background-color: #778f52;
+ color: #2d353b;
+ border-bottom: 8px solid #5d743e;
+ }
+
+ #custom-menu {
+ background-color: #778f52;
+ color: #2d353b;
+ border-bottom: 8px solid #5d743e;
+ }
+
+ #custom-power {
+ background-color: #ee606a;
+ color: #2d353b;
+ border-bottom: 8px solid #ca4853;
+ padding-left: 10px;
+ }
+
+ #custom-power_vertical{
+ background-color: #ee606a;
+ color: #2d353b;
+ border-bottom: 8px solid #ca4853;
+ }
+
+ #clock {
+ background-color: #96a84c;
+ color: #2d353b;
+ border-bottom: 8px solid #7a8c37;
+ }
+
+ #battery {
+ background-color: #3a998f;
+ color: #2d353b;
+ border-bottom: 8px solid #227d74;
+ }
+
+ @keyframes blink {
+ to {
+ background-color: #ffffff;
+ color: #000000;
+ }
+ }
+
+ #battery.critical:not(.charging) {
+ background-color: #ee606a;
+ color: #2d353b;
+ border-bottom: 8px solid #ca4853;
+ animation-name: blink;
+ animation-duration: 3.0s;
+ animation-timing-function: steps(12);
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ label:focus {
+ background-color: #000000;
+ }
+
+ #cpu {
+ background-color: #778f52;
+ color: #2d353b;
+ border-bottom: 8px solid #5d743e;
+ }
+
+ #memory {
+ background-color: #d980ad;
+ color: #2d353b;
+ border-bottom: 8px solid #b86790;
+ }
+
+ #disk {
+ background-color: #964B00;
+ border-bottom: 8px solid #793300;
+ }
+
+ #custom-lock,
+ #custom-light_dark,
+ #backlight {
+ background-color: #64b6ac;
+ color: #2d353b;
+ border-bottom: 8px solid #4f9990;
+ padding-left: 10px;
+ }
+
+ #network {
+ background-color: #2980b9;
+ }
+
+ #network.disconnected {
+ background-color: #f53c3c;
+ }
+
+ #pulseaudio {
+ background-color: #d8ac47;
+ color: #2d353b;
+ border-bottom: 8px solid #b78f30;
+ }
+
+ #pulseaudio.muted {
+ background-color: #90b1b1;
+ color: #2a5c45;
+ }
+
+ #wireplumber {
+ background-color: #fff0f5;
+ color: #000000;
+ }
+
+ #wireplumber.muted {
+ background-color: #f53c3c;
+ }
+
+ #custom-media {
+ background-color: #66cc99;
+ color: #2a5c45;
+ min-width: 100px;
+ }
+
+ #custom-media.custom-spotify {
+ background-color: #66cc99;
+ }
+
+ #custom-media.custom-vlc {
+ background-color: #ffa000;
+ }
+
+ #temperature {
+ background-color: #f0932b;
+ border-bottom: 8px solid #b78f30;
+ }
+
+ #temperature.critical {
+ background-color: #eb4d4b;
+ }
+
+ #tray {
+ background-color: #e67f51;
+ color: #2d353b;;
+ border-bottom: 8px solid #c3653b;
+ }
+
+ #tray > .passive {
+ -gtk-icon-effect: dim;
+ }
+
+ #tray > .needs-attention {
+ -gtk-icon-effect: highlight;
+ background-color: #eb4d4b;
+ }
+
+ #idle_inhibitor {
+ background-color: #2d3436;
+ }
+
+ #idle_inhibitor.activated {
+ background-color: #ecf0f1;
+ color: #2d3436;
+ }
+
+ #mpd {
+ background-color: #66cc99;
+ color: #2a5c45;
+ }
+
+ #mpd.disconnected {
+ background-color: #f53c3c;
+ }
+
+ #mpd.stopped {
+ background-color: #90b1b1;
+ }
+
+ #mpd.paused {
+ background-color: #51a37a;
+ }
+
+ #language {
+ background: #00b093;
+ color: #740864;
+ min-width: 16px;
+ }
+
+ #keyboard-state {
+ background: #97e1ad;
+ color: #000000;
+ min-width: 16px;
+ border-bottom: 8px solid #78b48a;
+ }
+
+ #keyboard-state > label {
+ padding: 0 5px;
+ }
+
+ #keyboard-state > label.locked {
+ background: rgba(0, 0, 0, 0.2);
+ }
+
+ #scratchpad {
+ background: rgba(0, 0, 0, 0.2);
+ }
+
+ #scratchpad.empty {
+ background-color: transparent;
+ }
+
+ tooltip {
+ background-color: #232a2e;
+ border: none;
+ border-bottom: 8px solid #1d2327;
+ }
+
+ tooltip decoration {
+ box-shadow: none;
+ }
+
+ tooltip decoration:backdrop {
+ box-shadow: none;
+ }
+
+ tooltip label {
+ color: #d3c6aa;
+ padding-left: 5px;
+ padding-right: 5px;
+ padding-top: 0px;
+ padding-bottom: 5px;
+ }
+
+
+ #pulseaudio-slider slider {
+ min-width: 0px;
+ min-height: 0px;
+ opacity: 0;
+ background-image: none;
+ border: none;
+ box-shadow: none;
+ }
+
+ #pulseaudio-slider trough {
+ background-color: #7f849c;
+ min-width: 80px;
+ min-height: 5px;
+ border-radius: 5px;
+ }
+
+ #pulseaudio-slider highlight {
+ min-height: 10px;
+ border-radius: 5px;
+ }
+
+ #backlight-slider slider {
+ min-width: 0px;
+ min-height: 0px;
+ opacity: 0;
+ background-image: none;
+ border: none;
+ box-shadow: none;
+ }
+
+ #backlight-slider trough {
+ background-color: #7f849c;
+ min-width: 80px;
+ min-height: 10px;
+ border-radius: 5px;
+ }
+
+ #backlight-slider highlight {
+ min-width: 10px;
+ border-radius: 5px;
+ }
+ '';
+
+ # Explicit overrides for notification coffee mug colors (red when inactive/no notifications, green when active/has notifications)
+ overrides = ''
+ /* Coffee mug notification colors */
+ #custom-swaync { color: #ee606a; } /* default red */
+ #custom-swaync.none,
+ #custom-swaync.dnd-none,
+ #custom-swaync.inhibited-none { color: #ee606a; }
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification { color: #00f769; }
+ '';
+in {
+ # Install scripts (power-menu.sh, etc.)
+ home.file = builtins.listToAttrs (
+ map (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts
+ );
+
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ # mode = "dock";
+ exclusive = true;
+ passthrough = false;
+ "gtk-layer-shell" = true;
+ "margin-left" = 6;
+ "margin-right" = 6;
+ "margin-top" = 2;
+
+ # Layout
+ "modules-left" = [
+ "idle_inhibitor"
+ "group/mobo_drawer"
+ "hyprland/workspaces#rw"
+ "tray"
+ "mpris"
+ ];
+ "modules-center" = [
+ "clock#2"
+ "group/notify"
+ "custom/weather"
+ ];
+ "modules-right" = [
+ "hyprland/window"
+ "battery"
+ "group/audio"
+ "custom/power"
+ ];
+
+ # Module definitions (subset needed by this layout)
+ battery = {
+ align = 0;
+ rotate = 0;
+ "full-at" = 100;
+ "design-capacity" = false;
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ "format-charging" = " {capacity}%";
+ "format-plugged" = " {capacity}%";
+ "format-alt-click" = "click";
+ "format-full" = "{icon} Full";
+ "format-alt" = "{icon} {time}";
+ "format-icons" = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ "format-time" = "{H}h {M}min";
+ tooltip = true;
+ "tooltip-format" = "{timeTo} {power}w";
+ "on-click-middle" = "$HOME/.config/hypr/scripts/ChangeBlur.sh";
+ "on-click-right" = "$HOME/.config/hypr/scripts/Wlogout.sh";
+ };
+
+ "clock#2" = {
+ format = " {:%I:%M %p}";
+ "format-alt" = "{:%A | %H:%M | %e %B}";
+ "tooltip-format" = "{:%Y %B}\n{calendar}";
+ };
+
+ cpu = {
+ format = "{usage}% ";
+ interval = 1;
+ "min-length" = 5;
+ "format-alt-click" = "click";
+ "format-alt" = "{icon0}{icon1}{icon2}{icon3} {usage:>2}% ";
+ "format-icons" = ["▁" "▂" "▃" "▄" "▅" "▆" "▇" "█"];
+ "on-click-right" = "gnome-system-monitor";
+ };
+
+ disk = {
+ interval = 30;
+ path = "/";
+ format = "{percentage_used}% ";
+ "tooltip-format" = "{used} used out of {total} on {path} ({percentage_used}%)";
+ };
+
+ "hyprland/workspaces#rw" = {
+ "disable-scroll" = true;
+ "all-outputs" = true;
+ "warp-on-scroll" = false;
+ "sort-by-number" = true;
+ "show-special" = false;
+ "on-click" = "activate";
+ "on-scroll-up" = "hyprctl dispatch workspace e+1";
+ "on-scroll-down" = "hyprctl dispatch workspace e-1";
+ "persistent-workspaces" = {"*" = 5;};
+ format = "{icon} {windows}";
+ "format-window-separator" = " ";
+ "window-rewrite-default" = " ";
+ "window-rewrite" = {
+ "(.*) — Mozilla Firefox" = " $1";
+ "(.*) - fish" = "> [$1]";
+ "(.*) - zsh" = "> [$1]";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class" = " ";
+ "class<[Ss]ignal|signal-desktop|org.signal.Signal>" = " ";
+ "title<.*Signal.*>" = " ";
+ "class" = "🖥️ ";
+ "class<[Kk]denlive|org.kde.kdenlive>" = "🎬 ";
+ "title<.*Kdenlive.*>" = "🎬 ";
+
+ # qs-* apps
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title" = " ";
+ "title<^Wallpapers$>" = " ";
+ "title<^Video Wallpapers$>" = " ";
+ "title<^qs-wlogout$>" = " ";
+
+ # BoxBuddy
+ "class<[Bb]ox[Bb]uddy|io.github.dvlv.boxbuddy|io.github.dvlv.BoxBuddy>" = " ";
+ "title<.*BoxBuddy.*>" = " ";
+
+ # Bazaar software store
+ "class" = " ";
+ "title<^Bazaar$>" = " ";
+
+ # satty screenshot tool
+ "class" = " ";
+ "title<^satty$>" = " ";
+ };
+ };
+
+ "hyprland/window" = {
+ format = "{}";
+ "max-length" = 25;
+ "separate-outputs" = true;
+ "offscreen-css" = true;
+ "offscreen-css-text" = "(inactive)";
+ };
+
+ idle_inhibitor = {
+ tooltip = true;
+ "tooltip-format-activated" = "Idle_inhibitor active";
+ "tooltip-format-deactivated" = "Idle_inhibitor not active";
+ format = "{icon}";
+ "format-icons" = {
+ activated = " ";
+ deactivated = " ";
+ };
+ };
+
+ memory = {
+ interval = 10;
+ format = "{used:0.1f}G ";
+ "format-alt" = "{percentage}% ";
+ "format-alt-click" = "click";
+ tooltip = true;
+ "tooltip-format" = "{used:0.1f}GB/{total:0.1f}G";
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --btop";
+ };
+
+ "custom/weather" = {
+ "return-type" = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+
+ mpris = {
+ interval = 10;
+ format = "{player_icon} ";
+ "format-paused" = "{status_icon} {dynamic}";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "scroll-step" = 5.0;
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "smooth-scrolling-threshold" = 1;
+ tooltip = true;
+ "tooltip-format" = "{status_icon} {dynamic}\nLeft Click: previous\nMid Click: Pause\nRight Click: Next";
+ "player-icons" = {
+ chromium = "";
+ default = "";
+ firefox = "";
+ kdeconnect = "";
+ mopidy = "";
+ mpv = "";
+ spotify = "";
+ vlc = "";
+ };
+ "status-icons" = {
+ paused = "";
+ playing = "";
+ stopped = "";
+ };
+ "max-length" = 30;
+ };
+
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ "format-bluetooth" = "{icon} {volume}%";
+ "format-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ "hands-free" = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" "" ""];
+ "ignored-sinks" = ["Easy Effects Sink"];
+ };
+ "scroll-step" = 5.0;
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle";
+ "on-click-right" = "pavucontrol -t 3";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "tooltip-format" = "{icon} {desc} | {volume}%";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "pulseaudio#microphone" = {
+ format = "{format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic";
+ "on-click-right" = "pavucontrol -t 4";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --mic-inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --mic-dec";
+ "tooltip-format" = "{source_desc} | {source_volume}%";
+ "scroll-step" = 5;
+ };
+
+ tray = {
+ "icon-size" = 20;
+ spacing = 4;
+ };
+
+ # Groups
+ "group/mobo_drawer" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "cpu";
+ "transition-left-to-right" = true;
+ };
+ modules = ["temperature" "cpu" "power-profiles-daemon" "memory" "disk"];
+ };
+
+ "group/audio" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "pulseaudio";
+ "transition-left-to-right" = true;
+ };
+ modules = ["pulseaudio" "pulseaudio#microphone"];
+ };
+
+ "group/notify" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "custom/swaync";
+ "transition-left-to-right" = false;
+ };
+ modules = ["custom/swaync" "custom/dot_update"];
+ };
+
+ # Custom modules
+ "custom/power" = {
+ format = " ⏻ ";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ };
+
+ "custom/quit" = {
+ format = "";
+ "on-click" = "hyprctl dispatch exit";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Exit Hyprland";
+ };
+
+ "custom/swaync" = {
+ tooltip = true;
+ "tooltip-format" = "Left Click: Launch Notification Center\nRight Click: Do not Disturb";
+ format = "{} {icon} ";
+ # Coffee mug icon for all states
+ "format-icons" = {
+ notification = "";
+ none = "";
+ "dnd-notification" = "";
+ "dnd-none" = "";
+ "inhibited-notification" = "";
+ "inhibited-none" = "";
+ "dnd-inhibited-notification" = "";
+ "dnd-inhibited-none" = "";
+ };
+ "return-type" = "json";
+ "exec-if" = "which swaync-client";
+ exec = "swaync-client -swb";
+ "on-click" = "sleep 0.1 && swaync-client -t -sw";
+ "on-click-right" = "swaync-client -d -sw";
+ escape = true;
+ };
+
+ # Support modules referenced by groups
+ temperature = {
+ interval = 10;
+ tooltip = true;
+ "hwmon-path" = ["/sys/class/hwmon/hwmon1/temp1_input" "/sys/class/thermal/thermal_zone0/temp"];
+ "critical-threshold" = 82;
+ "format-critical" = "{temperatureC}°C {icon}";
+ format = "{temperatureC}°C {icon}";
+ "format-icons" = [""];
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --nvtop";
+ };
+
+ "power-profiles-daemon" = {
+ format = "{icon} ";
+ "tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
+ tooltip = true;
+ "format-icons" = {
+ default = "";
+ performance = "";
+ balanced = "";
+ "power-saver" = "";
+ };
+ };
+
+ "custom/dot_update" = {
+ format = " ";
+ "on-click" = "$HOME/.config/hypr/scripts/KooLsDotsUpdate.sh";
+ tooltip = true;
+ "tooltip-format" = "Check KooL Dots update\nIf available";
+ };
+ }
+ ];
+
+ # Compose style: wallust colors first, then base style, then our overrides
+ style = wallustColors + baseStyle + overrides;
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-jerry.nix b/home-manager/programs/hypr/waybar/waybar-jerry.nix
new file mode 100644
index 0000000..3d9890b
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jerry.nix
@@ -0,0 +1,356 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}: let
+ terminal = "kitty";
+ base00 = "0F1419";
+ base01 = "131721";
+ base03 = "3E4B59";
+ base05 = "E6E1CF";
+ base06 = "E6E1CF";
+ base07 = "F3F4F5";
+ base08 = "F07178";
+ base09 = "FF8F40";
+ base0A = "FFB454";
+ base0B = "B8CC52";
+ base0C = "95E6CB";
+ base0D = "59C2FF";
+ base0E = "D2A6FF";
+ base0F = "E6B673";
+in
+ with lib; {
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+
+ modules-center = ["network" "pulseaudio" "cpu" "hyprland/workspaces" "memory" "disk" "clock"]; # Eterna: [ "hyprland/window" ]
+ modules-left = ["custom/startmenu" "hyprland/window"]; # Eternal: [ "hyprland/workspaces" "cpu" "memory" "network" ]
+ modules-right = ["tray" "idle_inhibitor" "custom/notification" "battery" "custom/exit"]; # Eternal: [ "idle_inhibitor" "pulseaudio" "clock" "custom/notification" "tray" ]
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format = '' {:%H:%M}'';
+ /*
+ ''{: %I:%M %p}'';
+ */
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 60;
+ separate-outputs = false;
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ on-click = "${terminal} -e btop";
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ on-click = "${terminal} -e btop";
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ # Not working with zaneyos window open then closes
+ #on-click = "${terminal} -e sh -c df -h ; read";
+ };
+ "network" = {
+ format-icons = ["" "" "" "" ""];
+ format-ethernet = " {bandwidthDownBits}";
+ format-wifi = " {bandwidthDownBits}";
+ format-disconnected = "";
+ tooltip = false;
+ on-click = "${terminal} -e btop";
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ on-click = "pavucontrol";
+ };
+ "custom/exit" = {
+ tooltip = false;
+ format = "⏻";
+ on-click = "sleep 0.1 && wlogout";
+ };
+ "custom/startmenu" = {
+ tooltip = false;
+ format = " ";
+ # exec = "rofi -show drun";
+ on-click = "rofi -show drun";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = " ";
+ deactivated = " ";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "swaync-client -t";
+ escape = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = ["" "" "" "" "" "" "" "" "" ""];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-size: 16px;
+ font-family: JetBrainsMono Nerd Font, Font Awesome, sans-serif;
+ font-weight: bold;
+ }
+ window#waybar {
+ /*
+
+ background-color: rgba(26,27,38,0);
+ border-bottom: 1px solid rgba(26,27,38,0);
+ border-radius: 0px;
+ color: #${base0F};
+ */
+
+ background-color: rgba(26,27,38,0);
+ border-bottom: 1px solid rgba(26,27,38,0);
+ border-radius: 0px;
+ color: #${base0F};
+ }
+ #workspaces {
+ /*
+ Eternal
+ background: linear-gradient(180deg, #${base00}, #${base01});
+ margin: 5px 5px 5px 0px;
+ padding: 0px 10px;
+ border-radius: 0px 15px 50px 0px;
+ border: 0px;
+ font-style: normal;
+ color: #${base00};
+ */
+ background: linear-gradient(45deg, #${base01}, #${base01});
+ margin: 5px;
+ padding: 0px 1px;
+ border-radius: 15px;
+ border: 0px;
+ font-style: normal;
+ color: #${base00};
+ }
+ #workspaces button {
+ padding: 0px 5px;
+ margin: 4px 3px;
+ border-radius: 15px;
+ border: 0px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 0.5;
+ transition: all 0.3s ease-in-out;
+ }
+ #workspaces button.active {
+ padding: 0px 5px;
+ margin: 4px 3px;
+ border-radius: 15px;
+ border: 0px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 1.0;
+ min-width: 40px;
+ transition: all 0.3s ease-in-out;
+ }
+ #workspaces button:hover {
+ border-radius: 15px;
+ color: #${base00};
+ background: linear-gradient(45deg, #${base0D}, #${base0E});
+ opacity: 0.8;
+ }
+ tooltip {
+ background: #${base00};
+ border: 1px solid #${base0E};
+ border-radius: 10px;
+ }
+ tooltip label {
+ color: #${base07};
+ }
+ #window {
+ /*
+ Eternal
+ color: #${base05};
+ background: #${base00};
+ border-radius: 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ margin: 5px;
+ padding: 2px 20px;
+ color: #${base05};
+ background: #${base01};
+ border-radius: 50px 15px 50px 15px;
+ }
+ #memory {
+ color: #${base0F};
+ /*
+ Eternal
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ background: #${base01};
+ margin: 5px;
+ padding: 2px 20px;
+ border-radius: 15px 50px 15px 50px;
+ }
+ #clock {
+ color: #${base0B};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #idle_inhibitor {
+ color: #${base0A};
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #cpu {
+ color: #${base07};
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #disk {
+ color: #${base0F};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #battery {
+ color: #${base08};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #network {
+ color: #${base09};
+ background: #${base00};
+ border-radius: 50px 15px 50px 15px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #tray {
+ color: #${base05};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #pulseaudio {
+ color: #${base0D};
+ /*
+ Eternal
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ */
+ background: #${base01};
+ margin: 4px;
+ padding: 2px 20px;
+ border-radius: 50px 15px 50px 15px;
+ }
+ #custom-notification {
+ color: #${base0C};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #custom-startmenu {
+ color: #${base0E};
+ background: #${base00};
+ border-radius: 0px 15px 50px 0px;
+ margin: 5px 5px 5px 0px;
+ padding: 2px 20px;
+ }
+ #idle_inhibitor {
+ color: #${base09};
+ background: #${base00};
+ border-radius: 15px 50px 15px 50px;
+ margin: 5px;
+ padding: 2px 20px;
+ }
+ #custom-exit {
+ color: #${base0E};
+ background: #${base00};
+ border-radius: 15px 0px 0px 50px;
+ margin: 5px 0px 5px 5px;
+ padding: 2px 20px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-jwt-catppuccin.nix b/home-manager/programs/hypr/waybar/waybar-jwt-catppuccin.nix
new file mode 100644
index 0000000..3db7f3b
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jwt-catppuccin.nix
@@ -0,0 +1,776 @@
+{pkgs, ...}: let
+ # Install any helper scripts shipped in modules/home/waybar/scripts into ~/.config/waybar/scripts
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ # Inline, improved Cava script packaged via Nix so we don't rely on an external bash file
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+
+ # Ensure cava exists
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+
+ # Characters for vertical bars (0..7)
+ bar="▁▂▃▄▅▆▇█"
+
+ # Build sed script that:
+ # - strips semicolons (cava RAW ASCII delimiter)
+ # - maps digits 0..7 to the corresponding glyph in $bar
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+
+ # Single-instance guard (kill prior instance cleanly)
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ # Give the old pipeline a moment to exit
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+
+ # Use a unique temporary config and clean it up on exit
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() {
+ rm -f "$config_file" "$pidfile"
+ }
+ trap cleanup EXIT INT TERM
+
+ cat >"$config_file" < box > #idle_inhibitor {
+ color: #f38ba8; /* red by default */
+ }
+
+ window#waybar > box > #idle_inhibitor.activated {
+ color: #a6e3a1; /* green when activated */
+ }
+
+ window#waybar > box > #idle_inhibitor.deactivated {
+ color: #f38ba8; /* red when deactivated */
+ }
+
+ tooltip {
+ background: @base;
+ border-radius: 7px;
+ }
+
+ button {
+ box-shadow: inset 0 3px transparent;
+ border: none;
+ border-radius: 0;
+ }
+
+ button:hover {
+ background: inherit;
+ }
+
+ #pulseaudio:hover {
+ background-color: @mantle;
+ }
+
+ #workspaces button {
+ padding: 0 5px;
+ background-color: transparent;
+ }
+
+ #workspaces button:hover {
+ background: rgba(0, 0, 0, 0.3);
+ border-radius: 7px;
+ }
+
+ /* Hyprland workspaces - based on working waybar-jak-catppuccin */
+ #workspaces button {
+ color: @sapphire; /* default/inactive workspaces - pale blue */
+ background-color: transparent;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-right: 6px;
+ padding-left: 4px;
+ }
+
+ #workspaces button.active {
+ color: @green; /* active workspace - green */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button.focused {
+ color: @rosewater; /* focused workspace - rosewater */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button.urgent {
+ color: @crust;
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button:hover {
+ background: transparent;
+ color: @flamingo;
+ border-radius: 15px;
+ }
+
+ #workspaces button.empty {
+ color: @red; /* empty workspace - red */
+ }
+
+ #workspaces button.urgent {
+ background-color: #eb4d4b;
+ }
+
+ #mode {
+ background-color: #64727d;
+ box-shadow: inset 0 0px #ffffff;
+ background: rgba(5, 5, 5, 0.3);
+ color: #000000;
+ padding: 1px 10px 1px 10px;
+ border-radius: 0px 0px 0px 0px;
+ margin-top: 5px;
+ }
+
+ #clock,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #temperature,
+ #backlight,
+ #network,
+ #custom-spotify,
+ #pulseaudio,
+ #wireplumber,
+ #custom-media,
+ #custom-waypaper,
+ #tray,
+ #mode,
+ #custom-weather,
+ #idle_inhibitor,
+ #scratchpad,
+ #power-profiles-daemon,
+ #custom-cava,
+ #custom-cava_mviz,
+ #custom-gpt,
+ #custom-mspowers,
+ #custom-qs-wallpaper,
+ #custom-qs-vid-wallpaper,
+ #custom-swaync,
+ #mpd {
+ background: @base;
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+
+ #window,
+ #workspaces {
+ background: @base;
+ color: @rosewater;
+ padding: 1px 1px 1px 1px;
+ margin-top: 5px;
+ }
+
+ .modules-left > widget:first-child > #workspaces {
+ margin-left: 5px;
+ }
+
+ .modules-right > widget:last-child > #workspaces {
+ margin-right: 0;
+ }
+
+ #clock {
+ color: @pink;
+ margin-top: 5px;
+ margin-right: 5px;
+ }
+
+ #custom-mspowers {
+ color: @yellow;
+ margin-top: 5px;
+ }
+
+ #clock:hover {
+ background-color: @mantle;
+ }
+
+ #custom-weather {
+ color: @sky;
+ padding: 1px 6px 1px 8px;
+ }
+
+ #custom-spotify {
+ color: @maroon;
+ padding: 1px 6px 1px 8px;
+ }
+
+ #custom-waypaper:hover {
+ background-color: @mantle;
+ }
+
+ #custom-cava,
+ #custom-cava_mviz {
+ background: @base;
+ color: @mauve;
+ padding: 1px 10px;
+ margin-left: 8px;
+ }
+
+ #custom-cava:hover,
+ #custom-cava_mviz:hover {
+ background-color: @mantle;
+ }
+
+ #custom-gpt {
+ font-size: 20px;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 15px 15px;
+ color: @mauve;
+ border-radius: 7px;
+ }
+
+ #custom-gpt:hover {
+ background-color: @mantle;
+ }
+
+ #custom-weather:hover {
+ background-color: @mantle;
+ }
+
+ #cava-player .status {
+ font-size: 18px;
+ color: #ffffff;
+ }
+
+ #custom-power {
+ color: @mauve;
+ background-color: @base;
+ margin-right: 5px;
+ margin-top: 5px;
+ padding: 1px 5px 1px 2px;
+ }
+
+ #custom-power:hover {
+ background-color: @mantle;
+ }
+
+ #custom-menu {
+ color: @blue;
+ background-color: @base;
+ margin-left: 5px;
+ margin-top: 5px;
+ padding: 1px 10px 1px 10px;
+ font-size: 18px;
+ min-width: 30px;
+ }
+
+ #custom-menu:hover {
+ background-color: @mantle;
+ }
+
+ #custom-qs-wallpaper,
+ #custom-qs-vid-wallpaper {
+ color: @sapphire;
+ background-color: @base;
+ font-size: 18px;
+ min-width: 20px;
+ }
+
+ #custom-qs-wallpaper:hover,
+ #custom-qs-vid-wallpaper:hover {
+ background-color: @mantle;
+ }
+
+ #custom-swaync {
+ color: @green;
+ background-color: @base;
+ }
+
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification,
+ #custom-swaync.dnd-inhibited-notification {
+ color: @red;
+ }
+
+ #custom-swaync:hover {
+ background-color: @mantle;
+ }
+
+ #battery {
+ color: @mauve;
+ }
+
+ #battery.charging,
+ #battery.plugged {
+ color: @green;
+ }
+
+ @keyframes blink {
+ to {
+ background: @base;
+ color: #000000;
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+ }
+
+ #battery.critical:not(.charging) {
+ color: #ffffff;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: steps(12);
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ #battery:hover {
+ background-color: @mantle;
+ }
+
+ #power-profiles-daemon {
+ padding-right: 15px;
+ color: #000000;
+ }
+
+ #power-profiles-daemon.performance {
+ color: #ffffff;
+ }
+
+ #power-profiles-daemon.balanced {
+ color: #ffffff;
+ }
+
+ #power-profiles-daemon.power-saver {
+ color: #000000;
+ }
+
+ label:focus {
+ background: @base;
+ }
+
+ #memory {
+ color: @yellow;
+ }
+
+ #memory:hover {
+ background-color: @mantle;
+ }
+
+ #disk {
+ background: @base;
+ }
+
+ #backlight {
+ color: @green;
+ }
+
+ #backlight:hover {
+ background-color: @mantle;
+ }
+
+ #network {
+ color: @peach;
+ }
+
+ #network.disconnected {
+ color: @red;
+ }
+
+ #network:hover {
+ background-color: @mantle;
+ }
+
+ #pulseaudio {
+ color: @peach;
+ }
+
+ #pulseaudio.muted {
+ color: @peach;
+ }
+
+ #temperature {
+ background: @base;
+ color: @yellow;
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+
+ #temperature.critical {
+ background-color: #eb4d4b;
+ }
+
+ /* Idle inhibitor - comprehensive targeting without !important */
+ #idle_inhibitor,
+ .idle_inhibitor,
+ button#idle_inhibitor,
+ .module#idle_inhibitor,
+ window#waybar #idle_inhibitor,
+ window#waybar .idle_inhibitor,
+ window#waybar button#idle_inhibitor {
+ color: #f38ba8; /* red when deactivated */
+ background-color: #1e1e2e;
+ }
+
+ #idle_inhibitor.activated,
+ .idle_inhibitor.activated,
+ button#idle_inhibitor.activated,
+ .module#idle_inhibitor.activated,
+ window#waybar #idle_inhibitor.activated,
+ window#waybar .idle_inhibitor.activated,
+ window#waybar button#idle_inhibitor.activated {
+ color: #a6e3a1; /* green when activated */
+ background-color: #1e1e2e;
+ }
+
+ #idle_inhibitor.deactivated,
+ .idle_inhibitor.deactivated,
+ button#idle_inhibitor.deactivated,
+ .module#idle_inhibitor.deactivated,
+ window#waybar #idle_inhibitor.deactivated,
+ window#waybar .idle_inhibitor.deactivated,
+ window#waybar button#idle_inhibitor.deactivated {
+ color: #f38ba8; /* red when deactivated */
+ background-color: #1e1e2e;
+ }
+
+ #idle_inhibitor:hover {
+ background-color: @mantle;
+ }
+
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-jwt-transparent.nix b/home-manager/programs/hypr/waybar/waybar-jwt-transparent.nix
new file mode 100644
index 0000000..4a8fc1b
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jwt-transparent.nix
@@ -0,0 +1,711 @@
+{pkgs, ...}: let
+ # Install any helper scripts shipped in modules/home/waybar/scripts into ~/.config/waybar/scripts
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ # Inline, improved Cava script packaged via Nix so we don't rely on an external bash file
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+
+ # Ensure cava exists
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+
+ # Characters for vertical bars (0..7)
+ bar="▁▂▃▄▅▆▇█"
+
+ # Build sed script that:
+ # - strips semicolons (cava RAW ASCII delimiter)
+ # - maps digits 0..7 to the corresponding glyph in $bar
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+
+ # Single-instance guard (kill prior instance cleanly)
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ # Give the old pipeline a moment to exit
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+
+ # Use a unique temporary config and clean it up on exit
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() {
+ rm -f "$config_file" "$pidfile"
+ }
+ trap cleanup EXIT INT TERM
+
+ cat >"$config_file" < box {
+ margin: 4px 8px 0 8px;
+ padding: 2px;
+ background-color: rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ }
+
+ tooltip {
+ background: rgb(30, 30, 46);
+ border-radius: 7px;
+ }
+
+ button {
+ box-shadow: inset 0 3px transparent;
+ border: none;
+ border-radius: 0;
+ }
+
+ button:hover {
+ background: inherit;
+ }
+
+ #workspaces button {
+ padding: 0 5px;
+ background-color: transparent;
+ }
+
+ #workspaces button:hover {
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 7px;
+ }
+
+ /* Hyprland workspaces - based on working waybar-jak-catppuccin */
+ #workspaces button {
+ color: #74c7ec; /* default/inactive workspaces - sapphire */
+ background-color: transparent;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-right: 6px;
+ padding-left: 4px;
+ }
+
+ #workspaces button.active {
+ color: #a6e3a1; /* active workspace - green */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button.focused {
+ color: #f5e0dc; /* focused workspace - rosewater */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button.urgent {
+ color: #11111b; /* crust */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button:hover {
+ background: transparent;
+ color: #f2cdcd; /* flamingo */
+ border-radius: 15px;
+ }
+
+ #workspaces button.empty {
+ color: #f38ba8; /* empty workspace - red */
+ }
+
+ #workspaces button.urgent {
+ background-color: #eb4d4b;
+ }
+
+ #mode {
+ background-color: #64727d;
+ box-shadow: inset 0 0px #ffffff;
+ background: rgba(5, 5, 5, 0.3);
+ color: #000000;
+ padding: 1px 10px 1px 10px;
+ border-radius: 0px 0px 0px 0px;
+ margin-top: 5px;
+ }
+
+ #clock,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #temperature,
+ #backlight,
+ #network,
+ #custom-spotify,
+ #pulseaudio,
+ #wireplumber,
+ #custom-media,
+ #custom-waypaper,
+ #tray,
+ #mode,
+ #custom-weather,
+ #idle_inhibitor,
+ #scratchpad,
+ #custom-power #power-profiles-daemon,
+ #custom-cava,
+ #custom-cava_mviz,
+ #custom-gpt,
+ #custom-menu,
+ #custom-qs-wallpaper,
+ #custom-qs-vid-wallpaper,
+ #custom-swaync,
+ #mpd {
+ background: rgba(30, 30, 46, 0);
+ padding: 1px 10px 1px 10px;
+ }
+
+ #window,
+ #workspaces {
+ color: #f5e0dc;
+ padding: 1px 1px 1px 1px;
+ }
+
+ .modules-right > widget:last-child > #workspaces {
+ margin-right: 0;
+ }
+
+ #clock {
+ color: #ffffff;
+ margin-right: 5px;
+ }
+
+ #clock:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-weather {
+ color: #ffffff;
+ padding: 1px 6px 1px 8px;
+ }
+
+ #custom-weather:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-spotify {
+ color: #ffffff;
+ padding: 1px 6px 1px 8px;
+ }
+
+ #custom-spotify:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-cava,
+ #custom-cava_mviz {
+ background: rgb(30, 30, 46);
+ color: #ffffff;
+ padding: 1px 10px;
+ margin-left: 8px;
+ }
+
+ #custom-cava:hover,
+ #custom-cava_mviz:hover {
+ background-color: #181825;
+ }
+
+ #custom-gpt {
+ font-size: 20px;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 15px 15px;
+ color: #ffffff;
+ border-radius: 7px;
+ }
+
+ #custom-gpt:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #cava-player .status {
+ font-size: 18px;
+ color: #ffffff;
+ }
+
+ #custom-power {
+ color: #ffffff;
+ padding: 1px 5px 1px 3px;
+ margin-right: 1px;
+ }
+
+ #custom-power:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-menu {
+ color: #89b4fa;
+ padding: 1px 10px 1px 10px;
+ margin-left: 5px;
+ }
+
+ #custom-menu:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-qs-wallpaper,
+ #custom-qs-vid-wallpaper {
+ color: #74c7ec;
+ }
+
+ #custom-qs-wallpaper:hover,
+ #custom-qs-vid-wallpaper:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-swaync {
+ color: #a6e3a1;
+ }
+
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification,
+ #custom-swaync.dnd-inhibited-notification {
+ color: #f38ba8;
+ }
+
+ #custom-swaync:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #battery {
+ color: #ffffff;
+ }
+
+ #battery.charging,
+ #battery.plugged {
+ color: #85eb81;
+ }
+
+ #battery:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ @keyframes blink {
+ to {
+ background: rgb(30, 30, 46);
+ color: #000000;
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+ }
+
+ #battery.critical:not(.charging) {
+ color: #ffffff;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: steps(12);
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ #power-profiles-daemon {
+ padding-right: 15px;
+ color: #000000;
+ }
+
+ #power-profiles-daemon.performance {
+ color: #ffffff;
+ }
+
+ #power-profiles-daemon.balanced {
+ color: #ffffff;
+ }
+
+ #power-profiles-daemon.power-saver {
+ color: #000000;
+ }
+
+ label:focus {
+ background: rgb(30, 30, 46);
+ }
+
+ #memory {
+ color: #ffffff;
+ padding: 1px 9px 1px 5px;
+ }
+
+ #memory:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #disk {
+ background: rgb(30, 30, 46);
+ }
+
+ #backlight {
+ color: #ffffff;
+ }
+
+ #network {
+ color: #ffffff;
+ }
+
+ #network.disconnected {
+ color: #f2564b;
+ }
+
+ #network:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #pulseaudio {
+ color: #ffffff;
+ }
+
+ #pulseaudio.muted {
+ color: #ffffff;
+ }
+
+ #wireplumber {
+ color: #000000;
+ }
+
+ #pulseaudio:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #wireplumber.muted {
+ background: rgb(30, 30, 46);
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+
+ #custom-media {
+ color: #2a5c45;
+ min-width: 100px;
+ }
+
+ #custom-media.custom-spotify {
+ background: rgb(30, 30, 46);
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+
+ #custom-media.custom-vlc {
+ background: rgb(30, 30, 46);
+ margin-top: 5px;
+ }
+
+ #temperature {
+ color: #ffffff;
+ }
+
+ #temperature.critical {
+ background-color: #eb4d4b;
+ }
+
+ #temperature:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #tray {
+ background-color: #2980b9;
+ }
+
+ #tray > .passive {
+ -gtk-icon-effect: dim;
+ }
+
+ #tray > .needs-attention {
+ -gtk-icon-effect: highlight;
+ background-color: #eb4d4b;
+ }
+
+ /* Idle inhibitor - coffee mug color changes */
+ #idle_inhibitor {
+ color: #f38ba8; /* default red (deactivated) */
+ }
+
+ #idle_inhibitor.activated {
+ color: #a6e3a1; /* green when activated */
+ }
+
+ #idle_inhibitor.deactivated {
+ color: #f38ba8; /* red when deactivated */
+ }
+
+ #idle_inhibitor:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-jwt-ultradark.nix b/home-manager/programs/hypr/waybar/waybar-jwt-ultradark.nix
new file mode 100644
index 0000000..59e9303
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-jwt-ultradark.nix
@@ -0,0 +1,711 @@
+{pkgs, ...}: let
+ # Install any helper scripts shipped in modules/home/waybar/scripts into ~/.config/waybar/scripts
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ # Inline, improved Cava script packaged via Nix so we don't rely on an external bash file
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+
+ # Ensure cava exists
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+
+ # Characters for vertical bars (0..7)
+ bar="▁▂▃▄▅▆▇█"
+
+ # Build sed script that:
+ # - strips semicolons (cava RAW ASCII delimiter)
+ # - maps digits 0..7 to the corresponding glyph in $bar
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+
+ # Single-instance guard (kill prior instance cleanly)
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ # Give the old pipeline a moment to exit
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+
+ # Use a unique temporary config and clean it up on exit
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() {
+ rm -f "$config_file" "$pidfile"
+ }
+ trap cleanup EXIT INT TERM
+
+ cat >"$config_file" < box {
+ margin: 4px 8px 0 8px;
+ padding: 2px;
+ background-color: rgba(0, 0, 0, 1);
+ border-radius: 8px;
+ }
+
+ tooltip {
+ background: rgb(30, 30, 46);
+ border-radius: 7px;
+ }
+
+ button {
+ box-shadow: inset 0 3px transparent;
+ border: none;
+ border-radius: 0;
+ }
+
+ button:hover {
+ background: inherit;
+ }
+
+ #workspaces button {
+ padding: 0 5px;
+ background-color: transparent;
+ }
+
+ #workspaces button:hover {
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 7px;
+ }
+
+ /* Hyprland workspaces - based on working waybar-jak-catppuccin */
+ #workspaces button {
+ color: #74c7ec; /* default/inactive workspaces - sapphire */
+ background-color: transparent;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-right: 6px;
+ padding-left: 4px;
+ }
+
+ #workspaces button.active {
+ color: #a6e3a1; /* active workspace - green */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button.focused {
+ color: #f5e0dc; /* focused workspace - rosewater */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button.urgent {
+ color: #11111b; /* crust */
+ background: transparent;
+ border-radius: 15px;
+ }
+
+ #workspaces button:hover {
+ background: transparent;
+ color: #f2cdcd; /* flamingo */
+ border-radius: 15px;
+ }
+
+ #workspaces button.empty {
+ color: #f38ba8; /* empty workspace - red */
+ }
+
+ #workspaces button.urgent {
+ background-color: #eb4d4b;
+ }
+
+ #mode {
+ background-color: #64727d;
+ box-shadow: inset 0 0px #ffffff;
+ background: rgba(5, 5, 5, 0.3);
+ color: #000000;
+ padding: 1px 10px 1px 10px;
+ border-radius: 0px 0px 0px 0px;
+ margin-top: 5px;
+ }
+
+ #clock,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #temperature,
+ #backlight,
+ #network,
+ #custom-spotify,
+ #pulseaudio,
+ #wireplumber,
+ #custom-media,
+ #custom-waypaper,
+ #tray,
+ #mode,
+ #custom-weather,
+ #idle_inhibitor,
+ #scratchpad,
+ #custom-power #power-profiles-daemon,
+ #custom-cava,
+ #custom-cava_mviz,
+ #custom-gpt,
+ #custom-menu,
+ #custom-qs-wallpaper,
+ #custom-qs-vid-wallpaper,
+ #custom-swaync,
+ #mpd {
+ background: rgba(30, 30, 46, 0);
+ padding: 1px 10px 1px 10px;
+ }
+
+ #window,
+ #workspaces {
+ color: #f5e0dc;
+ padding: 1px 1px 1px 1px;
+ }
+
+ .modules-right > widget:last-child > #workspaces {
+ margin-right: 0;
+ }
+
+ #clock {
+ color: #e5e5e5;
+ margin-right: 5px;
+ }
+
+ #clock:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-weather {
+ color: #e5e5e5;
+ padding: 1px 6px 1px 8px;
+ }
+
+ #custom-weather:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-spotify {
+ color: #e5e5e5;
+ padding: 1px 6px 1px 8px;
+ }
+
+ #custom-spotify:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-cava,
+ #custom-cava_mviz {
+ background: rgb(30, 30, 46);
+ color: #e5e5e5;
+ padding: 1px 10px;
+ margin-left: 8px;
+ }
+
+ #custom-cava:hover,
+ #custom-cava_mviz:hover {
+ background-color: #181825;
+ }
+
+ #custom-gpt {
+ font-size: 20px;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 15px 15px;
+ color: #e5e5e5;
+ border-radius: 7px;
+ }
+
+ #custom-gpt:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #cava-player .status {
+ font-size: 18px;
+ color: #e5e5e5;
+ }
+
+ #custom-power {
+ color: #e5e5e5;
+ padding: 1px 5px 1px 3px;
+ margin-right: 1px;
+ }
+
+ #custom-power:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-menu {
+ color: #89b4fa;
+ padding: 1px 10px 1px 10px;
+ margin-left: 5px;
+ }
+
+ #custom-menu:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-qs-wallpaper,
+ #custom-qs-vid-wallpaper {
+ color: #74c7ec;
+ }
+
+ #custom-qs-wallpaper:hover,
+ #custom-qs-vid-wallpaper:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #custom-swaync {
+ color: #a6e3a1;
+ }
+
+ #custom-swaync.notification,
+ #custom-swaync.dnd-notification,
+ #custom-swaync.inhibited-notification,
+ #custom-swaync.dnd-inhibited-notification {
+ color: #f38ba8;
+ }
+
+ #custom-swaync:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #battery {
+ color: #e5e5e5;
+ }
+
+ #battery.charging,
+ #battery.plugged {
+ color: #85eb81;
+ }
+
+ #battery:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ @keyframes blink {
+ to {
+ background: rgb(30, 30, 46);
+ color: #000000;
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+ }
+
+ #battery.critical:not(.charging) {
+ color: #e5e5e5;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: steps(12);
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ #power-profiles-daemon {
+ padding-right: 15px;
+ color: #000000;
+ }
+
+ #power-profiles-daemon.performance {
+ color: #e5e5e5;
+ }
+
+ #power-profiles-daemon.balanced {
+ color: #e5e5e5;
+ }
+
+ #power-profiles-daemon.power-saver {
+ color: #000000;
+ }
+
+ label:focus {
+ background: rgb(30, 30, 46);
+ }
+
+ #memory {
+ color: #e5e5e5;
+ padding: 1px 9px 1px 5px;
+ }
+
+ #memory:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #disk {
+ background: rgb(30, 30, 46);
+ }
+
+ #backlight {
+ color: #e5e5e5;
+ }
+
+ #network {
+ color: #e5e5e5;
+ }
+
+ #network.disconnected {
+ color: #f2564b;
+ }
+
+ #network:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #pulseaudio {
+ color: #e5e5e5;
+ }
+
+ #pulseaudio.muted {
+ color: #e5e5e5;
+ }
+
+ #wireplumber {
+ color: #000000;
+ }
+
+ #pulseaudio:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #wireplumber.muted {
+ background: rgb(30, 30, 46);
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+
+ #custom-media {
+ color: #2a5c45;
+ min-width: 100px;
+ }
+
+ #custom-media.custom-spotify {
+ background: rgb(30, 30, 46);
+ padding: 1px 10px 1px 10px;
+ margin-top: 5px;
+ }
+
+ #custom-media.custom-vlc {
+ background: rgb(30, 30, 46);
+ margin-top: 5px;
+ }
+
+ #temperature {
+ color: #e5e5e5;
+ }
+
+ #temperature.critical {
+ background-color: #eb4d4b;
+ }
+
+ #temperature:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+
+ #tray {
+ background-color: #2980b9;
+ }
+
+ #tray > .passive {
+ -gtk-icon-effect: dim;
+ }
+
+ #tray > .needs-attention {
+ -gtk-icon-effect: highlight;
+ background-color: #eb4d4b;
+ }
+
+ /* Idle inhibitor - coffee mug color changes */
+ #idle_inhibitor {
+ color: #f38ba8; /* default red (deactivated) */
+ }
+
+ #idle_inhibitor.activated {
+ color: #a6e3a1; /* green when activated */
+ }
+
+ #idle_inhibitor.deactivated {
+ color: #f38ba8; /* red when deactivated */
+ }
+
+ #idle_inhibitor:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-mangowc-jak-catppuccin.nix b/home-manager/programs/hypr/waybar/waybar-mangowc-jak-catppuccin.nix
new file mode 100644
index 0000000..6a18fcb
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-mangowc-jak-catppuccin.nix
@@ -0,0 +1,568 @@
+{pkgs, ...}: let
+ scriptsDir = ../waybar/scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+ bar="▁▂▃▄▅▆▇█"
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() { rm -f "$config_file" "$pidfile"; }
+ trap cleanup EXIT INT TERM
+ cat >"$config_file" <{calendar}";
+ calendar = {
+ mode = "year";
+ "mode-mon-col" = 3;
+ "weeks-pos" = "right";
+ "on-scroll" = 1;
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "W{:%V}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ "on-click-right" = "mode";
+ "on-click-forward" = "tz_up";
+ "on-click-backward" = "tz_down";
+ "on-scroll-up" = "shift_up";
+ "on-scroll-down" = "shift_down";
+ };
+ };
+
+ cpu = {
+ format = "{usage}% ";
+ interval = 1;
+ "min-length" = 5;
+ "format-alt-click" = "click";
+ "format-alt" = "{icon0}{icon1}{icon2}{icon3} {usage:>2}% ";
+ "format-icons" = ["▁" "▂" "▃" "▄" "▅" "▆" "▇" "█"];
+ "on-click-right" = "gnome-system-monitor";
+ };
+
+ disk = {
+ interval = 30;
+ path = "/";
+ format = "{percentage_used}% ";
+ "tooltip-format" = "{used} used out of {total} on {path} ({percentage_used}%)";
+ };
+
+ idle_inhibitor = {
+ tooltip = true;
+ "tooltip-format-activated" = "Idle_inhibitor active";
+ "tooltip-format-deactivated" = "Idle_inhibitor not active";
+ format = "{icon}";
+ "format-icons" = {
+ activated = " ";
+ deactivated = " ";
+ };
+ };
+
+ "keyboard-state" = {
+ capslock = true;
+ format = {
+ numlock = "N {icon}";
+ capslock = " {icon}";
+ };
+ "format-icons" = {
+ locked = "";
+ unlocked = "";
+ };
+ };
+
+ memory = {
+ interval = 10;
+ format = "{used:0.1f}G ";
+ "format-alt" = "{percentage}% ";
+ "format-alt-click" = "click";
+ tooltip = true;
+ "tooltip-format" = "{used:0.1f}GB/{total:0.1f}G";
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --btop";
+ };
+
+ network = {
+ format = "{ifname}";
+ "format-wifi" = "{icon}";
+ "format-ethernet" = "";
+ "format-disconnected" = "";
+ "tooltip-format" = "{ipaddr} {bandwidthUpBits} {bandwidthDownBits}";
+ "format-linked" = " {ifname} (No IP)";
+ "tooltip-format-wifi" = "{essid} {icon} {signalStrength}%";
+ "tooltip-format-ethernet" = "{ifname} ";
+ "tooltip-format-disconnected" = " Disconnected";
+ "max-length" = 30;
+ "format-icons" = ["" "" "" "" ""];
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --nmtui";
+ };
+
+ "network#speed" = {
+ interval = 1;
+ format = "{ifname}";
+ "format-wifi" = "{icon} {bandwidthUpBytes} {bandwidthDownBytes}";
+ "format-ethernet" = " {bandwidthUpBytes} {bandwidthDownBytes}";
+ "format-disconnected" = "";
+ "tooltip-format" = "{ipaddr}";
+ "format-linked" = " {ifname} (No IP)";
+ "tooltip-format-wifi" = "{essid} {icon} {signalStrength}%";
+ "tooltip-format-ethernet" = "{ifname} ";
+ "tooltip-format-disconnected" = " Disconnected";
+ "min-length" = 24;
+ "max-length" = 24;
+ "format-icons" = ["" "" "" "" ""];
+ };
+
+ "power-profiles-daemon" = {
+ format = "{icon} ";
+ "tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
+ tooltip = true;
+ "format-icons" = {
+ default = "";
+ performance = "";
+ balanced = "";
+ "power-saver" = "";
+ };
+ };
+
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ "format-bluetooth" = "{icon} {volume}%";
+ "format-muted" = "";
+ "format-icons" = {
+ headphone = "";
+ "hands-free" = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" "" ""];
+ "ignored-sinks" = ["Easy Effects Sink"];
+ };
+ "scroll-step" = 5.0;
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle";
+ "on-click-right" = "pavucontrol -t 3";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "tooltip-format" = "{icon} {desc} | {volume}%";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "pulseaudio#microphone" = {
+ format = "{format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = "";
+ "on-click" = "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic";
+ "on-click-right" = "pavucontrol -t 4";
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --mic-inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --mic-dec";
+ "tooltip-format" = "{source_desc} | {source_volume}%";
+ "scroll-step" = 5;
+ };
+
+ tray = {
+ "icon-size" = 20;
+ spacing = 4;
+ };
+
+ "group/audio" = {
+ orientation = "inherit";
+ drawer = {
+ "transition-duration" = 500;
+ "children-class" = "pulseaudio";
+ "transition-left-to-right" = true;
+ };
+ modules = ["pulseaudio" "pulseaudio#microphone"];
+ };
+
+ "custom/weather" = {
+ return-type = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.config/mangowc/waybar/scripts/Weather.py'";
+ interval = 600;
+ tooltip = true;
+ };
+
+ "custom/file_manager" = {
+ format = " ";
+ "on-click" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --files";
+ tooltip = true;
+ "tooltip-format" = "File Manager";
+ };
+ "custom/tty" = {
+ format = " ";
+ "on-click" = "$HOME/.config/hypr/scripts/WaybarScripts.sh --term";
+ tooltip = true;
+ "tooltip-format" = "Launch Terminal";
+ };
+ "custom/browser" = {
+ format = " ";
+ "on-click" = "xdg-open https://";
+ tooltip = true;
+ "tooltip-format" = "Launch Browser";
+ };
+ "custom/settings" = {
+ format = " ";
+ "on-click" = "$HOME/.config/hypr/scripts/Kool_Quick_Settings.sh";
+ tooltip = true;
+ "tooltip-format" = "Launch KooL Settings Menu";
+ };
+
+ "custom/qs_wallpapers_apply" = {
+ format = " ";
+ "on-click" = "qs-wallpapers-apply";
+ tooltip = true;
+ "tooltip-format" = "Set wallpaper";
+ };
+ "custom/qs_vid_wallpapers_apply" = {
+ format = " ";
+ "on-click" = "qs-vid-wallpapers-apply";
+ tooltip = true;
+ "tooltip-format" = "Set video wallpaper";
+ };
+
+ "custom/light_dark" = {
+ format = " ";
+ "on-click" = "$HOME/.config/hypr/scripts/DarkLight.sh";
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarStyles.sh";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Switch Dark-Light Themes\nRight Click: Waybar Styles Menu";
+ };
+ "custom/lock" = {
+ format = "";
+ "on-click" = "$HOME/.config/hypr/scripts/LockScreen.sh";
+ tooltip = true;
+ "tooltip-format" = " Screen Lock";
+ };
+ "custom/menu" = {
+ format = " ";
+ "on-click" = "launch-nwg-menu";
+ "on-click-right" = "$HOME/.config/hypr/scripts/WaybarLayout.sh";
+ tooltip = true;
+ "tooltip-format" = "Left Click: App Menu\nRight Click: Waybar Layout Menu";
+ };
+ "custom/startmenu" = {
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ format = "";
+ on-click = "launch-nwg-menu";
+ };
+
+ "custom/cava_mviz" = {
+ exec = "${waybarCava}/bin/WaybarCava";
+ format = "[ {} ]";
+ };
+
+ "custom/playerctl" = {
+ format = "{}";
+ "return-type" = "json";
+ "max-length" = 25;
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ "on-click-middle" = "playerctl play-pause";
+ "on-click" = "playerctl previous";
+ "on-click-right" = "playerctl next";
+ "scroll-step" = 5.0;
+ "on-scroll-up" = "$HOME/.config/hypr/scripts/Volume.sh --inc";
+ "on-scroll-down" = "$HOME/.config/hypr/scripts/Volume.sh --dec";
+ "smooth-scrolling-threshold" = 1;
+ };
+
+ "custom/power" = {
+ format = " ⏻ ";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/mangowc/waybar/scripts/power-menu.sh";
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ };
+
+ "custom/quit" = {
+ format = "";
+ "on-click" = "loginctl kill-session $XDG_SESSION_ID";
+ tooltip = true;
+ "tooltip-format" = "Left Click: Logout";
+ };
+
+ "custom/swaync" = {
+ tooltip = true;
+ "tooltip-format" = "Left Click: Launch Notification Center\nRight Click: Do not Disturb";
+ format = "{} {icon} ";
+ "format-icons" = {
+ notification = "";
+ none = "";
+ "dnd-notification" = "";
+ "dnd-none" = "";
+ "inhibited-notification" = "";
+ "inhibited-none" = "";
+ "dnd-inhibited-notification" = "";
+ "dnd-inhibited-none" = "";
+ };
+ "return-type" = "json";
+ "exec-if" = "which swaync-client";
+ exec = "swaync-client -swb";
+ "on-click" = "systemctl --user start swaync.service; swaync-client -t";
+ "on-click-right" = "systemctl --user start swaync.service; swaync-client -d";
+ escape = true;
+ };
+
+ "custom/separator#line" = {
+ format = "|";
+ interval = "once";
+ tooltip = false;
+ };
+ "custom/separator#blank" = {
+ format = "";
+ interval = "once";
+ tooltip = false;
+ };
+ };
+
+ style = let
+ c = catppuccinColors;
+ in ''
+ @define-color rosewater ${c.rosewater};
+ @define-color flamingo ${c.flamingo};
+ @define-color pink ${c.pink};
+ @define-color mauve ${c.mauve};
+ @define-color red ${c.red};
+ @define-color maroon ${c.maroon};
+ @define-color peach ${c.peach};
+ @define-color yellow ${c.yellow};
+ @define-color green ${c.green};
+ @define-color teal ${c.teal};
+ @define-color sky ${c.sky};
+ @define-color sapphire ${c.sapphire};
+ @define-color blue ${c.blue};
+ @define-color lavender ${c.lavender};
+ @define-color text ${c.text};
+ @define-color subtext1 ${c.subtext1};
+ @define-color subtext0 ${c.subtext0};
+ @define-color overlay2 ${c.overlay2};
+ @define-color overlay1 ${c.overlay1};
+ @define-color overlay0 ${c.overlay0};
+ @define-color surface2 ${c.surface2};
+ @define-color surface1 ${c.surface1};
+ @define-color surface0 ${c.surface0};
+ @define-color base ${c.base};
+ @define-color mantle ${c.mantle};
+ @define-color crust ${c.crust};
+
+ * { font-family: "JetBrainsMono Nerd Font"; font-weight: bold; min-height: 0; font-size: 101%; }
+ window#waybar { background-color: @base; border-radius: 5px; }
+ tooltip { background: @base; opacity: 1; border-radius: 10px; border-width: 2px; border-style: solid; border-color: @sapphire; }
+ tooltip label { color: @blue; }
+ #custom-startmenu { color: @green; margin-left: 4px; margin-right: 8px; }
+ #custom-cava_mviz { margin-left: 4px; }
+ #workspaces button { color: @sapphire; }
+ #workspaces button.active { color: @green; }
+ #workspaces button.empty { color: @red; }
+ #idle_inhibitor.activated { color: @green; }
+ #idle_inhibitor.deactivated { color: @red; }
+ #custom-power { color: @red; }
+ #network { color: @mauve; }
+ #custom-weather { color: @green; }
+ #pulseaudio { color: @blue; }
+ #clock { color: @green; }
+ #custom-playerctl { color: @lavender; }
+ '';
+
+ mangowcWaybar = pkgs.writeShellScriptBin "mangowc-waybar" ''
+ exec waybar -c "$HOME/.config/mangowc/waybar/config.jsonc" -s "$HOME/.config/mangowc/waybar/style.css"
+ '';
+in {
+ # Install scripts under ~/.config/mangowc/waybar/scripts
+ home.file =
+ builtins.listToAttrs (
+ map (name: {
+ name = ".config/mangowc/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts
+ )
+ // {
+ ".config/mangowc/waybar/config.jsonc".text = builtins.toJSON [cfg];
+ ".config/mangowc/waybar/style.css".text = style;
+ };
+
+ home.packages = [mangowcWaybar waybarCava];
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-mecha.nix b/home-manager/programs/hypr/waybar/waybar-mecha.nix
new file mode 100644
index 0000000..81f0ce6
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-mecha.nix
@@ -0,0 +1,514 @@
+{
+ lib,
+ pkgs,
+ config,
+ ...
+}: let
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in {
+ home.file = builtins.listToAttrs (map
+ (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts);
+
+ programs.waybar = {
+ enable = true;
+ settings = {
+ mainBar = {
+ layer = "top";
+ position = "top";
+ mode = "dock";
+ reload_style_on_change = true;
+ "gtk-layer-shell" = true;
+ modules-left = [
+ "custom/startmenu"
+ "custom/left1"
+ "hyprland/workspaces"
+ "custom/right1"
+ "custom/paddw"
+ "hyprland/window"
+ ];
+ modules-center = [
+ "custom/paddc"
+ "custom/left2"
+ "custom/temperature"
+ "custom/left3"
+ "memory"
+ "custom/left4"
+ "cpu"
+ "custom/leftin1"
+ "custom/left5"
+ "custom/distro"
+ "custom/right2"
+ "custom/rightin1"
+ "idle_inhibitor"
+ "custom/weather"
+ "clock#time"
+ "custom/right3"
+ "clock#date"
+ "custom/right4"
+ "custom/right5"
+ ];
+ modules-right = [
+ "mpris"
+ "custom/left6"
+ "pulseaudio"
+ "custom/left7"
+ "backlight"
+ "custom/left8"
+ "battery"
+ "custom/leftin2"
+ "custom/power"
+ ];
+
+ "hyprland/workspaces" = {
+ on-scroll-up = "hyprctl dispatch workspace -1";
+ on-scroll-down = "hyprctl dispatch workspace +1";
+ persistent-workspaces = {
+ "1" = [];
+ "2" = [];
+ "3" = [];
+ "4" = [];
+ "5" = [];
+ };
+ };
+
+ "hyprland/window" = {
+ swap-icon-label = false;
+ format = "{}";
+ tooltip = false;
+ min-length = 5;
+ rewrite = {
+ "" = " Hyprland";
+ "~" = " Terminal";
+ "zsh" = " Terminal";
+ "kitty" = " Terminal";
+ "tmux(.*)" = " Tmux";
+ "(.*)Mozilla Firefox" = " Firefox";
+ "(.*) �� Mozilla Firefox" = " $1";
+ "(.*)Zen Browser" = " Zen Browser";
+ "(.*) — Zen Browser" = " $1";
+ "(.*) - Visual Studio Code" = " $1";
+ "(.*)Visual Studio Code" = " Visual Studio Code";
+ "nvim" = " Neovim";
+ "nvim (.*)" = " $1";
+ "vim" = " Vim";
+ "vim (.*)" = " $1";
+ "(.*)Spotify" = " Spotify";
+ "(.*)Spotify Premium" = " Spotify Premium";
+ "OBS(.*)" = " OBS Studio";
+ "VLC media player" = " VLC Media Player";
+ "(.*) - VLC media player" = " $1";
+ "(.*) - mpv" = " $1";
+ "qView" = " qView";
+ "(.*).jpg" = " $1.jpg";
+ "(.*).png" = " $1.png";
+ "(.*).svg" = " $1.svg";
+ "• Discord(.*)" = "Discord$1";
+ "(.*)Discord(.*)" = " $1Discord$2";
+ "vesktop" = " Discord";
+ "ONLYOFFICE Desktop Editors" = " OnlyOffice Desktop";
+ "(.*).docx" = " $1.docx";
+ "(.*).xlsx" = " $1.xlsx";
+ "(.*).pptx" = " $1.pptx";
+ "(.*).pdf" = " $1.pdf";
+ "Authenticate" = " Authenticate";
+ };
+ };
+
+ "custom/startmenu" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ # on-click = "rofi -show drun";
+ on-click = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+
+ "custom/temperature" = {
+ exec = "~/.config/waybar/scripts/cpu-temp.sh";
+ return-type = "json";
+ format = "{}";
+ interval = 5;
+ min-length = 8;
+ max-length = 8;
+ };
+
+ memory = {
+ states = {
+ warning = 75;
+ critical = 90;
+ };
+ format = " {percentage}%";
+ "format-critical" = " {percentage}%";
+ tooltip = false;
+ interval = 5;
+ min-length = 7;
+ max-length = 7;
+ };
+
+ cpu = {
+ format = " {usage}%";
+ tooltip = false;
+ interval = 5;
+ min-length = 6;
+ max-length = 6;
+ };
+
+ "custom/distro" = {
+ format = " ";
+ tooltip = false;
+ };
+
+ idle_inhibitor = {
+ format = "{icon}";
+ format-icons = {
+ activated = " ";
+ deactivated = " ";
+ };
+ "tooltip-format-activated" = "Presentation Mode";
+ "tooltip-format-deactivated" = "Idle Mode";
+ "start-activated" = false;
+ };
+
+ "custom/weather" = {
+ "return-type" = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+
+ "clock#time" = {
+ format = "{:%H:%M}";
+ tooltip = false;
+ min-length = 6;
+ max-length = 6;
+ };
+
+ "clock#date" = {
+ format = " {:%m-%d}";
+ "tooltip-format" = "{calendar}";
+ calendar = {
+ mode = "month";
+ "mode-mon-col" = 6;
+ "on-click-right" = "mode";
+ format = {
+ months = "{}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ "on-click" = "mode";
+ "on-click-right" = "mode";
+ };
+ min-length = 8;
+ max-length = 8;
+ };
+
+ "custom/wifi" = {
+ exec = "~/.config/waybar/scripts/wifi-status.sh";
+ return-type = "json";
+ format = "{}";
+ on-click = "~/.config/waybar/scripts/wifi-menu.sh";
+ "on-click-right" = "kitty --title ' Network Manager TUI' bash -c nmtui";
+ interval = 1;
+ min-length = 1;
+ max-length = 1;
+ };
+
+ bluetooth = {
+ format = "";
+ "format-disabled" = "";
+ "format-connected" = "";
+ "format-connected-battery" = "";
+ "tooltip-format" = "{num_connections} connected";
+ "tooltip-format-disabled" = "Bluetooth Disabled";
+ "tooltip-format-connected" = "{device_enumerate}";
+ "tooltip-format-enumerate-connected" = "{device_alias}";
+ "tooltip-format-enumerate-connected-battery" = ":: {device_alias}: {device_battery_percentage}%";
+ on-click = "~/.config/waybar/scripts/bluetooth-menu.sh";
+ "on-click-right" = "kitty --title ' Bluetooth TUI' bash -c bluetui";
+ interval = 1;
+ min-length = 1;
+ max-length = 1;
+ };
+
+ mpris = {
+ format = "{player_icon} {title} - {artist}";
+ "format-paused" = "{status_icon} {title} - {artist}";
+ "player-icons" = {
+ default = " ";
+ spotify = " ";
+ firefox = " ";
+ };
+ "status-icons" = {
+ paused = "\u200A\u200A\u2009\u2009";
+ };
+ "tooltip-format" = "Playing: {title} - {artist}";
+ "tooltip-format-paused" = "Paused: {title} - {artist}";
+ min-length = 5;
+ max-length = 35;
+ };
+
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ "format-muted" = " {volume}%";
+ "format-icons" = {
+ default = ["" "" ""];
+ headphone = "";
+ headset = "";
+ };
+ "tooltip-format" = "Device: {desc}";
+ on-click = "~/.config/waybar/scripts/volume-control.sh -o m";
+ "on-scroll-up" = "~/.config/waybar/scripts/volume-control.sh -o i";
+ "on-scroll-down" = "~/.config/waybar/scripts/volume-control.sh -o d";
+ min-length = 6;
+ max-length = 6;
+ };
+
+ backlight = {
+ format = "{icon} {percent}%";
+ "format-icons" = ["" "" "" "" "" "" "" "" ""];
+ tooltip = false;
+ "on-scroll-up" = "~/.config/waybar/scripts/brightness-control.sh -o i";
+ "on-scroll-down" = "~/.config/waybar/scripts/brightness-control.sh -o d";
+ min-length = 6;
+ max-length = 6;
+ };
+
+ battery = {
+ states = {
+ warning = 20;
+ critical = 10;
+ };
+ format = "{icon} {capacity}%";
+ "format-icons" = ["" "" "" "" "" "" "" "" "" ""];
+ "format-charging" = " {capacity}%";
+ "tooltip-format" = "Discharging: {time}";
+ "tooltip-format-charging" = "Charging: {time}";
+ interval = 1;
+ min-length = 6;
+ max-length = 6;
+ };
+
+ "custom/power" = {
+ format = " ⏻ ";
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ };
+
+ "custom/paddw" = {
+ format = " ";
+ tooltip = false;
+ };
+
+ "custom/paddc" = {
+ format = " ";
+ tooltip = false;
+ };
+
+ "custom/left1" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left2" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left3" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left4" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left5" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left6" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left7" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/left8" = {
+ format = "";
+ tooltip = false;
+ };
+
+ "custom/right1" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/right2" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/right3" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/right4" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/right5" = {
+ format = "";
+ tooltip = false;
+ };
+
+ "custom/leftin1" = {
+ format = "";
+ tooltip = false;
+ };
+ "custom/leftin2" = {
+ format = "";
+ tooltip = false;
+ };
+
+ "custom/rightin1" = {
+ format = "";
+ tooltip = false;
+ };
+ };
+ };
+ style = ''
+ * {
+ font-family: "JetBrainsMono Nerd Font";
+ font-weight: bold;
+ font-size: 18px;
+ }
+
+ window#waybar {
+ background-color: #${config.lib.stylix.colors.base00};
+ transition-property: background-color;
+ transition-duration: .5s;
+ }
+
+ #workspaces {
+ background: #${config.lib.stylix.colors.base01};
+ }
+
+ #workspaces button {
+ padding: 0 5px;
+ background-color: transparent;
+ color: #${config.lib.stylix.colors.base05};
+ }
+
+ #workspaces button:hover {
+ background: rgba(0, 0, 0, 0.2);
+ }
+
+ #workspaces button.focused {
+ background-color: #${config.lib.stylix.colors.base03};
+ box-shadow: inherit;
+ text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
+ }
+
+ #workspaces button.urgent {
+ background-color: #${config.lib.stylix.colors.base08};
+ }
+
+ #mode {
+ background-color: #${config.lib.stylix.colors.base01};
+ border-bottom: 3px solid #${config.lib.stylix.colors.base05};
+ }
+
+ #clock,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #temperature,
+ #backlight,
+ #network,
+ #pulseaudio,
+ #wireplumber,
+ #custom-media,
+ #tray,
+ #mode,
+ #idle_inhibitor,
+ #scratchpad,
+ #mpris {
+ padding: 0 10px;
+ color: #${config.lib.stylix.colors.base05};
+ background-color: #${config.lib.stylix.colors.base01};
+ }
+
+ #window,
+ #workspaces {
+ margin: 0 4px;
+ }
+
+ .modules-left > widget:first-child > #workspaces {
+ margin-left: 0;
+ }
+
+ .modules-right > widget:last-child > #workspaces {
+ margin-right: 0;
+ }
+
+ #battery.charging, #battery.plugged {
+ color: #${config.lib.stylix.colors.base0B};
+ background-color: #${config.lib.stylix.colors.base01};
+ }
+
+ @keyframes blink {
+ to {
+ background-color: #${config.lib.stylix.colors.base01};
+ color: #${config.lib.stylix.colors.base08};
+ }
+ }
+
+ #battery.critical:not(.charging) {
+ background-color: #${config.lib.stylix.colors.base08};
+ color: #${config.lib.stylix.colors.base01};
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+ }
+
+ label:focus {
+ background-color: #${config.lib.stylix.colors.base00};
+ }
+
+ #pulseaudio.muted {
+ background-color: #${config.lib.stylix.colors.base01};
+ color: #${config.lib.stylix.colors.base04};
+ }
+
+ #tray {
+ background-color: #${config.lib.stylix.colors.base01};
+ }
+
+ #tray > .passive {
+ -gtk-icon-effect: dim;
+ }
+
+ #tray > .needs-attention {
+ -gtk-icon-effect: highlight;
+ background-color: #${config.lib.stylix.colors.base09};
+ }
+
+ #idle_inhibitor.activated {
+ background-color: #${config.lib.stylix.colors.base01};
+ color: #${config.lib.stylix.colors.base0B};
+ }
+ '';
+ };
+}
diff --git a/home-manager/programs/hypr/waybar/waybar-nekodyke.nix b/home-manager/programs/hypr/waybar/waybar-nekodyke.nix
new file mode 100755
index 0000000..9376d91
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-nekodyke.nix
@@ -0,0 +1,306 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ betterTransition = "all 0.3s cubic-bezier(.55,-0.68,.48,1.682)";
+ clock24h = false;
+in
+ with lib; {
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ margin-top = 6;
+ margin-left = 6;
+ margin-right = 6;
+ modules-center = ["hyprland/workspaces"];
+ modules-left = [
+ "custom/startmenu"
+ "cpu"
+ "memory"
+ "temperature"
+ "disk"
+ "hyprland/window"
+ "idle_inhibitor"
+ ];
+ modules-right = [
+ "pulseaudio"
+ "battery"
+ "custom/hyprbindings"
+ "custom/notification"
+ "clock"
+ "tray"
+ ];
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "pulseaudio/slider" = {
+ min = 0;
+ max = 100;
+ orientation = "horizontal";
+ };
+ "temperature" = {
+ format = " {temperatureC}°C ";
+ };
+ "clock" = {
+ format =
+ if clock24h == true
+ then '' {:L%H:%M}''
+ else '' {:L%I:%M %p}'';
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }\n{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 22;
+ separate-outputs = false;
+ rewrite = {
+ "" = " 🙈 No Windows? ";
+ };
+ };
+ "memory" = {
+ interval = 5;
+ icon-size = 20;
+ format = " {}%";
+ tooltip = true;
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ };
+ "network" = {
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ format-ethernet = " {bandwidthDownOctets}";
+ format-wifi = "{icon} {signalStrength}%";
+ format-disconnected = "";
+ tooltip = false;
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ on-click = "sleep 0.1 && pavucontrol";
+ scroll-step = 2;
+ };
+ "custom/exit" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && wlogout";
+ };
+ "custom/startmenu" = {
+ tooltip = false;
+ format = "";
+ # exec = "rofi -show drun";
+ #on-click = "sleep 0.1 && rofi-launcher";
+ on-click = "sleep 0.1 && nwg-drawer -mb 200 -mt 200 -mr 200 -ml 200";
+ };
+ "custom/hyprbindings" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && list-keybinds";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = "";
+ deactivated = "";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "sleep 0.1 && task-waybar";
+ escape = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ on-click = "";
+ tooltip = false;
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-family: JetBrainsMono Nerd Font Mono;
+ font-size: 16px;
+ border-radius: 0px;
+ border: none;
+ min-height: 0px;
+ margin: 0px;
+ }
+ window#waybar {
+ background: #${config.lib.stylix.colors.base00};
+ padding: 2px;
+ border-radius: 4px;
+ }
+ #workspaces {
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base00};
+ border: 2px solid #${config.lib.stylix.colors.base0B};
+ margin: 2px 4px;
+ padding: 5px 5px;
+ border-radius: 4px;
+ }
+ #workspaces button {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base00};
+
+ }
+ #workspaces button.active {
+ font-weight: bold;
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 4px;
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base0B};
+ transition: ${betterTransition};
+ opacity: 1.0;
+ min-width: 40px;
+ }
+ #workspaces button:hover {
+ font-weight: bold;
+ border-radius: 4px;
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base0B};
+ opacity: 0.8;
+ }
+ tooltip {
+ background: #${config.lib.stylix.colors.base00};
+ border: 1px solid #${config.lib.stylix.colors.base08};
+ border-radius: 12px;
+ }
+ tooltip label {
+ color: #${config.lib.stylix.colors.base08};
+ }
+ #window, #pulseaudio, #temperature, #cpu, #memory, #idle_inhibitor, #disk {
+ font-weight: bold;
+ margin: 2px 0px;
+ margin-right: 7px;
+ padding: 0px 18px;
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base0B};
+ border: 2px solid #${config.lib.stylix.colors.base0B};
+ border-radius: 4px;
+ }
+ #idle_inhibitor {
+ font-size: 28px;
+ }
+ #custom-startmenu {
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base0B};
+ font-size: 22px;
+ padding: 0px 5px 0px 5px;
+ border-radius: 4px;
+ padding: 0px 8px;
+ margin: 0px;
+ margin-right:7px;
+
+ }
+ #custom-hyprbindings, #network, #battery,
+ #custom-notification, #clock, #custom-exit {
+ /* font-weight: bold; */
+ font-size: 20px;
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base0B};
+ margin: 2px 0px;
+ margin-right: 7px;
+ border: 2px solid #${config.lib.stylix.colors.base0B};
+ border-radius: 4px;
+ padding: 0px 12px;
+ }
+ #tray{
+ font-weight: bold;
+ font-size: 16px;
+ margin: 0px;
+ background: #${config.lib.stylix.colors.base0B};
+ color: #${config.lib.stylix.colors.base00};
+ border: 2px solid #${config.lib.stylix.colors.base0B};
+ padding: 0px 18px;
+ margin: 0px 0px;
+ border-radius: 4px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-old-ddubsos.nix b/home-manager/programs/hypr/waybar/waybar-old-ddubsos.nix
new file mode 100644
index 0000000..775fe46
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-old-ddubsos.nix
@@ -0,0 +1,499 @@
+{
+ pkgs,
+ lib,
+ ...
+}: let
+ # Install helper scripts shipped in modules/home/waybar/scripts into ~/.config/waybar/scripts
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+
+ # Updated CAVA visualizer script packaged via Nix (from waybar-jak-catppuccin.nix)
+ waybarCava = pkgs.writeShellScriptBin "WaybarCava" ''
+ set -euo pipefail
+
+ # Ensure cava exists
+ if ! command -v cava >/dev/null 2>&1; then
+ echo "cava not found in PATH" >&2
+ exit 1
+ fi
+
+ # Characters for vertical bars (0..7)
+ bar="▁▂▃▄▅▆▇█"
+
+ # Build sed script that maps 0..7 to glyphs and strips ';'
+ dict="s/;//g"
+ bar_length=''${#bar}
+ for ((i = 0; i < bar_length; i++)); do
+ dict+=";s/$i/''${bar:$i:1}/g"
+ done
+
+ RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp}"
+ pidfile="$RUNTIME_DIR/waybar-cava.pid"
+ if [ -f "$pidfile" ]; then
+ oldpid=$(cat "$pidfile" || true)
+ if [ -n "''${oldpid:-}" ] && kill -0 "$oldpid" 2>/dev/null; then
+ kill "$oldpid" 2>/dev/null || true
+ sleep 0.1 || true
+ fi
+ fi
+ echo $$ > "$pidfile"
+
+ config_file=$(mktemp "''${RUNTIME_DIR}/waybar-cava.XXXXXX.conf")
+ cleanup() {
+ rm -f "$config_file" "$pidfile"
+ }
+ trap cleanup EXIT INT TERM
+
+ cat >"$config_file" < * { margin: 0; }
+ /* Tighten QS buttons margins/padding to bring them closer */
+ #custom-qs_wallpapers_apply,
+ #custom-qs_vid_wallpapers_apply {
+ margin: 2px 2px;
+ padding: 2px 4px;
+ }
+ #idle_inhibitor {
+ color: #b45bcf;
+ background: #3a3c4e;
+ margin: 4px 0px;
+ padding: 2px 14px;
+ border-radius: 10px;
+ }
+ #custom-power {
+ color: #ea51b2; /* Red color for power menu */
+ background: #3a3c4e;
+ margin: 4px 4px;
+ padding: 10px 10px;
+ border-radius: 10px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-pctrade-catppuccin.nix b/home-manager/programs/hypr/waybar/waybar-pctrade-catppuccin.nix
new file mode 100644
index 0000000..6802976
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-pctrade-catppuccin.nix
@@ -0,0 +1,340 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ # Keep consistency with other modules; scriptsDir can supply Weather.py, etc.
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in
+ with lib; {
+ # Install any helper scripts from ./scripts into ~/.config/waybar/scripts
+ home.file = builtins.listToAttrs (
+ map
+ (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts
+ );
+
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+
+ # Waybar configuration
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ height = 30;
+ spacing = 4;
+
+ # Layout to mirror waybarpc/config (with requested removals)
+ # - Left: start menu, clock, separator, weather
+ # - Center: workspaces
+ # - Right: tray, pulseaudio, battery, swaync, idle_inhibitor, power
+ modules-left = [
+ "custom/startmenu"
+ "clock"
+ "custom/weather"
+ ];
+ modules-center = [
+ "hyprland/workspaces"
+ ];
+ modules-right = [
+ "battery"
+ "tray"
+ "custom/notification"
+ "idle_inhibitor"
+ "pulseaudio"
+ "custom/power"
+ ];
+
+ # Workspaces (Hyprland)
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+
+ # 12-hour time format
+ clock = {
+ format = '' {:%I:%M %p}'';
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }\n{calendar}";
+ };
+
+ # Idle inhibitor with coffee mug icon
+ idle_inhibitor = {
+ format = "{icon}";
+ format-icons = {
+ activated = "";
+ deactivated = "";
+ };
+ tooltip = true;
+ };
+
+ # Notifications (SwayNotificationCenter via swaync-client)
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "swaync-client -t";
+ escape = true;
+ };
+
+ # Audio
+ pulseaudio = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ on-click = "sleep 0.1 && pavucontrol";
+ };
+
+ # Battery
+ battery = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ tooltip = false;
+ };
+
+ # Tray
+ tray = {
+ spacing = 10;
+ };
+
+ # Start menu and power menu
+ "custom/startmenu" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ # on-click = "rofi -show drun";
+ on-click = "launch-nwg-menu";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+
+ "custom/power" = {
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout";
+ format = " ⏻ ";
+ on-click = "qs-wlogout";
+ };
+
+ # Weather widget (uses existing ddubsos Weather.py script if present)
+ "custom/weather" = {
+ return-type = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+ }
+ ];
+
+ # Styling to mirror ~/Projects/waybarpc/style.css (with Catppuccin-like colors)
+ style = lib.concatStrings [
+ ''
+ /* Color variables based on waybarpc/colors.css */
+ @define-color bg #1a1b26;
+ @define-color bg-alt #16161e;
+ @define-color bg-alt2 #24283b;
+ @define-color bg-alt3 #414868;
+ @define-color border #565f89;
+ @define-color border2 #6183bb;
+ @define-color text #c0caf5;
+ @define-color text-dark #1a1b26; /* alias for typo tex-dark in original */
+ @define-color tex-dark #1a1b26;
+ @define-color accent #7e9cd8;
+ @define-color accent2 #957fb8;
+ @define-color red #f7768e;
+ @define-color green #a6e3a1;
+ @define-color blue #89b4fa;
+
+ * {
+ font-family: JetBrainsMono Nerd Font, monospace;
+ font-size: 13px;
+ }
+
+ window#waybar { background-color: @bg; }
+ window#waybar.hidden { opacity: 0.5; margin: 15px; }
+
+ /* Workspaces container */
+ #workspaces {
+ background-color: @bg-alt;
+ padding: 2px;
+ margin: 2px;
+ border-radius: 10px;
+ }
+ /* 3D shaded workspace buttons */
+ #workspaces button {
+ all: initial;
+ min-width: 0;
+ background: linear-gradient(to bottom, @bg-alt3, @bg);
+ padding: 6px 12px;
+ transition: all 0.1s linear;
+ border-top: 1px solid @border;
+ box-shadow: 0px 17px 5px 1px rgba(0, 0, 0, 0.2);
+ color: @accent2;
+ font-weight: 800;
+ text-shadow: -1px -1px 1px rgba(205, 214, 244, 0.1), 0px 2px 3px rgba(0, 0, 0, 0.3);
+ }
+ #workspaces button:first-child {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ }
+ #workspaces button:last-child {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ }
+ #workspaces button.empty {
+ color: #737373;
+ background: transparent;
+ text-shadow: none;
+ box-shadow: none;
+ }
+ #workspaces button.active {
+ box-shadow: 0px 20px 8px 2px rgba(0, 0, 0, 0.35);
+ background: linear-gradient(to bottom, @bg-alt3, @bg-alt);
+ color: @text;
+ font-size: 25px;
+ border-top: 1px solid @border2;
+ border-bottom: 3px solid @border2;
+ text-shadow: 0px 0px 14px @text;
+ }
+ #workspaces button.focused {
+ background: linear-gradient(to bottom, @accent2, @bg-alt3);
+ color: @bg;
+ text-shadow: 0px 0px 12px @accent2;
+ font-size: 22px;
+ border-top: 1px solid @accent2;
+ }
+ #workspaces button.visible {
+ background: linear-gradient(to bottom, @bg-alt3, @bg-alt2);
+ color: @accent;
+ text-shadow: none;
+ font-size: 18px;
+ border-top: 1px solid @border;
+ }
+ #workspaces button.urgent {
+ background-color: @red;
+ color: @bg;
+ text-shadow: 0px 0px 8px @red;
+ font-weight: bold;
+ }
+
+ /* Clock with gradient block */
+ #clock {
+ background: linear-gradient(to bottom, @bg-alt3, @bg);
+ font-size: 14px;
+ margin: 2px;
+ padding: 6px 10px;
+ border-radius: 6px;
+ font-weight: bold;
+ border-top: 1px solid @border;
+ border-bottom: 2px solid @bg-alt;
+ color: @text;
+ }
+
+ /* Notifications state color cues */
+ #custom-notification.none { color: @green; }
+ #custom-notification.notification, #custom-notification.dnd-notification, #custom-notification.inhibited-notification, #custom-notification.dnd-inhibited-notification { color: @red; }
+
+ /* Idle inhibitor colors */
+ #idle_inhibitor.activated { color: @green; }
+ #idle_inhibitor.deactivated { color: @red; }
+
+ /* Right-side blocks */
+ #pulseaudio, #battery, #tray {
+ background: linear-gradient(to bottom, @bg-alt3, @bg);
+ padding: 4px 8px;
+ margin: 2px;
+ border-radius: 6px;
+ border-top: 1px solid @border;
+ border-bottom: 2px solid @bg-alt;
+ font-weight: bold;
+ color: @text;
+ }
+ #pulseaudio { margin-left: 0; margin-right: 0; }
+
+ /* Shaded block style (match workspace button look) */
+ #custom-startmenu, #custom-weather, #idle_inhibitor, #custom-power, #custom-notification {
+ background: linear-gradient(to bottom, @bg-alt3, @bg);
+ padding: 6px 10px;
+ margin: 2px;
+ border-radius: 6px;
+ border-top: 1px solid @border;
+ border-bottom: 2px solid @bg-alt;
+ box-shadow: 0px 12px 4px 1px rgba(0, 0, 0, 0.2);
+ text-shadow: -1px -1px 1px rgba(205, 214, 244, 0.1), 0px 2px 3px rgba(0, 0, 0, 0.3);
+ color: @text;
+ font-size: 14px;
+ }
+ /* Make icons slightly larger for clarity */
+ #custom-startmenu, #idle_inhibitor, #custom-power, #custom-notification { font-size: 16px; }
+ #battery.warning, #battery.critical, #battery.urgent { color: @red; }
+
+ /* Separator styling */
+ #custom-sep { color: @accent; }
+
+ /* Center the startmenu glyph like the power button */
+ #custom-startmenu {
+ min-width: 28px;
+ min-height: 24px;
+ padding-left: 8px;
+ padding-right: 12px;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-simple.nix b/home-manager/programs/hypr/waybar/waybar-simple.nix
new file mode 100644
index 0000000..53b2499
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-simple.nix
@@ -0,0 +1,305 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ clock24h = false;
+in
+ with lib; {
+ # Configure & Theme Waybar
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ modules-center = ["hyprland/workspaces"];
+ modules-left = [
+ "custom/startmenu"
+ "custom/arrow6"
+ "pulseaudio"
+ "cpu"
+ "memory"
+ "idle_inhibitor"
+ "custom/arrow7"
+ "hyprland/window"
+ ];
+ modules-right = [
+ "custom/arrow4"
+ "custom/hyprbindings"
+ "custom/arrow3"
+ "custom/notification"
+ "custom/arrow3"
+ "custom/exit"
+ "battery"
+ "custom/arrow2"
+ "tray"
+ "custom/arrow1"
+ "clock"
+ ];
+
+ "hyprland/workspaces" = {
+ format = "{name}";
+ format-icons = {
+ default = " ";
+ active = " ";
+ urgent = " ";
+ };
+ on-scroll-up = "hyprctl dispatch workspace e+1";
+ on-scroll-down = "hyprctl dispatch workspace e-1";
+ };
+ "clock" = {
+ format =
+ if clock24h == true
+ then '' {:L%H:%M}''
+ else '' {:L%I:%M %p}'';
+ tooltip = true;
+ tooltip-format = "{:%A, %d.%B %Y }\n{calendar}";
+ };
+ "hyprland/window" = {
+ max-length = 22;
+ separate-outputs = false;
+ rewrite = {
+ "" = " 🙈 No Windows? ";
+ };
+ };
+ "memory" = {
+ interval = 5;
+ format = " {}%";
+ tooltip = true;
+ };
+ "cpu" = {
+ interval = 5;
+ format = " {usage:2}%";
+ tooltip = true;
+ };
+ "disk" = {
+ format = " {free}";
+ tooltip = true;
+ };
+ "network" = {
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ format-ethernet = " {bandwidthDownOctets}";
+ format-wifi = "{icon} {signalStrength}%";
+ format-disconnected = "";
+ tooltip = false;
+ };
+ "tray" = {
+ spacing = 12;
+ };
+ "pulseaudio" = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ on-click = "sleep 0.1 && pavucontrol";
+ };
+ "custom/exit" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && wlogout";
+ };
+ "custom/startmenu" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && rofi-launcher";
+ };
+ "custom/hyprbindings" = {
+ tooltip = false;
+ format = "";
+ on-click = "sleep 0.1 && list-keybinds";
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = "";
+ deactivated = "";
+ };
+ tooltip = "true";
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "sleep 0.1 && task-waybar";
+ escape = true;
+ };
+ "battery" = {
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ on-click = "";
+ tooltip = false;
+ };
+ "custom/arrow1" = {
+ format = "";
+ };
+ "custom/arrow2" = {
+ format = "";
+ };
+ "custom/arrow3" = {
+ format = "";
+ };
+ "custom/arrow4" = {
+ format = "";
+ };
+ "custom/arrow5" = {
+ format = "";
+ };
+ "custom/arrow6" = {
+ format = "";
+ };
+ "custom/arrow7" = {
+ format = "";
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ * {
+ font-family: JetBrainsMono Nerd Font Mono;
+ font-size: 14px;
+ border-radius: 0px;
+ border: none;
+ min-height: 0px;
+ }
+ window#waybar {
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base05};
+ }
+ #workspaces button {
+ padding: 0px 5px;
+ background: transparent;
+ color: #${config.lib.stylix.colors.base04};
+ }
+ #workspaces button.active {
+ color: #${config.lib.stylix.colors.base08};
+ }
+ #workspaces button:hover {
+ color: #${config.lib.stylix.colors.base08};
+ }
+ tooltip {
+ background: #${config.lib.stylix.colors.base00};
+ border: 1px solid #${config.lib.stylix.colors.base05};
+ border-radius: 12px;
+ }
+ tooltip label {
+ color: #${config.lib.stylix.colors.base05};
+ }
+ #window {
+ padding: 0px 10px;
+ }
+ #pulseaudio, #cpu, #memory, #idle_inhibitor {
+ padding: 0px 10px;
+ background: #${config.lib.stylix.colors.base04};
+ color: #${config.lib.stylix.colors.base00};
+ }
+ #custom-startmenu {
+ color: #${config.lib.stylix.colors.base02};
+ padding: 0px 14px;
+ font-size: 20px;
+ background: #${config.lib.stylix.colors.base0B};
+ }
+ #custom-hyprbindings, #network, #battery,
+ #custom-notification, #custom-exit {
+ background: #${config.lib.stylix.colors.base0F};
+ color: #${config.lib.stylix.colors.base00};
+ padding: 0px 10px;
+ }
+ #tray {
+ background: #${config.lib.stylix.colors.base02};
+ color: #${config.lib.stylix.colors.base00};
+ padding: 0px 10px;
+ }
+ #clock {
+ font-weight: bold;
+ padding: 0px 10px;
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base0E};
+ }
+ #custom-arrow1 {
+ font-size: 24px;
+ color: #${config.lib.stylix.colors.base0E};
+ background: #${config.lib.stylix.colors.base02};
+ }
+ #custom-arrow2 {
+ font-size: 24px;
+ color: #${config.lib.stylix.colors.base02};
+ background: #${config.lib.stylix.colors.base0F};
+ }
+ #custom-arrow3 {
+ font-size: 24px;
+ color: #${config.lib.stylix.colors.base00};
+ background: #${config.lib.stylix.colors.base0F};
+ }
+ #custom-arrow4 {
+ font-size: 24px;
+ color: #${config.lib.stylix.colors.base0F};
+ background: transparent;
+ }
+ #custom-arrow6 {
+ font-size: 24px;
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base04};
+ }
+ #custom-arrow7 {
+ font-size: 24px;
+ color: #${config.lib.stylix.colors.base04};
+ background: transparent;
+ }
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/hypr/waybar/waybar-tony.nix b/home-manager/programs/hypr/waybar/waybar-tony.nix
new file mode 100644
index 0000000..6fedb74
--- /dev/null
+++ b/home-manager/programs/hypr/waybar/waybar-tony.nix
@@ -0,0 +1,449 @@
+{
+ pkgs,
+ lib,
+ host,
+ config,
+ ...
+}: let
+ clock24h = false;
+ scriptsDir = ./scripts;
+ scripts = builtins.attrNames (builtins.readDir scriptsDir);
+in
+ with lib; {
+ # Configure & Theme Waybar (Tony)
+ home.file = builtins.listToAttrs (
+ map (name: {
+ name = ".config/waybar/scripts/" + name;
+ value = {
+ source = "${scriptsDir}/${name}";
+ executable = true;
+ };
+ })
+ scripts
+ );
+
+ programs.waybar = {
+ enable = true;
+ package = pkgs.waybar;
+ settings = [
+ {
+ layer = "top";
+ position = "top";
+ height = 30;
+ spacing = 4;
+
+ modules-left = [
+ "custom/startmenu"
+ "custom/sep_gap_left"
+ "group/qs_wallpapers"
+ "custom/sep"
+ "hyprland/workspaces"
+ "custom/sep"
+ #"custom/sep"
+ "hyprland/window"
+ "custom/sep"
+ ];
+ modules-center = [
+ #"custom/sep"
+ "idle_inhibitor"
+ "custom/weather"
+ "custom/notification"
+ #"custom/sep"
+ ];
+ modules-right = [
+ "custom/sep"
+ "tray"
+ "custom/sep"
+ "pulseaudio"
+ #"network"
+ "cpu"
+ #"memory"
+ "clock"
+ "custom/sep"
+ "custom/power"
+ ];
+
+ "hyprland/workspaces" = {
+ disable-scroll = true;
+ all-outputs = true;
+ warp-on-scroll = false;
+ format = "{name}";
+ persistent-workspaces = {
+ "*" = 9;
+ };
+ };
+ "hyprland/window" = {
+ max-length = 40;
+ seperate-outputs = false;
+ };
+ tray = {
+ spacing = 10;
+ };
+ clock = {
+ format-alt = "{:%Y-%m-%d}";
+ };
+ cpu = {
+ format = "CPU: {usage}%";
+ tooltip = false;
+ };
+ memory = {
+ format = "Mem: {used}GiB";
+ };
+ disk = {
+ interval = 60;
+ path = "/";
+ format = "Disk: {free}";
+ };
+ battery = {
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 15;
+ };
+ format = "Bat: {capacity}% {icon} {time}";
+ format-plugged = "{capacity}% ";
+ format-alt = "Bat {capacity}%";
+ format-time = "{H}:{M}";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+ network = {
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ format-ethernet = "{ifname} {ipaddr}";
+ format-wifi = "{essid} {signalStrength}% {ipaddr}";
+ format-disconnected = "";
+ tooltip = true;
+ tooltip-format = "{ifname}\nIPv4: {ipaddr}/{cidr}\nGateway: {gwaddr}\nSSID: {essid}\nSignal: {signalStrength}%";
+ on-click = "nmtui";
+ };
+ "custom/sep" = {
+ format = "|";
+ interval = 0;
+ };
+ "idle_inhibitor" = {
+ format = "{icon}";
+ format-icons = {
+ activated = "";
+ deactivated = "";
+ };
+ tooltip = true;
+ };
+ "custom/startmenu" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "App menu";
+ on-click = "rofi -show drun";
+ "on-click-right" = "nwg-drawer -mr 225 -ml 225 -mt 200 -mb 200 -is 48 --spacing 15";
+ };
+
+ # Wallpaper quick-switchers close to startmenu
+ "custom/qs_wallpapers_apply" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "Set image wallpaper";
+ on-click = "qs-wallpapers-apply";
+ };
+ "custom/qs_vid_wallpapers_apply" = {
+ format = "";
+ tooltip = true;
+ "tooltip-format" = "Set video wallpaper";
+ on-click = "qs-vid-wallpapers-apply";
+ };
+ "group/qs_wallpapers" = {
+ orientation = "inherit";
+ modules = [
+ "custom/qs_wallpapers_apply"
+ "custom/sep_gap"
+ "custom/qs_vid_wallpapers_apply"
+ ];
+ };
+
+ # Narrow spacer for QS icons
+ "custom/sep_gap" = {
+ format = " ";
+ tooltip = false;
+ };
+ # Spacer between startmenu and first QS icon
+ "custom/sep_gap_left" = {
+ format = " ";
+ tooltip = false;
+ };
+ "custom/notification" = {
+ tooltip = false;
+ format = "{icon} {}";
+ format-icons = {
+ notification = "";
+ none = "";
+ dnd-notification = "";
+ dnd-none = "";
+ inhibited-notification = "";
+ inhibited-none = "";
+ dnd-inhibited-notification = "";
+ dnd-inhibited-none = "";
+ };
+ return-type = "json";
+ exec-if = "which swaync-client";
+ exec = "swaync-client -swb";
+ on-click = "swaync-client -t";
+ escape = true;
+ };
+ "custom/weather" = {
+ return-type = "json";
+ exec = "sh -lc 'WEATHER_ICON_STYLE=emoji WEATHER_TOOLTIP_MARKUP=1 ~/.local/bin/weather'";
+ interval = 600;
+ tooltip = true;
+ };
+ pulseaudio = {
+ format = "{icon} {volume}% {format_source}";
+ format-bluetooth = "{volume}% {icon} {format_source}";
+ format-bluetooth-muted = " {icon} {format_source}";
+ format-muted = " {format_source}";
+ format-source = " {volume}%";
+ format-source-muted = "";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ on-click = "pavucontrol";
+ };
+ "custom/power" = {
+ format = " ⏻ ";
+ tooltip = true;
+ "tooltip-format" = "Power menu: Left-click for QS logout, Right-click for rofi power menu";
+ "on-click" = "qs-wlogout";
+ "on-click-right" = "~/.config/waybar/scripts/power-menu.sh";
+ };
+ }
+ ];
+ style = concatStrings [
+ ''
+ @define-color bg #1a1b26;
+ @define-color fg #a9b1d6;
+ @define-color blk #32344a;
+ @define-color red #f7768e;
+ @define-color grn #9ece6a;
+ @define-color ylw #e0af68;
+ @define-color blu #7aa2f7;
+ @define-color mag #ad8ee6;
+ @define-color cyn #0db9d7;
+ @define-color brblk #444b6a;
+ @define-color white #ffffff;
+
+ * {
+ font-family: "JetBrainsMono Nerd Font", monospace;
+ font-size: 16px;
+ font-weight: bold;
+ }
+
+ window#waybar {
+ background-color: @bg;
+ color: @fg;
+ }
+
+ #workspaces button {
+ padding: 0 6px;
+ color: @cyn;
+ background: transparent;
+ border-bottom: 3px solid @bg;
+ }
+ #workspaces button.active {
+ color: @cyn;
+ border-bottom: 3px solid @mag;
+ }
+ #workspaces button.empty {
+ color: @white;
+ }
+ #workspaces button.empty.active {
+ color: @cyn;
+ border-bottom: 3px solid @mag;
+ }
+
+ #workspaces button.urgent {
+ background-color: @red;
+ }
+
+ button:hover {
+ background: inherit;
+ box-shadow: inset 0 -3px #ffffff;
+ }
+
+ #clock,
+ #custom-sep,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #network,
+ #tray,
+ #pulseaudio,
+ #idle_inhibitor,
+ #custom-notification,
+ #custom-power {
+ padding: 0 8px;
+ color: @white;
+ }
+ /* Rounded, raised bottom effect for center/right modules */
+ #clock,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #network,
+ #tray,
+ #pulseaudio,
+ #idle_inhibitor,
+ #custom-notification,
+ #custom-power {
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ box-shadow: inset 0 -2px rgba(255,255,255,0.07);
+ }
+ /* Tighten spacing between the two QS buttons */
+ #group-qs_wallpapers { margin: 0; padding: 0; }
+
+ /* Make QS icons match startmenu color and background (bright green) */
+ /* Start menu stays bright green; QS icons switch to clock blue (@cyn) */
+ #custom-startmenu {
+ color: @grn;
+ background: transparent;
+ font-size: 21px; /* ~30% larger than base 16px */
+ }
+ #custom-qs_wallpapers_apply,
+ #custom-qs_vid_wallpapers_apply {
+ color: @cyn; /* match clock color */
+ background: transparent;
+ font-size: 21px; /* ~30% larger than base 16px */
+ }
+ /* Prevent QS icons from being clipped; add a tiny internal pad */
+ #custom-qs_wallpapers_apply,
+ #custom-qs_vid_wallpapers_apply {
+ padding: 0 2px;
+ min-width: 20px;
+ }
+ #custom-startmenu { margin-right: 6px; }
+
+ #custom-sep {
+ color: @brblk;
+ }
+ /* Width for gap spacer between QS icons */
+ #custom-sep_gap { padding: 0 1px; }
+ #custom-sep_gap_left { padding: 0 2px; }
+
+ #clock {
+ color: @cyn;
+ border-bottom: 4px solid @cyn;
+ }
+
+ #battery {
+ color: @mag;
+ border-bottom: 4px solid @mag;
+ }
+
+ #disk {
+ color: @ylw;
+ border-bottom: 4px solid @ylw;
+ }
+
+ #memory {
+ color: @mag;
+ border-bottom: 4px solid @mag;
+ }
+
+ #cpu {
+ color: @grn;
+ border-bottom: 4px solid @grn;
+ }
+
+ #network {
+ color: @blu;
+ border-bottom: 4px solid @blu;
+ }
+
+ #network.disconnected {
+ background-color: @red;
+ }
+
+ #pulseaudio {
+ color: @blu;
+ border-bottom: 4px solid @blu;
+ }
+
+ /* Center the idle_inhibitor icon within its pill */
+ #idle_inhibitor {
+ /* Center visually via symmetric padding + fixed min width */
+ padding-left: 10px;
+ padding-right: 10px;
+ min-width: 26px; /* keep a consistent hit area */
+ border-bottom: 4px solid @brblk; /* default raised strip */
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ }
+ #idle_inhibitor label {
+ margin: 0; /* remove any label offset */
+ padding: 0;
+ }
+
+ #idle_inhibitor.deactivated {
+ color: @red;
+ border-bottom: 4px solid @red;
+ }
+
+ #idle_inhibitor.activated {
+ color: @grn;
+ border-bottom: 4px solid @grn;
+ margin-right: 5px;
+ }
+
+ #custom-notification {
+ color: @grn; /* default green */
+ border-bottom: 4px solid @grn;
+ }
+ /* Turn red on new alerts */
+ #custom-notification.notification,
+ #custom-notification.dnd-notification,
+ #custom-notification.inhibited-notification {
+ color: @red;
+ border-bottom: 4px solid @red;
+ }
+ /* Add subtle raised effect to center modules too */
+ #custom-notification,
+ #idle_inhibitor {
+ box-shadow: inset 0 -3px @brblk;
+ }
+
+ #tray {
+ background-color: @bg; /* match bar background */
+ border-bottom: 4px solid @brblk; /* restore raised strip */
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ }
+
+ #custom-power {
+ color: @red;
+ border-bottom: 4px solid @red;
+ }
+
+ ''
+ ];
+ };
+ }
diff --git a/home-manager/programs/programs.nix b/home-manager/programs/programs.nix
index 6dc4d22..b52ec61 100644
--- a/home-manager/programs/programs.nix
+++ b/home-manager/programs/programs.nix
@@ -10,7 +10,7 @@
./hypr/hyprland.nix
./hypr/hyprlock.nix
./hypr/theme.nix
- ./hypr/waybar.nix
+ ./hypr/waybar/waybar-curved.nix
./hypr/wlogout.nix
]
# macOS programs
@@ -18,18 +18,6 @@
./ghostty/ghostty.nix
];
- gtk = lib.mkIf (hostTypes.isLinuxDesktop hostname) {
- enable = true;
- gtk3.extraConfig.gtk-application-prefer-dark-theme = true;
- gtk4.extraConfig.gtk-application-prefer-dark-theme = true;
- };
-
- qt = lib.mkIf (hostTypes.isLinuxDesktop hostname) {
- enable = true;
- platformTheme.name = "kde";
- style.name = "breeze";
- };
-
dconf = lib.mkIf (hostTypes.isLinuxDesktop hostname) {
settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
};
diff --git a/home-manager/programs/rofi/rofi.nix b/home-manager/programs/rofi/rofi.nix
index 325602a..bffe192 100644
--- a/home-manager/programs/rofi/rofi.nix
+++ b/home-manager/programs/rofi/rofi.nix
@@ -1,6 +1,7 @@
{
config,
pkgs,
+ lib,
configPath,
...
}:
@@ -12,7 +13,7 @@
package = pkgs.rofi.override {
plugins = [ pkgs.rofi-emoji ];
};
- font = "JetBrainsMono Nerd Font 12";
+ font = lib.mkForce "JetBrainsMono Nerd Font 12";
plugins = [
pkgs.rofi-emoji
pkgs.rofi-calc
@@ -36,7 +37,7 @@
let
inherit (config.lib.formats.rasi) mkLiteral;
in
- {
+ lib.mkForce {
"*" = {
active-background = mkLiteral "#101C2F";
active-foreground = mkLiteral "#D6CBD5";
diff --git a/home-manager/programs/thunar.nix b/home-manager/programs/thunar.nix
new file mode 100644
index 0000000..90415c5
--- /dev/null
+++ b/home-manager/programs/thunar.nix
@@ -0,0 +1,16 @@
+{ pkgs, ... }:
+
+{
+ programs = {
+ thunar = {
+ enable = true;
+ plugins = with pkgs.xfce; [
+ thunar-archive-plugin
+ thunar-volman
+ ];
+ };
+ };
+ environment.systemPackages = with pkgs; [
+ ffmpegthumbnailer # Need For Video / Image Preview
+ ];
+}
\ No newline at end of file
diff --git a/hosts/eva-01/configuration.nix b/hosts/eva-01/configuration.nix
index 939e3e4..95a64ed 100644
--- a/hosts/eva-01/configuration.nix
+++ b/hosts/eva-01/configuration.nix
@@ -18,6 +18,7 @@
# Include the results of the hardware scan.
./hardware-configuration.nix
inputs.home-manager.nixosModules.default
+ inputs.stylix.nixosModules.stylix
];
# Bootloader.
@@ -284,6 +285,39 @@
dejavu_fonts
];
+ # Stylix
+ stylix = {
+ enable = true;
+ image = /etc/nixos/assets/pfp/neonNerv.png;
+ polarity = "dark";
+ opacity.terminal = 1.0;
+ cursor = {
+ package = pkgs.bibata-cursors;
+ name = "Bibata-Modern-Ice";
+ size = 24;
+ };
+ fonts = {
+ monospace = {
+ package = pkgs.nerd-fonts.jetbrains-mono;
+ name = "JetBrains Mono";
+ };
+ sansSerif = {
+ package = pkgs.montserrat;
+ name = "Montserrat";
+ };
+ serif = {
+ package = pkgs.montserrat;
+ name = "Montserrat";
+ };
+ sizes = {
+ applications = 12;
+ terminal = 15;
+ desktop = 11;
+ popups = 12;
+ };
+ };
+ };
+
home-manager = {
extraSpecialArgs = {
inherit
@@ -293,6 +327,7 @@
hostname
hostTypes
;
+ host = hostname; # waybar-curved.nix and others expect `host`
};
users = {
"rogueking" = import ./../../home-manager/home.nix;
@@ -300,39 +335,6 @@
backupFileExtension = "backup";
};
- #home-manager = {
- # extraSpecialArgs = { inherit inputs; };
- # users = {
- # "rogueking" = import ../home-manager/home.nix;
- # };
- # backupFileExtension = "backup";
- #};
-
- # Some programs need SUID wrappers, can be configured further or are
- # started in user sessions.
- # programs.mtr.enable = true;
- # programs.gnupg.agent = {
- # enable = true;
- # enableSSHSupport = true;
- # };
-
- # List services that you want to enable:
-
- # Enable the OpenSSH daemon.
- # services.openssh.enable = true;
-
- # Open ports in the firewall.
- # networking.firewall.allowedTCPPorts = [ ... ];
- # networking.firewall.allowedUDPPorts = [ ... ];
- # Or disable the firewall altogether.
- # networking.firewall.enable = false;
-
- # This value determines the NixOS release from which the default
- # settings for stateful data, like file locations and database versions
- # on your system were taken. It‘s perfectly fine and recommended to leave
- # this value at the release version of the first install of this system.
- # Before changing this value read the documentation for this option
- # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
- system.stateVersion = "25.05"; # Did you read the comment?
+ system.stateVersion = "25.11";
}
diff --git a/hosts/eva-03/configuration.nix b/hosts/eva-03/configuration.nix
index 90671b8..e44ca7e 100644
--- a/hosts/eva-03/configuration.nix
+++ b/hosts/eva-03/configuration.nix
@@ -18,6 +18,7 @@
[ # Include the results of the hardware scan.
./hardware-configuration.nix
inputs.home-manager.nixosModules.default
+ inputs.stylix.nixosModules.stylix
];
#Kernel
@@ -41,7 +42,13 @@
# Nix optimizations
nix.optimise.automatic = true;
- nix.settings.auto-optimise-store = true;
+ nix.settings = {
+ download-buffer-size = 200000000;
+ auto-optimise-store = true;
+ substituters = ["https://hyprland.cachix.org"];
+ trusted-public-keys = ["hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="];
+ };
+
nix.gc = {
automatic = true;
dates = "weekly";
@@ -52,10 +59,6 @@
networking.hostName = "eva-03"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
- # Configure network proxy if necessary
- # networking.proxy.default = "http://user:password@proxy:port/";
- # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
-
# Enable networking
networking.networkmanager.enable = true;
@@ -93,10 +96,6 @@
# Modesetting is required.
modesetting.enable = true;
- # Nvidia power management. Experimental, and can cause sleep/suspend to fail.
- # Enable this if you have graphical corruption issues or application crashes after waking
- # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
- # of just the bare essentials.
# powerManagement.enable = false;
open = false;
@@ -173,6 +172,19 @@
CUDA_VISIBLE_DEVICES = "0,1";
};
};
+
+ services.comfyui = {
+ enable = true;
+ enableManager = true;
+ listenAddress = "0.0.0.0";
+ dataDir = "/home/rogueking/Documents/models/comfyui-data";
+ user = "rogueking";
+ group = "users";
+ package = pkgs-unstable.comfy-ui-cuda;
+ #createUser = true; # Use existing user
+ # If dataDir is on a separate mount (NFS, ZFS dataset, etc.):
+ # requiresMounts = [ "home-myuser-comfyui\\x2ddata.mount" ];
+ };
services.fprintd.enable = true;
services.fprintd.tod.enable = true;
@@ -295,6 +307,41 @@
dejavu_fonts
];
+ # Stylix
+ stylix = {
+ enable = true;
+ image = ../../assets/pfp/neonNerv.png;
+ polarity = "dark";
+ opacity.terminal = 1.0;
+ enableReleaseChecks = false;
+ targets.gtk.enable = false;
+ cursor = {
+ package = pkgs.bibata-cursors;
+ name = "Bibata-Modern-Ice";
+ size = 24;
+ };
+ fonts = {
+ monospace = {
+ package = pkgs.nerd-fonts.jetbrains-mono;
+ name = "JetBrains Mono";
+ };
+ sansSerif = {
+ package = pkgs.montserrat;
+ name = "Montserrat";
+ };
+ serif = {
+ package = pkgs.montserrat;
+ name = "Montserrat";
+ };
+ sizes = {
+ applications = 12;
+ terminal = 15;
+ desktop = 11;
+ popups = 12;
+ };
+ };
+ };
+
home-manager = {
extraSpecialArgs = {
inherit
@@ -304,6 +351,7 @@
hostname
hostTypes
;
+ host = hostname; # waybar-curved.nix and others expect `host`
};
users = {
"rogueking" = import ./../../home-manager/home.nix;