From 292b8e93727d5c3384b342b59a2f64b4ec3e475b Mon Sep 17 00:00:00 2001 From: Mitsuo Makuda Date: Thu, 13 Nov 2025 14:15:48 +0000 Subject: [PATCH] Version 0.1.0 --- .vscode/ltex.dictionary.en-GB.txt | 1 + flake.nix | 27 + home-manager/10_hypr/01_monitors.nix | 8 + home-manager/10_hypr/02_autostart.nix | 18 + home-manager/10_hypr/03_look-and-feel.nix | 21 + home-manager/10_hypr/04_decoration.nix | 27 + home-manager/10_hypr/05_animation.nix | 31 + home-manager/10_hypr/06_layouts.nix | 20 + home-manager/10_hypr/07_input.nix | 28 + home-manager/10_hypr/08_keybinds.nix | 70 ++ .../10_hypr/09_windows-and-workspaces.nix | 22 + home-manager/10_hypr/10_extras_ascii-boot.nix | 26 + home-manager/10_hypr/11_extras_quotes.nix | 20 + home-manager/10_hypr/12_hypr_shaders.nix | 14 + home-manager/10_hypr/13_waybar-watcher.nix | 106 +++ home-manager/10_hypr/14_refresh-eww.nix | 12 + home-manager/10_hypr/15_hyprpapr.nix | 10 + home-manager/10_hypr/default.nix | 56 ++ .../01_cursors-and-selection-colours.nix | 14 + .../20_alacritty/02_primary-colours.nix | 10 + .../20_alacritty/03_normal-palette-ansi.nix | 16 + .../20_alacritty/04_font-settings.nix | 26 + home-manager/20_alacritty/05_mouse.nix | 9 + home-manager/20_alacritty/default.nix | 20 + .../20_cava/01_shaders_bar-spectrum.nix | 68 ++ .../20_cava/02_shaders_northern-lights.nix | 29 + .../20_cava/03_shaders_pass-through.nix | 15 + .../20_cava/04_shaders_spectrogram.nix | 46 ++ .../05_shaders_winamp-line-style-spectrum.nix | 89 +++ home-manager/20_cava/default.nix | 87 +++ home-manager/20_eww/01_windows.nix | 472 +++++++++++++ home-manager/20_eww/02_scripts.nix | 629 ++++++++++++++++++ home-manager/20_eww/default.nix | 546 +++++++++++++++ home-manager/20_rofi/01_config.nix | 20 + home-manager/20_rofi/02_theme.nix | 110 +++ home-manager/20_rofi/default.nix | 8 + home-manager/20_waybar/01_config.nix | 215 ++++++ home-manager/20_waybar/02_style.nix | 192 ++++++ home-manager/20_waybar/03_scripts.nix | 301 +++++++++ home-manager/20_waybar/04_workspace.nix | 56 ++ home-manager/20_waybar/default.nix | 10 + home-manager/30_zsh/01_zshrc.nix | 21 + home-manager/30_zsh/default.nix | 7 + home-manager/home.nix | 68 ++ nixos/configuration.nix | 127 ++++ 45 files changed, 3728 insertions(+) create mode 100644 .vscode/ltex.dictionary.en-GB.txt create mode 100644 flake.nix create mode 100644 home-manager/10_hypr/01_monitors.nix create mode 100644 home-manager/10_hypr/02_autostart.nix create mode 100644 home-manager/10_hypr/03_look-and-feel.nix create mode 100644 home-manager/10_hypr/04_decoration.nix create mode 100644 home-manager/10_hypr/05_animation.nix create mode 100644 home-manager/10_hypr/06_layouts.nix create mode 100644 home-manager/10_hypr/07_input.nix create mode 100644 home-manager/10_hypr/08_keybinds.nix create mode 100644 home-manager/10_hypr/09_windows-and-workspaces.nix create mode 100644 home-manager/10_hypr/10_extras_ascii-boot.nix create mode 100644 home-manager/10_hypr/11_extras_quotes.nix create mode 100644 home-manager/10_hypr/12_hypr_shaders.nix create mode 100644 home-manager/10_hypr/13_waybar-watcher.nix create mode 100644 home-manager/10_hypr/14_refresh-eww.nix create mode 100644 home-manager/10_hypr/15_hyprpapr.nix create mode 100644 home-manager/10_hypr/default.nix create mode 100644 home-manager/20_alacritty/01_cursors-and-selection-colours.nix create mode 100644 home-manager/20_alacritty/02_primary-colours.nix create mode 100644 home-manager/20_alacritty/03_normal-palette-ansi.nix create mode 100644 home-manager/20_alacritty/04_font-settings.nix create mode 100644 home-manager/20_alacritty/05_mouse.nix create mode 100644 home-manager/20_alacritty/default.nix create mode 100644 home-manager/20_cava/01_shaders_bar-spectrum.nix create mode 100644 home-manager/20_cava/02_shaders_northern-lights.nix create mode 100644 home-manager/20_cava/03_shaders_pass-through.nix create mode 100644 home-manager/20_cava/04_shaders_spectrogram.nix create mode 100644 home-manager/20_cava/05_shaders_winamp-line-style-spectrum.nix create mode 100644 home-manager/20_cava/default.nix create mode 100644 home-manager/20_eww/01_windows.nix create mode 100644 home-manager/20_eww/02_scripts.nix create mode 100644 home-manager/20_eww/default.nix create mode 100644 home-manager/20_rofi/01_config.nix create mode 100644 home-manager/20_rofi/02_theme.nix create mode 100644 home-manager/20_rofi/default.nix create mode 100644 home-manager/20_waybar/01_config.nix create mode 100644 home-manager/20_waybar/02_style.nix create mode 100644 home-manager/20_waybar/03_scripts.nix create mode 100644 home-manager/20_waybar/04_workspace.nix create mode 100644 home-manager/20_waybar/default.nix create mode 100644 home-manager/30_zsh/01_zshrc.nix create mode 100644 home-manager/30_zsh/default.nix create mode 100644 home-manager/home.nix create mode 100644 nixos/configuration.nix diff --git a/.vscode/ltex.dictionary.en-GB.txt b/.vscode/ltex.dictionary.en-GB.txt new file mode 100644 index 0000000..9bf5935 --- /dev/null +++ b/.vscode/ltex.dictionary.en-GB.txt @@ -0,0 +1 @@ +NubNix diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7624190 --- /dev/null +++ b/flake.nix @@ -0,0 +1,27 @@ +{ + description = "NubNix - NixOS, Home Manager and Pewdiepie's Hyprland"; + + inputs = { + nixpkgs.url = "path:/run/media/nixos/GOLDENUSB/nixpkgs"; + home-manager.url = "path:/run/media/nixos/GOLDENUSB/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { self, nixpkgs, home-manager, ... }: + let + system = "x86_64-linux"; + in { + nixosConfigurations.nubnix = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + ./nixos/configuration.nix + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.friend = import ./home/home.nix; + } + ]; + }; + }; +} diff --git a/home-manager/10_hypr/01_monitors.nix b/home-manager/10_hypr/01_monitors.nix new file mode 100644 index 0000000..361b975 --- /dev/null +++ b/home-manager/10_hypr/01_monitors.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/01_monitors.conf".text = '' + # ── MONITORS ────────────────────────────────────────────────────────────── + monitor = eDP-1, preferred, auto, 1.25 + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/02_autostart.nix b/home-manager/10_hypr/02_autostart.nix new file mode 100644 index 0000000..fec77f9 --- /dev/null +++ b/home-manager/10_hypr/02_autostart.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/02_autostart.conf".text = '' + # ── AUTOSTART ───────────────────────────────────────────────────────────── + exec-once = ~/.config/hypr/scripts/waybar_watcher.sh & + + # FIREFOX PRELOAD - fast firefox bööt, just hide workspace 9. + exec-once = hyprctl dispatch exec '[workspace 9 silent] firefox --new-instance --profile ~/.mozilla/firefox/c> + + # EWW SCRIPTS + exec-once = ~/.config/eww/scripts/audio/audio_visualizer.py & + exec-once = cava -p ~/.config/cava/config & + + # ROFI image cache + exec-once = cp ~/.config/rofi/image.png /dev/shm/rofi_image.png + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/03_look-and-feel.nix b/home-manager/10_hypr/03_look-and-feel.nix new file mode 100644 index 0000000..1c4eaac --- /dev/null +++ b/home-manager/10_hypr/03_look-and-feel.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/03_look-and-feel.conf".text = '' + # ── LOOK AND FEEL ───────────────────────────────────────────────────────── + general { + col.active_border = rgba(9cdef2ff) + col.inactive_border = rgba(444444ff) + gaps_in = 5 + gaps_out = 20 + border_size = 2 + + col.active_border = rgba(61afefff) # Blue for focused windows + col.inactive_border = rgba(444444ff) + + resize_on_border = false + allow_tearing = false + layout = dwindle + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/04_decoration.nix b/home-manager/10_hypr/04_decoration.nix new file mode 100644 index 0000000..95f0029 --- /dev/null +++ b/home-manager/10_hypr/04_decoration.nix @@ -0,0 +1,27 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/04_decoration.conf".text = '' + # ── DECORATION ──────────────────────────────────────────────────────────── + decoration { + rounding = 1 + rounding_power = 2 + + active_opacity = 1.0 + inactive_opacity = 1.0 + + shadow { + enabled = true + range = 5 + render_power = 4 + color = rgba(1fbeffee) + } + + blur { + size = 2 + passes = 1 + brightness = 0.4 + } + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/05_animation.nix b/home-manager/10_hypr/05_animation.nix new file mode 100644 index 0000000..d7a8555 --- /dev/null +++ b/home-manager/10_hypr/05_animation.nix @@ -0,0 +1,31 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/05_animation.conf".text = '' + # ── ANIMATIONS ──────────────────────────────────────────────────────────── + animations { + enabled = yes, please :) + bezier = easeOutQuint,0.23,1,0.32,1 + bezier = easeInOutCubic,0.65,0.05,0.36,1 + bezier = linear,0,0,1,1 + bezier = almostLinear,0.5,0.5,0.75,1.0 + bezier = quick,0.15,0,0.1,1 + animation = global, 1, 10, default + animation = border, 1, 5.39, easeOutQuint + animation = windows, 1, 4.79, easeOutQuint + animation = windowsIn, 1, 4.1, easeOutQuint, popin 87% + animation = windowsOut, 1, 1.49, linear, popin 87% + animation = fadeIn, 1, 1.73, almostLinear + animation = fadeOut, 1, 1.46, almostLinear + animation = fade, 1, 3.03, quick + animation = layers, 1, 3.81, easeOutQuint + animation = layersIn, 1, 4, easeOutQuint, fade + animation = layersOut, 1, 1.5, linear, fade + animation = fadeLayersIn, 1, 1.79, almostLinear + animation = fadeLayersOut, 1, 1.39, almostLinear + animation = workspaces, 1, 1.94, almostLinear, fade + animation = workspacesIn, 1, 1.21, almostLinear, fade + animation = workspacesOut, 1, 1.94, almostLinear, fade + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/06_layouts.nix b/home-manager/10_hypr/06_layouts.nix new file mode 100644 index 0000000..b9ba65b --- /dev/null +++ b/home-manager/10_hypr/06_layouts.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/06_layouts.conf".text = '' + # ── LAYOUTS ─────────────────────────────────────────────────────────────── + dwindle { + pseudotile = true + preserve_split = true + } + + master { + new_status = master + } + + misc { + force_default_wallpaper = 0 + disable_hyprland_logo = true + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/07_input.nix b/home-manager/10_hypr/07_input.nix new file mode 100644 index 0000000..a05ce3a --- /dev/null +++ b/home-manager/10_hypr/07_input.nix @@ -0,0 +1,28 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/07_input.conf".text = '' + # ── INPUT ───────────────────────────────────────────────────────────────── + input { + kb_layout = gb, se, + kb_variant = + kb_model = + kb_options = + kb_rules = + follow_mouse = 1 + sensitivity = 0 + touchpad { + natural_scroll = true + } + } + + gestures { + workspace_swipe = false + } + + device { + name = epic-mouse-v1 + sensitivity = -0.5 + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/08_keybinds.nix b/home-manager/10_hypr/08_keybinds.nix new file mode 100644 index 0000000..e377fa5 --- /dev/null +++ b/home-manager/10_hypr/08_keybinds.nix @@ -0,0 +1,70 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/08_keybinds.conf".text = '' + # ── KEYBINDINGS ──────────────────────────────────────────────────────────── + $mainMod = SUPER L + $mod = SUPER + # Keyboard language switch + bind = SUPER, S, exec, hyprctl switchxkblayout "asus-keyboard-2" 0 + bind = SUPER, E, exec, hyprctl switchxkblayout "asus-keyboard-2" 1 + # Apps + bind = ALT, T, exec, $terminal + bind = ALT, B, exec, firefox + bind = ALT, F, exec, thunar + bind = ALT, W, killactive, + bind = ALT, V, togglefloating, + bind = ALT, {, pseudo, + bind = ALT, J, togglesplit, + bind = ALT, SPACE, exec, rofi -show drun + # Move focus + bind = ALT, left, movefocus, l + bind = ALT, right, movefocus, r + bind = ALT, up, movefocus, u + bind = ALT, down, movefocus, d + # Screenshot + bind = ALT, P, exec, slurp | tee >(grim -g "$(cat)" "$HOME/Pictures/Screenshots/screenshot-$(date +'%Y-%m-%d-%H%M%S').png") | grim -g "$(cat)" - | wl-copy + # Function keys + bind = , XF86KbdBrightnessDown, exec, bash ~/.config/kbd-brightness.sh down + bind = , XF86KbdBrightnessUp, exec, bash ~/.config/kbd-brightness.sh up + bind = , XF86Launch3, exec, bash ~/.config/kbd-breathing.sh + exec-once = bash ~/.config/kbd-brightness.sh & + bind = , XF86Launch4, exec, ~/.config/hypr/scripts/asus-kbd/cycle-profile.s + # Touchpad / Monitor + bind = , XF86Display, exec, hyprctl dispatch cyclenextmonitor + bind = , XF86Launch1, exec, ~/.config/hyprlock/lock.sh + # Workspaces + bind = ALT, 1, workspace, 1 + bind = ALT, 2, workspace, 2 + bind = ALT, 3, workspace, 3 + bind = ALT, 4, workspace, 4 + bind = ALT, 9, workspace, 9 #Kept hidden as "workspace for background tasks". + bind = $mainMod, 1, movetoworkspace, 1 + bind = $mainMod, 2, movetoworkspace, 2 + bind = $mainMod, 3, movetoworkspace, 3 + bind = $mainMod, 4, movetoworkspace, 4 + bind = $mainMod, 9, movetoworkspace, 9 + bind = $mainMod, S, togglespecialworkspace, magic + bind = $mainMod SHIFT, S, movetoworkspace, special:magic + bind = $mainMod, mouse_down, workspace, e+1 + bind = $mainMod, mouse_up, workspace, e-1 + bindm = ALT, mouse:272, movewindow + bindm = ALT, mouse:273, resizewindow + # Multimedia keys + bindel = , XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ + bindel = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- + bindel = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle + bindel = , XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle + bindel = , XF86MonBrightnessUp, exec, brightnessctl s 10%+ + bindel = , XF86MonBrightnessDown, exec, brightnessctl s 10%- + bindl = , XF86AudioNext, exec, playerctl next + bindl = , XF86AudioPause, exec, playerctl play-pause + bindl = , XF86AudioPlay, exec, playerctl play-pause + bindl = , XF86AudioPrev, exec, playerctl previous + # ── ASUS KEYBOARD SCRIPTS ────────────────────────────────────────────────── + bind = , XF86KbdBrightnessUp, exec, ~/.config/hypr/scripts/asus-kbd/kbd-brightness.sh up + bind = , XF86KbdBrightnessDown, exec, ~/.config/hypr/scripts/asus-kbd/kbd-brightness.sh down + bind = , XF86Launch3, exec, ~/.config/hypr/scripts/asus-kbd/kbd-breathing.sh + bind = , XF86Launch4, exec, ~/.config/hypr/scripts/asus-kbd/cycle-profile.sh + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/09_windows-and-workspaces.nix b/home-manager/10_hypr/09_windows-and-workspaces.nix new file mode 100644 index 0000000..212d2c9 --- /dev/null +++ b/home-manager/10_hypr/09_windows-and-workspaces.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/09_windows-and-workspaces.conf".text = '' + # ── WINDOWS AND WORKSPACES ──────────────────────────────────────────────── + windowrulev2 = suppressevent maximize, class:.* + windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0 + windowrulev2 = nofocus, class:^(eww)$ + + workspace=1,persistent:true + workspace=2,persistent:true + workspace=3,persistent:true + workspace=4,persistent:true + workspace=9,persistent:true + + workspace=1,monitor:eDP-1 + workspace=2,monitor:eDP-1 + workspace=3,monitor:eDP-1 + workspace=4,monitor:eDP-1 + workspace=9,monitor:eDP-1 + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/10_extras_ascii-boot.nix b/home-manager/10_hypr/10_extras_ascii-boot.nix new file mode 100644 index 0000000..c000e23 --- /dev/null +++ b/home-manager/10_hypr/10_extras_ascii-boot.nix @@ -0,0 +1,26 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/extras/ascii_boot.txt".text = '' + [ REACTOR STATUS REPORT ] + Date: 2025-04-21 Time: 15:05:35 + ============================================ + > Radiation Forecast................. +17°C + > Phantom Link....................... CONNECTED + > Battery Reserve.................... 62% + > Filesystem Mount................... OK + > Memory Integrity................... STABLE (77% free) + > Display Pipeline................... ACTIVE + > Audio Interface.................... IDLE + > Bluetooth Module................... ONLINE + > Internet Uplink.................... ESTABLISHED + > Hyprland Interface................. ACTIVE + ============================================ + + > "“Pain and suffering are always inevitable for a large intelligence and a deep heart.”" + – Dostoevsky + + >>> DOBRO POZHALOVAT', KOMANDIR. + >>> PANEL' UPRAVLENIYA REAKTORA: ONLINE. + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/11_extras_quotes.nix b/home-manager/10_hypr/11_extras_quotes.nix new file mode 100644 index 0000000..a9e224e --- /dev/null +++ b/home-manager/10_hypr/11_extras_quotes.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/extras/quotes.txt".text = '' + “I’ve lived to bury my desires.” - Pushkin + “Become who you are.” - Nietzsche + “One must still have chaos in oneself to be able to give birth to a dancing star.” - Nietzsche + “I am not a man, I am dynamite.” - Nietzsche + “There are no beautiful surfaces without a terrible depth.” - Nietzsche + “Pain and suffering are always inevitable for a large intelligence and a deep heart.” - Dostoevsky + “Above all, don’t lie to yourself.” - Dostoevsky + “Taking a new step, uttering a new word, is what people fear most.” - Dostoevsky + “To go wrong in one’s own way is better than to go right in someone else’s.” - Dostoevsky + “I’ve lived to bury my desires, and see my dreams corrode with rust.” - Pushkin + “My name has become a legend - and I remain a shadow.” - Pushkin + “I loved you: perhaps that flame still burns.” - Pushkin + “And I shall bury myself in my books and the silence of my dreams.” - Pushkin + “Life deceives the hopeful, but art is always true.” - Pushkin + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/12_hypr_shaders.nix b/home-manager/10_hypr/12_hypr_shaders.nix new file mode 100644 index 0000000..c7474ab --- /dev/null +++ b/home-manager/10_hypr/12_hypr_shaders.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/shaders/screenshot_overlay.frag".text = '' + #version 330 + uniform sampler2D tex; + in vec2 uv; + out vec4 fragColor; + void main() { + vec4 color = texture(tex, uv); + fragColor = mix(color, vec4(0.2, 0.4, 0.8, 1.0), 0.4); // Adjust the blue tint strength + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/13_waybar-watcher.nix b/home-manager/10_hypr/13_waybar-watcher.nix new file mode 100644 index 0000000..ac99a02 --- /dev/null +++ b/home-manager/10_hypr/13_waybar-watcher.nix @@ -0,0 +1,106 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/wallpapers/black.png".source = + pkgs.fetchurl { + url = "https://github.com/pewdiepie-archdaemon/dionysus/blob/dionysus/dotfiles/hypr/wallpapers/black.png?raw=true"; + sha256 = "06cfc2114fe04546436ddb47e2dfd7655e2d7be4d184be0a7b123d96c06cc91a"; + }; + + home.file.".config/hypr/wallpapers/bg_wallpaper.png".source = + pkgs.fetchurl { + url = "https://github.com/pewdiepie-archdaemon/dionysus/blob/dionysus/dotfiles/hypr/wallpapers/bg_wallpaper.png?raw=true"; + sha256 = "d87aafd5486f6b6231f172411bea9633ff3550a65d4bd52bbc3176ca37e1afa9"; + }; + + home.file.".config/hypr/scripts/waybar-watcher.sh".text = '' + #!/bin/bash + + touch "/var/log/waybar_watcher.log" + logfile="/var/log/waybar_watcher.log" + wallpaper_with_window="/home/nubfriedrice/.config/hypr/wallpapers/black.png" + wallpaper_without_window="/home/nubfriedrice/.config/hypr/wallpapers/bg_wallpaper.png" + current_wallpaper="" + eww_visible=false + waybar_visible=false + monitor=$(hyprctl monitors -j | jq -r '.[0].name') + + # Eww widgets + eww_windows="active_workspace \ + ascii_decor_frame \ + audio_status \ + cpu_ram_storage_bars \ + four_boxes \ + net_bars \ + orange_workspace \ + power-cooling_header_text \ + power_mode_text \ + right_fan_data \ + right_internet_text \ + visualizer_window \ + welcome_text \ + workspace_window_text" + + # Start hyprpaper if needed + if ! pgrep -x hyprpaper > /dev/null; then + echo "Starting hyprpaper..." >> "$logfile" + hyprpaper & + sleep 1 + fi + + while true; do + echo "--- $(date) ---" >> "$logfile" + active_workspace=$(hyprctl activeworkspace -j | jq -r '.id') + window_count=$(hyprctl clients -j | jq "[.[] | select(.workspace.id == $active_workspace and .mapped == true)] | length") + echo "Window count: $window_count" >> "$logfile" + + if [ "$window_count" -eq 0 ]; then + # No windows → Eww on, Waybar off + if [ "$current_wallpaper" != "$wallpaper_without_window" ]; then + echo "Switching to wallpaper WITHOUT window" >> "$logfile" + hyprctl hyprpaper preload "$wallpaper_without_window" + sleep 0.3 + hyprctl hyprpaper wallpaper "$monitor,$wallpaper_without_window" + current_wallpaper="$wallpaper_without_window" + fi + + if ! $eww_visible; then + echo "Launching Eww widgets..." >> "$logfile" + pgrep -x eww || eww daemon & + sleep 1 + eww open-many $eww_windows + eww_visible=true + fi + + if $waybar_visible; then + echo "Stopping Waybar..." >> "$logfile" + pkill -x waybar + waybar_visible=false + fi + + else + # Windows → Waybar on, Eww off + if [ "$current_wallpaper" != "$wallpaper_with_window" ]; then + echo "Switching to wallpaper WITH window" >> "$logfile" + hyprctl hyprpaper preload "$wallpaper_with_window" + sleep 0.3 + hyprctl hyprpaper wallpaper "$monitor,$wallpaper_with_window" + current_wallpaper="$wallpaper_with_window" + fi + + if $eww_visible; then + echo "Hiding Eww widgets..." >> "$logfile" + eww close-all + eww_visible=false + fi + + if ! $waybar_visible; then + echo "Starting Waybar..." >> "$logfile" + nohup waybar >/dev/null 2>&1 & + waybar_visible=true + fi + fi + sleep 0.5 + done + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/14_refresh-eww.nix b/home-manager/10_hypr/14_refresh-eww.nix new file mode 100644 index 0000000..1171bc4 --- /dev/null +++ b/home-manager/10_hypr/14_refresh-eww.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/scripts/refresh-eww.sh".text = '' + #!/bin/bash + while true; do + eww update line_refresh=$(date +%s%3N) + sleep 0.05 + done + } + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/15_hyprpapr.nix b/home-manager/10_hypr/15_hyprpapr.nix new file mode 100644 index 0000000..54c0a73 --- /dev/null +++ b/home-manager/10_hypr/15_hyprpapr.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/hypr/hyprpaper.conf".text = '' + preload=$HOME/.config/hypr/wallpapers/black.png + preload=$HOME/.config/hypr/wallpapers/bg_wallpaper.png + wallpaper=eDP-1,$HOME/.config/hypr/wallpapers/bg_wallpaper.png + fit=2 + ''; +} \ No newline at end of file diff --git a/home-manager/10_hypr/default.nix b/home-manager/10_hypr/default.nix new file mode 100644 index 0000000..521c431 --- /dev/null +++ b/home-manager/10_hypr/default.nix @@ -0,0 +1,56 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./01_monitors.nix + ./02_autostart.nix + ./03_look-and-feel.nix + ./04_decoration.nix + ./05_animation.nix + ./06_layouts.nix + ./07_input.nix + ./08_keybinds.nix + ./09_windows-and-workspaces.nix + ./10_extras_ascii-boot.nix + ./11_extras_quotes.nix + ./12_hypr_shaders.nix + ./13_waybar-watcher.nix + ./14_refresh-eww.nix + ./15_hyprpapr.nix + ]; + + home.file.".config/hypr/hyprland.conf".text = '' + # ────────────────────────────────────────────────────────────────────────── + # °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh shhheersh + # Hyprland config + # vers. 1.0-nix + # ────────────────────────────────────────────────────────────────────────── + + # ── MONITORS ────────────────────────────────────────────────────────────── + source=~/.config/hypr/01_monitors.conf + + # ── AUTOSTART ───────────────────────────────────────────────────────────── + source=~/.config/hypr/02_autostart.conf + + # ── LOOK AND FEEL ───────────────────────────────────────────────────────── + source=~/.config/hypr/03_look-and-feel.conf + + # ── DECORATION ──────────────────────────────────────────────────────────── + source=~/.config/hypr/04_decoration.conf + + # ── ANIMATIONS ──────────────────────────────────────────────────────────── + source=~/.config/hypr/05_animation.conf + + # ── LAYOUTS ─────────────────────────────────────────────────────────────── + source=~/.config/hypr/06_layouts.conf + + # ── INPUT ───────────────────────────────────────────────────────────────── + source=~/.config/hypr/07_input.conf + + # ── KEYBINDINGS ─────────────────────────────────────────────────────────── + source=~/.config/hypr/08_keybindings.conf + + # ── WINDOWS AND WORKSPACES ──────────────────────────────────────────────── + source=~/.config/hypr/09_windows-and-workspaces.conf + ''; +} \ No newline at end of file diff --git a/home-manager/20_alacritty/01_cursors-and-selection-colours.nix b/home-manager/20_alacritty/01_cursors-and-selection-colours.nix new file mode 100644 index 0000000..117aa7d --- /dev/null +++ b/home-manager/20_alacritty/01_cursors-and-selection-colours.nix @@ -0,0 +1,14 @@ +{ config, pkgs, lib, ... }: + +{ + home.file.".config/alacritty/01_cursors-and-selection-colours.toml".text = '' + # ── Cursor & Selection Colours ──────────────────────────────────────────── + [colors.cursor] + cursor = "#528bff" + text = "#9cdef2" + + [colors.selection] + text = "#9cdef2" + background = "#3e4451" + ''; +} \ No newline at end of file diff --git a/home-manager/20_alacritty/02_primary-colours.nix b/home-manager/20_alacritty/02_primary-colours.nix new file mode 100644 index 0000000..f7732d9 --- /dev/null +++ b/home-manager/20_alacritty/02_primary-colours.nix @@ -0,0 +1,10 @@ +{ config, pkgs, lib, ... }: + +{ + home.file.".config/alacritty/02_primary-colours.toml".text = '' + # ── Primary Colours ─────────────────────────────────────────────────────── + [colors.primary] + background = "#282c34" + foreground = "#9cdef2" + ''; +} \ No newline at end of file diff --git a/home-manager/20_alacritty/03_normal-palette-ansi.nix b/home-manager/20_alacritty/03_normal-palette-ansi.nix new file mode 100644 index 0000000..fb1442b --- /dev/null +++ b/home-manager/20_alacritty/03_normal-palette-ansi.nix @@ -0,0 +1,16 @@ +{ config, pkgs, lib, ... }: + +{ + home.file.".config/alacritty/03_normal-palette-ansi.toml".text = '' + # ── Normal Palette (ANSI) ───────────────────────────────────────────────── + [colors.normal] + black = "#2e3440" + red = "#e06c75" + green = "#9cdef2" + yellow = "#e5c07b" + blue = "#61afef" + magenta = "#c678dd" + cyan = "#9cdef2" + white = "#828997" + ''; +} \ No newline at end of file diff --git a/home-manager/20_alacritty/04_font-settings.nix b/home-manager/20_alacritty/04_font-settings.nix new file mode 100644 index 0000000..de3bf75 --- /dev/null +++ b/home-manager/20_alacritty/04_font-settings.nix @@ -0,0 +1,26 @@ +{ config, pkgs, lib, ... }: + +{ + home.file.".config/alacritty/04_font-settings.toml".text = '' + # ── Font Settings ───────────────────────────────────────────────────────── + [font] + size = 11.0 + + [font.normal] + family = "Gohu GohuFont" + style = "Regular" + + [font.bold] + family = "Gohu GohuFont" + style = "Bold" + + [font.italic] + family = "Gohu GohuFont" + style = "Italic" + + [font.bold_italic] + family = "Gohu GohuFont" + style = "Bold Italic" + + ''; +} \ No newline at end of file diff --git a/home-manager/20_alacritty/05_mouse.nix b/home-manager/20_alacritty/05_mouse.nix new file mode 100644 index 0000000..4bd9a44 --- /dev/null +++ b/home-manager/20_alacritty/05_mouse.nix @@ -0,0 +1,9 @@ +{ config, pkgs, lib, ... }: + +{ + home.file.".config/alacritty/05_mouse.toml".text = '' + # ── Mouse & Environment ─────────────────────────────────────────────────── + [mouse] + hide_when_typing = true + ''; +} \ No newline at end of file diff --git a/home-manager/20_alacritty/default.nix b/home-manager/20_alacritty/default.nix new file mode 100644 index 0000000..f7c10e0 --- /dev/null +++ b/home-manager/20_alacritty/default.nix @@ -0,0 +1,20 @@ +{ config, pkgs, lib, ... }: + +{ + home.file.".config/alacritty/alacritty.toml".text = '' + # ────────────────────────────────────────────────────────────────────────── + # °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh shhheersh + # Nord-inspired, neon-accent terminal theme + # vers. 1.0.0-nix + # ────────────────────────────────────────────────────────────────────────── + [general] + import [ + "~/.config/alacritty/01_cursors-and-selection-colours.toml" + "~/.config/alacritty/02_primary-colours.toml" + "~/.config/alacritty/03_normal-palette-ansi.toml" + "~/.config/alacritty/04_font-settings.toml" + "~/.config/alacritty/05_mouse.toml" + ] + ''; + +} \ No newline at end of file diff --git a/home-manager/20_cava/01_shaders_bar-spectrum.nix b/home-manager/20_cava/01_shaders_bar-spectrum.nix new file mode 100644 index 0000000..886e285 --- /dev/null +++ b/home-manager/20_cava/01_shaders_bar-spectrum.nix @@ -0,0 +1,68 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/cava/shaders/bar_spectrum.frag".text = '' + #version 330 + + in vec2 fragCoord; + out vec4 fragColor; + + // bar values. defaults to left channels first (low to high), then right (high to low). + uniform float bars[512]; + + uniform int bars_count; // number of bars (left + right) (configurable) + uniform int bar_width; // bar width (configurable), not used here + uniform int bar_spacing; // space bewteen bars (configurable) + uniform vec3 u_resolution; // window resolution + + //colors, configurable in cava config file (r,g,b) (0.0 - 1.0) + uniform vec3 bg_color; // background color + uniform vec3 fg_color; // foreground color + uniform int gradient_count; + uniform vec3 gradient_colors[8]; // gradient colors + + vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max) { + //create color based on fraction of this color and next color + float yr = (y - y_min) / (y_max - y_min); + return col_1 * (1.0 - yr) + col_2 * yr; + } + + void main() { + // find which bar to use based on where we are on the x axis + float x = u_resolution.x * fragCoord.x; + int bar = int(bars_count * fragCoord.x); + //calculate a bar size + float bar_size = u_resolution.x / bars_count; + //the y coordinate and bar values are the same + float y = bars[bar]; + // make sure there is a thin line at bottom + if (y * u_resolution.y < 1.0) { + y = 1.0 / u_resolution.y; + } + //draw the bar up to current height + if (y > fragCoord.y) { + //make some space between bars basen on settings + if (x > (bar + 1) * (bar_size) - bar_spacing) { + fragColor = vec4(bg_color,1.0); + } + else { + if (gradient_count == 0) { + fragColor = vec4(fg_color,1.0); + } + else { + //find which color in the configured gradient we are at + int color = int((gradient_count - 1) * fragCoord.y); + //find where on y this and next color is supposed to be + float y_min = color / (gradient_count - 1.0); + float y_max = (color + 1.0) / (gradient_count - 1.0); + //make color + fragColor = vec4(normalize_C(fragCoord.y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0); + } + } + } + else { + fragColor = vec4(bg_color,1.0); + } + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_cava/02_shaders_northern-lights.nix b/home-manager/20_cava/02_shaders_northern-lights.nix new file mode 100644 index 0000000..ae4fb02 --- /dev/null +++ b/home-manager/20_cava/02_shaders_northern-lights.nix @@ -0,0 +1,29 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/cava/shaders/northern_lights.frag".text = '' + #version 330 + in vec2 fragCoord; + out vec4 fragColor; + // bar values. defaults to left channels first (low to high), then right (high to low). + uniform float bars[512]; + uniform int bars_count; // number of bars (left + right) (configurable) + uniform vec3 u_resolution; // window resolution, not used here + //colors, configurable in cava config file + uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here + uniform vec3 fg_color; // foreground color, not used here + void main() { + // find which bar to use based on where we are on the x axis + int bar = int(bars_count * fragCoord.x); + float bar_y = 1.0 - abs((fragCoord.y - 0.5)) * 2.0; + float y = (bars[bar]) * bar_y; + float bar_x = (fragCoord.x - float(bar) / float(bars_count)) * bars_count; + float bar_r = 1.0 - abs((bar_x - 0.5)) * 2; + bar_r = bar_r * bar_r * 2; + // set color + fragColor.r = fg_color.x * y * bar_r; + fragColor.g = fg_color.y * y * bar_r; + fragColor.b = fg_color.z * y * bar_r; + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_cava/03_shaders_pass-through.nix b/home-manager/20_cava/03_shaders_pass-through.nix new file mode 100644 index 0000000..728f6a3 --- /dev/null +++ b/home-manager/20_cava/03_shaders_pass-through.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/cava/shaders/pass_through.vert".text = '' + #version 330 + // Input vertex data, different for all executions of this shader. + layout(location = 0) in vec3 vertexPosition_modelspace; + // Output data ; will be interpolated for each fragment. + out vec2 fragCoord; + void main() { + gl_Position = vec4(vertexPosition_modelspace,1); + fragCoord = (vertexPosition_modelspace.xy+vec2(1,1))/2.0; + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_cava/04_shaders_spectrogram.nix b/home-manager/20_cava/04_shaders_spectrogram.nix new file mode 100644 index 0000000..e82067b --- /dev/null +++ b/home-manager/20_cava/04_shaders_spectrogram.nix @@ -0,0 +1,46 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/cava/shaders/spectrogram.frag".text = '' + #version 330 + in vec2 fragCoord; + out vec4 fragColor; + // bar values. defaults to left channels first (low to high), then right + // (high to low). + uniform float bars[512]; + uniform int bars_count; // number of bars (left + right) (configurable) + uniform int bar_width; // bar width (configurable), not used here + uniform int bar_spacing; // space bewteen bars (configurable) + uniform vec3 u_resolution; // window resolution + // colors, configurable in cava config file (r,g,b) (0.0 - 1.0) + uniform vec3 bg_color; // background color + uniform vec3 fg_color; // foreground color + uniform int gradient_count; + uniform vec3 gradient_colors[8]; // gradient colors + uniform sampler2D inputTexture; // Texture from the first render pass + vec3 normalize_C(float y, vec3 col_1, vec3 col_2, float y_min, float y_max) { + // create color based on fraction of this color and next color + float yr = (y - y_min) / (y_max - y_min); + return col_1 * (1.0 - yr) + col_2 * yr; + } + void main() { + // find which bar to use based on where we are on the y axis + int bar = int(bars_count * fragCoord.y); + float y = bars[bar]; + float band_size = 1.0 / float(bars_count); + float current_band_min = bar * band_size; + float current_band_max = (bar + 1) * band_size; + int hist_length = 512; + float win_size = 1.0 / hist_length; + if (fragCoord.x > 1.0 - win_size) { + if (fragCoord.y > current_band_min && fragCoord.y < current_band_max) { + fragColor = vec4(fg_color * y, 1.0); + } + } else { + vec2 offsetCoord = fragCoord; + offsetCoord.x += float(win_size); + fragColor = texture(inputTexture, offsetCoord); + } + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_cava/05_shaders_winamp-line-style-spectrum.nix b/home-manager/20_cava/05_shaders_winamp-line-style-spectrum.nix new file mode 100644 index 0000000..a60001f --- /dev/null +++ b/home-manager/20_cava/05_shaders_winamp-line-style-spectrum.nix @@ -0,0 +1,89 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/cava/shaders/winamp_line_style_spectrum.frag".text = '' + #version 330 + // Emulate the "line style" spectrum analyzer from Winamp 2. + // Try this config for a demonstration: + /* + [general] + bar_width = 2 + bar_spacing = 0 + higher_cutoff_freq = 22000 + [output] + method = sdl_glsl + channels = mono + fragment_shader = winamp_line_style_spectrum.frag + [color] + background = '#000000' + gradient = 1 + gradient_color_1 = '#319C08' + gradient_color_2 = '#29CE10' + gradient_color_3 = '#BDDE29' + gradient_color_4 = '#DEA518' + gradient_color_5 = '#D66600' + gradient_color_6 = '#CE2910' + [smoothing] + noise_reduction = 10 + */ + in vec2 fragCoord; + out vec4 fragColor; + // bar values. defaults to left channels first (low to high), then right (high to low). + uniform float bars[512]; + uniform int bars_count; // number of bars (left + right) (configurable) + uniform int bar_width; // bar width (configurable), not used here + uniform int bar_spacing; // space bewteen bars (configurable) + uniform vec3 u_resolution; // window resolution + //colors, configurable in cava config file (r,g,b) (0.0 - 1.0) + uniform vec3 bg_color; // background color + uniform vec3 fg_color; // foreground color + uniform int gradient_count; + uniform vec3 gradient_colors[8]; // gradient colors + vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max) { + //create color based on fraction of this color and next color + float yr = (y - y_min) / (y_max - y_min); + return col_1 * (1.0 - yr) + col_2 * yr; + } + + void main() + { + // find which bar to use based on where we are on the x axis + float x = u_resolution.x * fragCoord.x; + int bar = int(bars_count * fragCoord.x); + //calculate a bar size + float bar_size = u_resolution.x / bars_count; + //the y coordinate is stretched by 4X to resemble Winamp + float y = min(bars[bar] * 4.0, 1.0); + // make sure there is a thin line at bottom + if (y * u_resolution.y < 1.0) { + y = 1.0 / u_resolution.y; + } + vec4 bar_color; + if (gradient_count == 0) { + bar_color = vec4(fg_color,1.0); + } + else { + //find color in the configured gradient for the top of the bar + int color = int((gradient_count - 1) * y); + //find where on y this and next color is supposed to be + float y_min = float(color) / (gradient_count - 1.0); + float y_max = float(color + 1) / (gradient_count - 1.0); + //make a solid color for the entire bar + bar_color = vec4(normalize_C(y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0); + } + //draw the bar up to current height + if (y > fragCoord.y) { + //make some space between bars based on settings + if (x > (bar + 1) * (bar_size) - bar_spacing) { + fragColor = vec4(bg_color,1.0); + } + else { + fragColor = bar_color; + } + } + else { + fragColor = vec4(bg_color,1.0); + } + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_cava/default.nix b/home-manager/20_cava/default.nix new file mode 100644 index 0000000..39e704c --- /dev/null +++ b/home-manager/20_cava/default.nix @@ -0,0 +1,87 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./01_shaders_bar-spectrum.nix + ./02_shaders_nothern-lights.nix + ./03_shaders_pass-through.nix + ./04_shaders_spectrogram.nix + ./05_shaders_winamp-line-style-spectrum.nix + ]; + + home.file = { + ".config/cava/config".text = '' + # ────────────────────────────────────────────────────────────────────────── + # °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh shhheersh + # Custom config for cava + # vers. 1.0.0-nix + # ────────────────────────────────────────────────────────────────────────── + + ; ── General ─────────────────────────────────────────────────────────────── + [general] + ; framerate – frames per second (non‑negative) + framerate = 64 + + ; number of bars (0 = auto). 64 gives a nice “classic” look. + bars = 64 + + ; ── Input ───────────────────────────────────────────────────────────────── + [input] + ; Choose the backend you actually use. Here we keep *pulse* active and + ; leave the other back‑ends commented for easy switching. + method = pulse + source = alsa_output.pci-0000_06_00.6.analog-stereo.monitor + ;method = pipewire + ;source = auto + ;method = alsa + ;source = hw:Loopback,1 + ;method = fifo + ;source = /tmp/mpd.fifo + ;method = shmem + ;source = /squeezelite-AA:BB:CC:DD:EE:FF + ;method = portaudio + ;source = auto + ;method = sndio + ;source = default + ;method = oss + ;source = /dev/dsp + ;method = jack + ;source = default + + ; ── Output ──────────────────────────────────────────────────────────────── + [output] + ; Raw output is the most portable – it writes binary/ascii data to a FIFO. + method = raw + raw_target = /tmp/cava.raw ; where the data will be written + data_format = ascii ; ascii makes it easy to inspect with `cat` + + ; Uncomment and adjust if you ever need binary data. + ;bit_format = 16bit + + ; ── Colours ─────────────────────────────────────────────────────────────── + [color] + ; Keep the terminal’s own palette (default) – edit only if your terminal + ; supports true‑colour changes. + ;background = default + ;foreground = default + + ; ── Smoothing ───────────────────────────────────────────────────────────── + [smoothing] + ; The “Monstercat” smoothing algorithm gives a nice, slightly‑soft look. + ; Set to 0 to disable, 1‑100 to increase smoothness. + monstercat = 0 + waves = 0 + + ; ── Equaliser (optional) ────────────────────────────────────────────────── + [eq] + ; Uncomment the bands you want to boost/cut. Values are 0‑100 where 50 is + ; “no change”. Example shows a flat (all‑50) EQ. + ;1 = 50 ; bass + ;2 = 50 + ;3 = 50 ; mid‑tone + ;4 = 50 + ;5 = 50 ; treble + ''; + }; + +} \ No newline at end of file diff --git a/home-manager/20_eww/01_windows.nix b/home-manager/20_eww/01_windows.nix new file mode 100644 index 0000000..67a53f2 --- /dev/null +++ b/home-manager/20_eww/01_windows.nix @@ -0,0 +1,472 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/eww/windows/ascii/audio_status.yuck".text = '' + ;; ── audio_status ─────────────────────────────────────────────────────────── + ;; Text displaying audio status. + ;; Anchored top outside visualizer + (defwindow audio_status + :visible show_eww + :anchor "top right" + :geometry (geometry :x "79px" :y "288px" :width "300px" :height "40px") + :stacking "bg" + :monitor 0 + :exclusive false + :focusable false + (box :orientation "vertical" :halign "end" + (label :text ascii_audio_status :class "ascii-core-status") + ) + ) + ''; + + home.file.".config/eww/windows/ascii/visualizer_window.yuck".text = '' + ;; ── visualizer window ─────────────────────────────────────────────────── + ;; Displays ASCII visual for audio activity. + ;; Anchored very top + (defwindow audio_status + :visible show_eww + :anchor "top right" + :geometry (geometry :x "79px" :y "288px" :width "300px" :height "40px") + :stacking "bg" + :monitor 0 + :exclusive false + :focusable false + (box :orientation "vertical" :halign "end" + (label :text ascii_audio_status :class "ascii-core-status") + ) + ) + (defwindow visualizer_window + :visible show_eww + :monitor 0 + :geometry (geometry :x 38 :y 143 :width 340 :height 150) + :layer "bottom" + :stacking "bg" + :focusable false + :window-type "wayland" + :anchor [ "top center" ] + (audio-visualizer)) + (defwidget audio-visualizer [] + (box + :class "visualizer-outer-frame" + :padding 6 + (box + :class "visualizer-inner-frame" + :padding 10 + (label + :text visualizer_content + :markup true + :class "visualizer-text")))) + ''; + + home.file.".config/eww/windows/bar/cpu_ram_storage_bars.yuck".text = '' + ;; ── CPU RAM Storage ─────────────────────────────────────────────────── + ;; Text displaying cpu load, ram usage, storage + ;; Anchored middle left + + (defwindow cpu_ram_storage_bars + :visible show_eww + :anchor "top right" + :monitor 0 + :geometry (geometry :x "33px" :y "482px" :width "450px" :height "140px") + :stacking "bg" + :exclusive false + :focusable false + (box :orientation "vertical" :halign "start" :space "10px" + ;; ==== CPU LOAD ==== + (label :text " [ CPU LOAD ]" :class "stats-label" :halign "start") + (box :orientation "horizontal" :halign "start" :space "4px" + (box :class "module-frame" :orientation "vertical" :halign "start" :style "margin-top: -8px;" + (label :text cpu_bar :class "ram-bar") + ) + (box :class "module-frame" :orientation "vertical" :halign "start" :style "min-width: 40px; padding: 0px;" + (label :text cpu_usage :class "ram-bar2" :halign "center")) + ) + ;; ==== RAM USAGE ==== + (label :text " [ RAM USAGE ]" :class "stats-label" :halign "start") + (box :orientation "horizontal" :halign "center" :space "4px" + ;; LEFT: ASCII RAM BAR + (box :class "module-frame" :orientation "vertical" :halign "start" :style "margin-top: -8px;" + (label :text ram_bar :class "ram-bar")) + ;; RIGHT: RAM PERCENT + (box :class "module-frame" :orientation "vertical" :halign "start" :style "padding: 0px; ; min-width: 40px" + (label :text ram_percent :class "ram-bar2" :halign "center")) + ) + ;; ==== CPU LOAD ==== + ;; ==== STORAGE REMAINING ==== + (label :text " [ STORAGE ]" :class "stats-label" :halign "start") + (box :orientation "horizontal" :halign "center" :space "4px" + (box :class "module-frame" :orientation "vertical" :halign "start" :style "margin-top: -8px;" + (label :text storage_bar :class "ram-bar")) + (box :class "module-frame" :orientation "vertical" :halign "start" :style "min-width: 35px; padding: 2px;" + (label :text storage_percent :class "ram-bar2" :halign "center")) + ) + ) + ) + ''; + + home.file.".config/eww/windows/misc/welcome_text.yuck".text = '' + ;; ── welcome text─────────────────────────────────────────────────── + ;; Text displaying date and weather in cyrilic + ;; Anchored right screen + (defwindow welcome_text + :visible show_eww + :anchor "top" + :monitor 0 + :geometry (geometry :x "1740px" :y "152px" :width "100px" :height "90px") + :stacking "bg" + :exclusive false + :focusable false + (box :orientation "vertical" :halign "end" :class "stats-box" :space "1px" + ;; Welcome Line + (label :text "> Добро пожаловать, ${USER}" :class "label-primary" :halign "end" :style "margin-top: -20px;") + ;; Date Line + (label :text "Текущая дата: ${welcome_date}" :class "label-primary" :halign "end" :style "margin-top: -10px;") + ;; Weather Line + (label :text "Погода: ${weather_forecast}" :class "label-primary" :halign "end" :style "margin-top: -10px;") + ) + ) + ''; + + home.file.".config/eww/windows/net/ascii_decor_frame.yuck".text = '' + ;; ── ascii decor frame ─────────────────────────────────────────────────── + ;; Text displaying audio status. + ;; Anchored top inside visualizer + (defwindow ascii_decor_frame + :visible show_eww + :anchor "bottom right" + :geometry (geometry :x "30px" :y "808px" :width "220px" :height "100px") + :stacking "bg" + :exclusive false + :focusable false + :monitor 0 + (box :orientation "vertical" :halign "center" :valign "center" + (label :text ascii_decor1 :class "ascii-decor1") + ) + ) + ''; + + home.file.".config/eww/windows/net/net_bars.yuck".text = '' + ;; ── net bars ─────────────────────────────────────────────────── + ;; Text header and vectors showing network info + ;; Anchored bottom + + (defwindow net_bars + :visible show_eww + :anchor "top left" + :geometry (geometry :x "9px" :y "638px" :width "420px" :height "120px") + :stacking "bg" + :exclusive false + :focusable false + :monitor 0 + + ;; Horizontal layout for side-by-side bars + (box :orientation "horizontal" :halign "center" :space "10px" + + ;; DOWNLOAD BAR + (box :orientation "vertical" :halign "center" + (label :text "[ DOWNLOAD ]" :style "margin-top: 160px;" :class "stats-label") + (box :class "module-frame2" + (label :text download_bar :class "ram-bar")) + ) + + ;; UPLOAD BAR + (box :orientation "vertical" :halign "center" :style "min-width: 81px;" + (label :text "[ UPLOAD ]" :style "margin-top: 160px;" :class "stats-label") + (box :class "module-frame2" + (label :text upload_bar :class "ram-bar")) + ) + + ;; LATENCY BAR + (box :orientation "vertical" :halign "center" + (label :text "[ LATENCY ]" :style "margin-top: 160px;" :class "stats-label") + (box :class "module-frame2" + (label :text ping_bar :class "ram-bar")) + ) + + ;; VPN BAR + (box :orientation "vertical" :halign "center" :style "min-width: 81px;" + (label :text "[ VPN ]" :style "margin-top: 160px;" :class "stats-label") + (box :class "module-frame2" + (label + :text vpn_bar + :markup true ;; allow ASCII multi-line + :class "ram-bar")) + + ) + ) + ) + ''; + + home.file.".config/eww/windows/net/right_internet_text.yuck".text = '' + ;; ── right internet text ─────────────────────────────────────────────────── + ;; Text displaying ping and vpn status + ;; Anchored top very bottom right + + (defwindow right_internet_text + :visible show_eww + :anchor "top left" + :monitor 0 + :geometry (geometry :x "42px" :y "976px" :width "320px" :height "80px") + :stacking "bg" + :exclusive false + :focusable false + + (box :class "internet-clean-box" :orientation "vertical" :halign "center" :space "8px" + (box :orientation "horizontal" :halign "center" :space "6px" + (label :text download_speed :class "label-primary2") + (label :text upload_speed :class "label-primary2") + (label :text ping_ms :class "label-primary2") + (label :text vpn_status_text :class "label-primary2") + + ) + ) + ) + ''; + + home.file.".config/eww/windows/sys/active_workspace.yuck".text = '' + ;; ── active workspace ─────────────────────────────────────────────────── + ;; Text displaying active/inactive workspaces + ;; Anchored middle right + + (defwindow active_workspace + :visible show_eww + :anchor "top left" + :geometry (geometry :x "267px" :y "502px" :width "100px" :height "200px") + :stacking "bg" + :exclusive false + :monitor 0 + :focusable false + + (box :orientation "vertical" :space "10px" :valign "center" + + ;; === Workspace 1 === + (box :class "info-left" :orientation "vertical" :space "2px" :style "margin-bottom: 15px;" + + (label :text ws1 :class "ascii-core-status2")) + + ;; === Workspace 2 === + (box :class "info-left" :orientation "vertical" :space "2px" :style "margin-bottom: 15px;" + + (label :text ws2 :class "ascii-core-status2")) + + + ;; === Workspace 3 === + (box :class "info-left" :orientation "vertical" :space "2px" :style "margin-bottom: 15px;" + + (label :text ws3 :class "ascii-core-status2")) + + ;; === Workspace 4 === + (box :class "info-left" :orientation "vertical" :space "2px" :style "margin-bottom: 15px;" + + (label :text ws4 :class "ascii-core-status2")) + ) + ) + + + + ;;box :orientation "vertical" :space "10px" :valign "center" + ;; (label :text "Workspace 1" :class "label-primary") + ;;(label :text "Workspace 2" :class "label-primary") + ;;(label :text "" :class "label-primary") + ;; + + ;; (label :text "Workspace 3" :class "label-primary") + ;; (label :text "Workspace 4" :class "label-primary"))) + ''; + + home.file.".config/eww/windows/sys/four_boxes.yuck".text = '' + ;; ── four boxes ─────────────────────────────────────────────────── + ;; four boxes showing uptime, battery life, cpu temp, gpu temp + ;; Anchored top + (defwindow four_boxes + :visible show_eww + :anchor "right" + :monitor 0 + :geometry (geometry :x "4" :y "340px" :width "430px" :height "140") + :stacking "bg" + :exclusive false + (box :orientation "horizontal" :space-evenly true + ;; LEFT COLUMN + (box :orientation "vertical" :halign "center" :space "10px" + ;; REACTOR UPTIME + (box :class "module-frame" :orientation "vertical" :halign "center" + (label :text "[ REACTOR UPTIME ]" :class "stats-label") + (box :width "140px" + (label :text uptime_full :class "label-primary" :halign "center")) + ) + ;; CPU TEMP + (box :class "module-frame" :orientation "vertical" :halign "center" + (label :text "[ CPU TEMP ]" :class "stats-label") + (box :width "140px" + (label :text "${cpu_temp}" :class "label-primary" :halign "center")) + ) + ) + ;; RIGHT COLUMN + (box :orientation "vertical" :halign "center" :space "10px" + ;; MELTDOWN CLOCK + (box :class "module-frame" :orientation "vertical" :halign "center" + (label :text "[ MELTDOWN CLOCK ]" :class "stats-label") + (box :width "140px" + (label :text battery_time :class "label-primary" :halign "center")) + ) + ;; GPU TEMP + (box :class "module-frame" :orientation "vertical" :halign "center" + (label :text "[ GPU TEMP ]" :class "stats-label") + (box :width "140px" + (label :text "+${gpu_temp}°C" :class "label-primary" :halign "center")) + ) + ) + ) + ) + ''; + + home.file.".config/eww/windows/sys/orange_workspace.yuck".text = '' + ;; ── orange workspace ─────────────────────────────────────────────────── + ;; Vectors displaying reactor number in cyrilic text + ;; Anchored middle right + (defwindow orange_workspace + :visible show_eww + :anchor "top left" + :geometry (geometry :x "371px" :y "509px" :width "60px" :height "100px") + :stacking "bg" + :exclusive false + :focusable false + :monitor 0 + (box :orientation "vertical" :space "10px" + (box :class "info-right-box" :valign "end" :halign "start" (label :text "А1" :class "info-right-text" )) + (box :class "info-right-box" :valign "end" :halign "start" (label :text "Б2" :class "info-right-text" )) + (box :class "info-right-box" :valign "end" :halign "start" (label :text "В3" :class "info-right-text" )) + (box :class "info-right-box" :valign "end" :halign "start" (label :text "Г4" :class "info-right-text" )))) + ''; + + home.file.".config/eww/windows/sys/power_cooling_header_text.yuck".text = '' + ;; ── power cooling header ─────────────────────────────────────────────────── + ;; Text displaying header for cooling and power + ;; Anchored bottom + + (defwindow power-cooling_header_text + :visible show_eww + :anchor "top left" + :monitor 0 + :geometry (geometry :x "-52px" :y "700px" :width "100px" :height "8px") + :stacking "bg" + :exclusive false + :focusable false + + ;; Switch to horizontal to place boxes side by side + (box :orientation "horizontal" :halign "center" :space "12px" + ;; First box: POWER GRID + (label :text "[ POWER GRID ]" :class "stats-label3") + + ;; Second box: another label, e.g. MODE STATUS + (label :text "[ COOLING ]" :class "stats-label3" :halign "center") + ) + ) + ''; + + home.file.".config/eww/windows/sys/power_mode_text.yuck".text = '' + ;; ── power mode text ─────────────────────────────────────────────────── + ;; Text displaying power in cyrilic text + ;; Anchored bottom left + + (defwindow power_mode_text + :anchor "top left" + :monitor 0 + :geometry (geometry :x "-31px" :y "724px" :width "80px" :height "62px") + :stacking "bg" + :exclusive false + :focusable false + + (box :orientation "vertical" :halign "start" :space "4px" + ;; Power Draw + (box :orientation "horizontal" :halign "end" :space "4px" :style "margin-top:-10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "нагрузка: " :class "power-label") + (label :text power_draw :class "power-value" :halign "end" ) + ) + + ;; CPU Voltage + (box :orientation "horizontal" :halign "start" :space "4px" :style "margin-top: -10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "цпу: " :class "power-label") + (label :text cpu_voltage :class "power-value" :halign "end" ) + ) + + ;; GPU Voltage + (box :orientation "horizontal" :halign "start" :space "4px" :style "margin-top: -10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "гпу: " :class "power-label") + + (label :text gpu_voltage :class "power-value" :halign "end" ) + ) + + ;; GPU Voltage + (box :orientation "horizontal" :halign "start" :space "4px" :style "margin-top: -10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "питание: " :class "power-label") + (label :text dc_voltage :class "power-value" :halign "end" ) + ) + ) + ) + ''; + + home.file.".config/eww/windows/sys/right_fan-data.yuck".text = '' + ;; ── right fan data─────────────────────────────────────────────────── + ;; Text displaying cooling and fan RPM + ;; Anchored bottom right + (defwindow right_fan_data + :visible show_eww + :anchor "top left" + :monitor 0 + :geometry (geometry :x "171px" :y "724px" :width "200px" :height "64px") + :stacking "bg" + :exclusive false + :focusable false + (box :orientation "vertical" :halign "start" :space "4px" + ;; FAN + (box :orientation "horizontal" :halign "end" :space "4px" :style "margin-top:-10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "цпу вент: " :class "power-label3") + (label :text cpu_fan_rpm :class "power-value" :halign "end" ) + ) + ;; FAN + (box :orientation "horizontal" :halign "start" :space "4px" :style "margin-top: -10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "оперконтроль: " :class "power-label3") + (label :text gpu_fan_ascii :class "power-value" :halign "end" ) + ) + ;; fan + (box :orientation "horizontal" :halign "end" :space "4px" :style "margin-top:-10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "гпу вент: " :class "power-label3") + (label :text gpu_fan_rpm :class "power-value" :halign "end" ) + ) + ;;fan + (box :orientation "horizontal" :halign "start" :space "4px" :style "margin-top: -10px;" + (label :text "> " :class "power-label2" :halign "end" ) + (label :text "оперконтроль: " :class "power-label3") + (label :text gpu_fan_ascii :class "power-value" :halign "end" ) + ) + ) + ) + ''; + + home.file.".config/eww/windows/sys/workspace_window_text.yuck".text = '' + ;; ── workspace window text ─────────────────────────────────────────────────── + ;; Text and ascii showing active workspace number + ;; Anchored top middle + + (defwindow workspace_window_text + :anchor "center" + :monitor 0 + :geometry (geometry :x "9px" :y "300px" :width "420px" :height "220px") + :stacking "bg" + :exclusive false + :focusable false + + (box :orientation "vertical" :halign "center" + (label :text reactor_core_layout :class "ascii-core-status2") + ) + ) + ''; +} \ No newline at end of file diff --git a/home-manager/20_eww/02_scripts.nix b/home-manager/20_eww/02_scripts.nix new file mode 100644 index 0000000..7c905a4 --- /dev/null +++ b/home-manager/20_eww/02_scripts.nix @@ -0,0 +1,629 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/eww/scripts/ascii/ascii_core_layout.sh".file = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # ascii_core_layout.sh + # Gets the current Hyprland workspace ID and writes a small ASCII frame + # to /tmp/core_layout.txt. + # Example output (written to /tmp/core_layout.txt): + # ─┐ ┌─ + # [ 2 ] + # ─┘ └─ + # ───────────────────────────────────────────────────────────────────────────── + + ws=$(hyprctl activeworkspace -j | jq -r '.id') + + cat < /tmp/core_layout.txt + ─┐ ┌─ + [ $ws ] + ─┘ └─ + EOF + ''; + + home.file.".config/eww/scripts/audio/audio_cava_status.sh".file = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # Checks whether the ASCII visualizer output file (/tmp/visualizer.txt) + # is actively updating by comparing MD5 hashes between loops. + # Outputs simple text. + # Called by ascii_audio_status window + # ───────────────────────────────────────────────────────────────────────────── + + VIS_FILE="/tmp/visualizer.txt" + HASH_FILE="/tmp/.last_vis_hash" + + # ── Safety checks ─────────────────────────────────────────────────────────── + if [ ! -s "$VIS_FILE" ]; then + echo "[ CORE STATUS: ] Standby." + exit 0 + fi + + # ── Hash current frame ────────────────────────────────────────────────────── + if command -v md5sum >/dev/null 2>&1; then + CURRENT=$(md5sum "$VIS_FILE" | awk '{print $1}') + elif command -v md5 >/dev/null 2>&1; then # macOS/BSD fallback + CURRENT=$(md5 -q "$VIS_FILE") + else + echo "[ CORE STATUS: ] Unknown (no md5 tool found)" + exit 1 + fi + + LAST=$(cat "$HASH_FILE" 2>/dev/null || echo "") + + # ── Save current hash for next check ────────────────────────────────────── + echo "$CURRENT" > "$HASH_FILE" + + # ── Compare ─────────────────────────────────────────────────────────────── + if [ "$CURRENT" = "$LAST" ] && [ -n "$LAST" ]; then + echo "[ CORE STATUS: ] Inactive." + else + echo "[ CORE STATUS: ] Generating visuals." + fi + ''; + + home.file.".config/eww/scripts/audio/audio_visualizer.py".text = '' + #!/usr/bin/env python3 + # ───────────────────────────────────────────────────────────────────────────── + # °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh shhheersh + # vers. 1.0 + # ───────────────────────────────────────────────────────────────────────────── + # Reads /tmp/cava.raw and writes an ASCII‑art file that can be shown by eww, + # waybar, or any terminal widget. Can run as exec once in hyprland config. + # ───────────────────────────────────────────────────────────────────────────── + + import argparse + import os + import signal + import sys + import time + + import numpy as np + + # ── Default visual parameters ─────────────────────────────────────────────── + DEFAULT_WIDTH = 64 + DEFAULT_HEIGHT = 12 + DEFAULT_FPS = 30 + DEFAULT_DECAY = 0.92 # lower → longer trails + CHARS = [" ", ".", ":", "·", "•", "•"] # ascending intensity + + + def parse_frame(line: str, width: int) -> list[int]: + """Turn a semicolon‑separated line from CAVA into a list of ints.""" + try: + return [int(x) for x in line.strip().split(";") if x][:width] + except ValueError: + return [0] * width + + + def normalize(vals: list[int]) -> np.ndarray: + """Scale values to the range [0, 1].""" + arr = np.array(vals, dtype=float) + return (arr - arr.min()) / (arr.max() - arr.min() + 1e-5) + + + def get_char_index(val: float) -> int: + """Map a normalized value to the appropriate character index.""" + return min(int(val * (len(CHARS) - 1)), len(CHARS) - 1) + + + def build_frame(_, history: np.ndarray, height: int, width: int) -> list[str]: + """Create the ASCII rows from the decay buffer.""" + frame = [[" " for _ in range(width)] for _ in range(height)] + + for x in range(width): + for y in range(height): + strength = history[y, x] + idx = get_char_index(strength) + frame[height - y - 1][x] = CHARS[idx] + + # No baseline drawing – the “remove” request is satisfied + return ["".join(row) for row in frame] + + + def run( + cava_path: str, + out_path: str, + width: int = DEFAULT_WIDTH, + height: int = DEFAULT_HEIGHT, + fps: int = DEFAULT_FPS, + decay: float = DEFAULT_DECAY, + ) -> None: + """Main loop – read CAVA output, update the decay buffer, write ASCII.""" + os.makedirs(os.path.dirname(out_path), exist_ok=True) + + decay_buffer = np.zeros((height, width), dtype=float) + + while True: + try: + with open(cava_path, "r") as f: + # read one line at a time from the FIFO + line = f.readline() + if not line: + time.sleep(1.0 / fps) + continue + except Exception: + time.sleep(1.0 / fps) + continue + + # 1️⃣ Parse & normalise + values = parse_frame(line, width) + values = normalize(values) if values else np.zeros(width) + + # 2️⃣ Build a binary “bars” matrix for the current frame + new_frame = np.zeros((height, width), dtype=float) + for i, val in enumerate(values): + bar_h = int(val * height) + new_frame[:bar_h, i] = 1.0 + + # 3️⃣ Apply decay (trails) and blend with the new frame + decay_buffer = np.maximum(decay_buffer * decay, new_frame) + + # 4️⃣ Render ASCII and write out + ascii_lines = build_frame(values, decay_buffer, height, width) + with open(out_path, "w") as out: + out.write("\n".join(ascii_lines)) + + time.sleep(1.0 / fps) + + + + def _handle_sigint(signum, frame): + """Graceful exit on Ctrl‑C.""" + print("\n[+] CAVA ASCII visualizer stopped.") + sys.exit(0) + + + def main() -> None: + parser = argparse.ArgumentParser( + description="CAVA → ASCII visualizer (compatible with eww/widgets)", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--cava-path", default="/tmp/cava.raw", + help="Path to CAVA raw output file") + parser.add_argument("--out-path", default="/tmp/visualizer.txt", + help="File where ASCII art will be written") + parser.add_argument("--width", type=int, default=DEFAULT_WIDTH, + help="Number of columns (match CAVA `bars` setting)") + parser.add_argument("--height", type=int, default=DEFAULT_HEIGHT, + help="Number of rows in the ASCII canvas") + parser.add_argument("--fps", type=int, default=DEFAULT_FPS, + help="Refresh rate (frames per second)") + parser.add_argument("--decay", type=float, default=DEFAULT_DECAY, + help="Trail‑fade factor (0‑1, lower = slower fade)") + + args = parser.parse_args() + signal.signal(signal.SIGINT, _handle_sigint) + + print("[+] Starting CAVA ASCII visualizer …") + run( + cava_path=args.cava_path, + out_path=args.out_path, + width=args.width, + height=args.height, + fps=args.fps, + decay=args.decay, + ) + if __name__ == "__main__": + main() + ''; + + home.file.".config/eww/scripts/bar/bar_render.sh" = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # Converts a numeric percentage (0–100) into an ASCII block bar. + # Example: + # ./usage_render_bar.sh 73 + # ███████▓░░ + # ───────────────────────────────────────────────────────────────────────────── + + usage=$1 # pass percentage as the first argument + full="█" + half="▓" + empty="░" + + blocks=10 + filled=$(( usage * blocks / 100 )) + bar="" + + for ((i=0; i + # Example: ./upload_bar.sh 73 + # Output (top to bottom): + # │ + # │ + # ╽ + # █ + # █ + # ───────────────────────────────────────────────────────────────────────────── + + percent=$1 + lines=5 + + # Cap the percent between 0 and 100 + if [ "$percent" -gt 100 ]; then percent=100; fi + if [ "$percent" -lt 0 ]; then percent=0; fi + + # Calculate how many rows to fill + filled=$((percent * lines / 100)) + + # Always show at least one block if >0 + if (( percent > 0 && filled == 0 )); then + filled=1 + fi + + # Draw from top to bottom + for ((i=0; i/dev/null \ + | grep 'time=' \ + | awk -F'time=' '{print int($2)}' \ + || echo 0 + ''; + + home.file.".config/eww/scripts/net/ping_latency.sh".text = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # net_ping_latency.sh + # Visualizes ping latency as a vertical bar (5 lines). + # + # Usage: ./net_ping_latency.sh + # Example: ./net_ping_latency.sh 120 + # Output (top to bottom): + # │ + # ╽ + # █ + # █ + # █ + # ───────────────────────────────────────────────────────────────────────────── + + + ms=$1 + lines=5 + max_ms=200 # adjust scale (200ms = 100%) + + # Scale ping ms → percentage + percent=$(( ms * 100 / max_ms )) + if [ "$percent" -gt 100 ]; then percent=100; fi + if [ "$percent" -lt 0 ]; then percent=0; fi + + # Calculate filled rows + filled=$(( (percent * lines + 99) / 100 )) + if (( ms > 0 && filled == 0 )); then + filled=1 + fi + + for ((i=0; i + # Example: ./upload_bar.sh 73 + # Output (top to bottom): + # │ + # │ + # ╽ + # █ + # █ + # ───────────────────────────────────────────────────────────────────────────── + + percent=$1 + lines=5 + + # Cap 0–100 + if [ "$percent" -gt 100 ]; then percent=100; fi + if [ "$percent" -lt 0 ]; then percent=0; fi + + # Scale percentage into rows (round up) + filled=$(( (percent * lines + 99) / 100 )) + + # Always show at least one block if >0 + if (( percent > 0 && filled == 0 )); then + filled=1 + fi + + # Draw from top to bottom + for ((i=0; i/dev/null | grep -q "ESTABLISHED"; then + # VPN is up → full block bar + for ((i=0; i/dev/null | grep -q "ESTABLISHED"; then + country=$(curl -s ifconfig.co/country 2>/dev/null) + [[ -z "$country" ]] && country="НЕУСТАНОВЛЕНО" + echo "[УЗЕЛ] $country" + else + echo "[НЕТ СВЯЗИ]" + fi + ''; + + home.file.".config/eww/scripts/sys/sys_cpu_voltage.sh".text = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # sys_dc_voltage.sh + # Reads the VDDNB (SoC / NB voltage) from lm-sensors and prints it in mV. + # Requires: lm-sensors (run `sensors-detect` to configure chip readings). + # ───────────────────────────────────────────────────────────────────────────── + + sensors | awk '/vddnb:/ {printf "%s mV\n", $2}' || echo "N/A" + ''; + + home.file.".config/eww/scripts/sys/sys_dc_voltage.sh".text = '' + #!/bin/bash + # ───────────────────────────────────────────────────────────────────────────── + # sys_cpu_voltage.sh + # Reads CPU voltage (in0) from lm-sensors and prints it in volts. + # Requires: lm-sensors (and sensors-detect configured) + # ───────────────────────────────────────────────────────────────────────────── + + sensors | awk '/in0:/ {print $2 " V"}' || echo "N/A" + ''; + + home.file.".config/eww/scripts/sys/sys_fan_bar.sh".text = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # bar_render.sh + # Renders a simple horizontal bar graph from a percentage value. + # Example: ./bar_render.sh 75 → ███████░░░ + # ───────────────────────────────────────────────────────────────────────────── + + usage=$1 # percent or normalized value + full="█" + empty="░" + blocks=10 + filled=$(( usage * blocks / 100 )) + bar="" + + for ((i=0; i "$cache" + + # Get RPM + if [ "$fan" = "cpu" ]; then + rpm=$(sensors | grep -i 'cpu_fan' | awk '{print $2}') + elif [ "$fan" = "gpu" ]; then + rpm=$(sensors | grep -i 'gpu_fan' | awk '{print $2}') + else + rpm=0 + fi + [ -z "$rpm" ] && rpm=0 + + if [ "$rpm" -eq 0 ]; then + echo "|" + else + echo "${SPIN[$index]}" + fi + ''; + + home.file.".config/eww/scripts/sys/sys_gpu_voltage.sh".text = '' + #!/bin/bash + # ───────────────────────────────────────────────────────────────────────────── + # Reads NVIDIA GPU voltage using nvidia-smi and prints it in millivolts. + # ───────────────────────────────────────────────────────────────────────────── + sensors | awk '/vddgfx/ {print $2 " mV"}' || echo "N/A" + ''; + + home.file.".config/eww/scripts/sys/sys_workspace.sh".text = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # Prints the status of workspaces 1–4 in Hyprland, marking the active one. + # Output format: "wsN= [ ACTIVE ]" or "wsN= [INACTIVE]" + # ───────────────────────────────────────────────────────────────────────────── + + # Get active workspace ID (requires jq + hyprctl) + CURRENT=$(hyprctl activeworkspace -j 2>/dev/null | jq -r '.id') + + # Fallback if query fails + if [[ -z "$CURRENT" || "$CURRENT" == "null" ]]; then + echo "[!] Could not determine active workspace." + exit 1 + fi + + for i in {1..4}; do + if [[ "$i" -eq "$CURRENT" ]]; then + echo "ws${i}= [ ACTIVE ]" + else + echo "ws${i}= [INACTIVE]" + fi + done + ''; + +} \ No newline at end of file diff --git a/home-manager/20_eww/default.nix b/home-manager/20_eww/default.nix new file mode 100644 index 0000000..7574459 --- /dev/null +++ b/home-manager/20_eww/default.nix @@ -0,0 +1,546 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./01_windows.nix + ./02_scripts.nix + ]; + + home.file.".config/eww/eww.yuck".text = '' + ;; ─────────────────────────────────────────────────────────────────────────── + ;; °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh + ;; shhheersh + ;; EWW HUD config, some stuff duct taped, some stuff glued + ;; vers. 1.0-nix + ;; ─────────────────────────────────────────────────────────────────────────── + ;; === Windows ─────────────────────────────────────────────────────────────── + (include "./windows/ascii/visualizer_window.yuck") + (include "windows/ascii/audio_status.yuck") + (include "windows/sys/four_boxes.yuck") + (include "windows/sys/workspace_window_text.yuck") + (include "windows/bar/cpu_ram_storage_bars.yuck") + (include "windows/sys/active_workspace.yuck") + (include "windows/sys/orange_workspace.yuck") + (include "windows/sys/power_cooling_header_text.yuck") + (include "windows/sys/power_mode_text.yuck") + (include "windows/sys/right_fan_data.yuck") + (include "windows/net/ascii_decor_frame.yuck") + (include "windows/net/net_bars.yuck") + (include "windows/net/right_internet_text.yuck") + (include "windows/misc/welcome_text.yuck") + ;; === Variables ───────────────────────────────────────────────────────────── + (defvar max_fan_rpm "5000") + (defvar ascii_decor1 " + - - + -- -- + - - + -- -- + - - + -- -- + - - + -- -- + - - + -- -- + - - + ") + ;; === Workspace Status ────────────────────────────────────────────────────── + (defpoll ws1 :interval "1s" "bash ~/.config/eww/scripts/sys/sys_workspace.sh | grep ws1= | cut -d= -f2 || echo 'null'") + (defpoll ws2 :interval "1s" "bash ~/.config/eww/scripts/sys/sys_workspace.sh | grep ws2= | cut -d= -f2 || echo 'null'") + (defpoll ws3 :interval "1s" "bash ~/.config/eww/scripts/sys/sys_workspace.sh | grep ws3= | cut -d= -f2 || echo 'null'") + (defpoll ws4 :interval "1s" "bash ~/.config/eww/scripts/sys/sys_workspace.sh | grep ws4= | cut -d= -f2 || echo 'null'") + (defpoll current_workspace :interval "0.5s" "hyprctl activeworkspace -j | jq -r '.id' || echo 'null'") + ;; === Power & Voltage ─────────────────────────────────────────────────────── + (defpoll gpu_voltage :interval "5s" "bash ~/.config/eww/scripts/sys/sys_gpu_voltage.sh || echo 'null'") + (defpoll cpu_voltage :interval "5s" "bash ~/.config/eww/scripts/sys/sys_cpu_voltage.sh || echo 'null'") + (defpoll dc_voltage :interval "10s" "bash ~/.config/eww/scripts/sys/sys_dc_voltage.sh || echo 'null'") + (defpoll power_mode :interval "10s" "bash ~/.config/eww/scripts/sys/sys_power_mode.sh || echo 'null'") + (defpoll power_draw :interval "5s" "sensors | grep -m 1 'power1:' | awk '{print $2 \" \"$3}' || echo 'N/A'") + ;; === CPU & GPU Stats ─────────────────────────────────────────────────────── + (defpoll cpu :interval "10m" "lscpu | grep 'Model name' | cut -d ':' -f2 | xargs || echo 'null'") + (defpoll gpu :interval "10m" "lspci | grep -i vga | cut -d ':' -f3 || echo 'null'") + (defpoll cpu_usage :interval "2s" "top -bn1 | grep 'Cpu(s)' | awk '{print int($2 + $4)}' || echo 'null'") + (defpoll cpu_bar :interval "2s" "bash ~/.config/eww/scripts/bar/bar_render.sh $(top -bn1 | grep 'Cpu(s)' | awk '{print int($2 + $4)}') || echo 'null'") + (defpoll gpu_usage :interval "2s" "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits || echo 'N/A'") + (defpoll cpu_temp :interval "5s" "sensors | grep 'Tctl' | awk '{print $2}' || echo 'N/A'") + (defpoll gpu_temp :interval "5s" "nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits || echo 'N/A'") + ;; Fan RPM values + (defpoll cpu_fan_rpm :interval "5s" "sensors | grep -i 'cpu_fan' | awk '{print $2 \" RPM\"}' || echo 'null'") + (defpoll gpu_fan_rpm :interval "5s" "sensors | grep -i 'gpu_fan' | awk '{print $2 \" RPM\"}' || echo 'null'") + ;; Fan ASCII spinners + (defpoll cpu_fan_ascii :interval "0.2s" "bash ~/.config/eww/scripts/sys/sys_fan_spin.sh cpu || echo 'null'") + (defpoll gpu_fan_ascii :interval "0.2s" "bash ~/.config/eww/scripts/sys/sys_fan_spin.sh gpu || echo 'null'") + ;; === Memory & Storage ────────────────────────────────────────────────────── + (defpoll ram_info :interval "5s" "free -h | awk '/Mem:/ {print $3\" / \"$2}' || echo 'null'") + (defpoll ram_percent :interval "5s" "free | awk '/Mem:/ {printf \"%d\", $3/$2 * 100}' || echo 'null'") + (defpoll ram_bar :interval "5s" "bash ~/.config/eww/scripts/bar/bar_render.sh $(free | awk '/Mem:/ {printf(\"%.0f\", $3/$2 * 100)}') || echo 'null'") + (defpoll ram :interval "5s" "free -h | awk '/Mem:/ {print $3 \"/\" $2}' || echo 'null'") + (defpoll disk :interval "10s" "df -h / | awk 'NR==2 {print $3 \"/\" $2}' || echo 'null'") + (defpoll storage_percent :interval "5s" "df / | awk 'NR==2 {print int($3*100/$2)}' || echo 'null'") + (defpoll storage_bar :interval "5s" "bash ~/.config/eww/scripts/bar/bar_render.sh $(df / | awk 'NR==2 {print int($3*100/$2)}') || echo 'null'") + ;; === Networking ──────────────────────────────────────────────────────────── + (defpoll upload_speed :interval "3s" "bash ~/.config/eww/scripts/net/net_upload.sh || echo 'null'") + (defpoll upload_bar :interval "3s" "bash ~/.config/eww/scripts/net/net_upload.sh | xargs bash ~/.config/eww/scripts/net/net_upload_bar.sh || echo 'null'") + (defpoll download_speed :interval "3s" "bash ~/.config/eww/scripts/net/net_download.sh || echo 'null'") + (defpoll download_bar :interval "3s" "bash ~/.config/eww/scripts/net/net_download.sh | xargs bash ~/.config/eww/scripts/net/net_download_bar.sh || echo 'null'") + (defpoll ping_ms :interval "5s" "bash ~/.config/eww/scripts/net/net_ping.sh || echo 'null'") + (defpoll ping_bar :interval "5s" "bash ~/.config/eww/scripts/net/net_ping.sh | xargs bash ~/.config/eww/scripts/net/net_ping_latency.sh || echo 'null'") + (defpoll vpn_status_text :interval "5s" "bash ~/.config/eww/scripts/net/net_vpn_status.sh || echo 'null'") + (defpoll vpn_bar :interval "5s" "bash ~/.config/eww/scripts/net/net_vpn.sh | xargs bash ~/.config/eww/scripts/net/net_vpn_bar.sh || echo 'null'") + ;; === Time & Date ─────────────────────────────────────────────────────────── + (defpoll welcome_date :interval "30s" "date '+%A, %d %B %Y' || echo 'null'") + (defpoll weekday_str :interval "10s" "date +%A || echo 'null'") + (defpoll datetime_str :interval "10s" "date '+%H:%M • %d %B %Y' || echo 'null'") + (defpoll weather_forecast :interval "30m" "curl -s 'wttr.in?format=%C+%t' || echo 'N/A'") + ;; === System Info ─────────────────────────────────────────────────────────── + (defpoll os :interval "10m" "uname -o || echo 'null'") + (defpoll desktop :interval "10m" "echo $XDG_CURRENT_DESKTOP || echo 'null'") + (defpoll wm :interval "10m" "echo $XDG_SESSION_TYPE || echo 'null'") + (defpoll shell :interval "10m" "basename $SHELL || echo 'null'") + (defpoll USER :interval "10m" "whoami || echo 'null'") + (defpoll install-age :interval "1h" "uptime -s | xargs -I{} date -d {} +%s | xargs -I{} echo $(( ($(date +%s) - {}) / 86400 ))' days' || echo 'null'") + (defpoll since-boot :interval "5s" "uptime -s || echo 'null'") + (defpoll uptime_full :interval "0.5s" "awk '{sec=int($1); ms=substr(sprintf(\"%.3f\", $1 - sec), 3); printf \"%02d:%02d:%02d.%s\\n\", sec/3600, (sec%3600)/60, sec%60, ms}' /proc/uptime || echo 'null'") + (defpoll centered-name :interval "10m" "echo $USER@$(hostname) || echo 'null'") + (defpoll battery_time :interval "10s" + "upower -i $(upower -e | grep BAT) 2>/dev/null | awk ' + /state:/ { state = $2 } + /time to empty/ { print $4 \" \"$5 } + /time to full/ { full = $4 \" \"$5 } + END { + if (state == \"discharging\") exit 0; + else if (state == \"charging\") print \"Re-establishing\"; + else print \"N/A\" + }' || echo 'null'") + ;; === ASCII Widgets & Feeds === + (defpoll visualizer_gen :interval "0.2s" "cat /tmp/visualizer.txt || echo 'null'") + (defpoll visualizer_content :interval "0.2s" "cat /tmp/visualizer.txt || echo '----------------------------standby--------------------------'") + (defpoll reactor_gen :interval "0.5s" "cat /tmp/reactor_frame.txt || echo 'null'") + (defpoll reactor_ascii :interval "0.5s" "cat /tmp/reactor_frame.txt || echo 'standby'") + (defpoll reactor_core_layout :interval "1s" "bash ~/.config/eww/scripts/ascii/ascii_core_layout.sh && cat /tmp/core_layout.txt || echo 'standby'") + (defpoll live_log_gen :interval "5s" "bash ~/.config/eww/scripts/ascii/ascii_live_log.sh || echo 'null'") + (defpoll live_text :interval "5s" "cat /tmp/live_text.txt || echo '--------------…'") + (defpoll ascii_audio_status :interval "2s" "bash ~/.config/eww/scripts/audio/audio_cava_status.sh || echo 'null'") + ;; === Widgets ──────────────────────────────────────────────────────────────────── + (defwidget audio-visualizer [] + (box :class "outer-frame" + (box :class "inner-frame" + (box :class "visualizer-container" + (label + :text visualizer_content + :markup true + :class "visualizer-text"))))) + ''; + + home.file.".config/eww/eww.scss".text = '' + // ───────────────────────────────────────────────────────────────────────── + // °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh + // shhheersh + // EWW HUD style + // vers. 1.0-nix + // ───────────────────────────────────────────────────────────────────────── + + // ── Visualizer ─────────────────────────────────────────────────────────── + .visualizer-container { + background-color: transparent; + } + + .visualizer { + color: #08c0d0; // Nord Cyan + font-family: monospace; + background-color: transparent; + font-size: 9px; + } + + .visualizer-container { + border-radius: 2px; + background: linear-gradient(to top, rgba(25,25,25,0.5), rgba(25,25,25,0)); + padding: 4px; + } + + .visualizer-text { + font-family: monospace; + font-size: 8px; + color: #56b6c2; + } + + // ── Windows ────────────────────────────────────────────────────────────── + window { + background-color: transparent; + box-shadow: none; + border: none; + } + + .window { + background-color: transparent; + } + + // ── Pixel ASCII ────────────────────────────────────────────────────────── + .pixel-container { + background-color: transparent; + padding: 2px; + } + + .pixel-ascii { + font-family: monospace; + font-size: 6px; + color: #e5c07b; + background-color: transparent; + } + + // ── Color Classes ──────────────────────────────────────────────────────── + .red_1 { color: #ff6c6b; } + .green_1 { color: #9cdef2; } + .blue_1 { color: #61afef; } + .yellow_1 { color: #9cdef2; } + .red_2 { color: #ff6c6b; } + .green_2 { color: #98c379; } + .blue_2 { color: #61afef; } + .yellow_2 { color: #fab387; } + + // ── Frames ─────────────────────────────────────────────────────────────── + .outer-frame { + border: 2px solid #61afef; + border-radius: 3px; + padding: 4px; + background-color: transparent; + min-width: 350px; + } + + .inner-frame { + border: 2px solid #56b6c2; + border-radius: 1px; + padding: 6px; + //background-color: rgba(25, 25, 25, 0.4); + } + + .module-frame { + border: 2px solid #61afef; + border-radius: 2px; + margin-bottom: 5px; + margin-left: 5px; + margin-right: 5px; + margin-top: 5px; + min-height: 10px; + min-width: 140px; + } + + .module-frame { + border: 2px solid #61afef; + border-radius: 2px; + margin: 5px; + padding: 1px; + min-height: 10px; + min-width: 140px; + background-image: linear-gradient(to left, rgba(0,0,0,0.4), rgba(0,0,0,0)); + transition: all 0.2s ease-in-out; + } + + .module-frame2 { + border: 2px solid #61afef; + border-radius: 2px; + margin: 5px; + padding: 1px; + min-height: 10px; + min-width: 10px; + background-image: linear-gradient(to left, rgba(0,0,0,0.4), rgba(0,0,0,0)); + transition: all 0.2s ease-in-out; + } + + .module-frame:hover { + border-color: #88c0d0; + background-image: linear-gradient(to left, rgba(136, 192, 208, 0.1), rgba(0, 0, 0, 0)); + box-shadow: 0 0 8px rgba(136, 192, 208, 0.4); + } + + + // ── Labels & Stats ─────────────────────────────────────────────────────── + .label-primary { + font-size: 14px; + font-weight: bold; + color: #9cdef2; + } + + .label-primary2 { + font-size: 9px; + font-weight: bold; + color: #9cdef2; + border: 2px solid #61afef; + border-radius: 2px; + margin-bottom: 50px; + margin-left: 27px; + margin-right: 4px; + margin-top: 5px; + padding: 1px; + min-height: 10px; + min-width: 50px; + border: none; + } + + .label-secondary { + font-size: 8px; + color: #888; + } + + .internet-clean-box { + background: transparent; + border: none; + box-shadow: none; + padding: 0; + } + + .stats-label { + font-size: 10px; + font-weight: bold; + color: #56b6c2; + letter-spacing: 1px; + } + + .stats-label2 { + font-size: 10px; + font-weight: bold; + color: #56b6c2; + letter-spacing: 1px; + } + + .stats-label3 { + font-size: 10px; + margin-left: 87px; + font-weight: bold; + color: #56b6c2; + letter-spacing: 1px; + } + + .stats-box { + border-radius: 12px; + min-height: 10px; + min-width: 100px; + } + + // ── RAM & Bars ─────────────────────────────────────────────────────────── + .ascii-bar-frame { + border: 1px solid #61afef; + border-radius: 4px; + margin: 4px; + padding: 4px; + min-width: 220px; + font-size: 10px; + } + + .ram-bar { + font-size: 20px; + font-family: monospace; + color: #9cdef2; + letter-spacing: 4px; + padding: 2px 2px; + } + + .ram-bar2 { + color: #9cdef2; + letter-spacing: 1.5px; + padding: 1px 1px; + font-size: 10px; + } + + .ram-bar4 { + color: #9cdef2; + letter-spacing: 1.5px; + padding: 1px 1px; + font-size: 10px; + } + + // ── Date & Time ────────────────────────────────────────────────────────── + .day-time-container { + padding: 1em; + border-radius: 12px; + border: 2px solid #88c0d0; + } + + .weekday-container { + border: 2px solid #3b4252; + border-radius: 12px; + padding: 16px; + min-width: 200px; + } + + .weekday-text { + font-size: 34px; + font-weight: bold; + color: #fab387; + } + + .time-text { + font-size: 18px; + color: #a3be8c; + margin-top: 6px; + } + + // ── Welcome ────────────────────────────────────────────────────────────── + .welcome-box { + background-color: rgba(25,25,25,0.6); + border: 2px solid #88c0d0; + border-radius: 8px; + padding: 12px 20px; + margin-top: 10px; + } + + .welcome-text { font-size: 18px; font-weight: bold; color: #9cdef2; } + .welcome-sub { font-size: 12px; color: #eceff4; margin-top: 4px; } + .welcome-label { color: #56b6c2; font-size: 12px; font-weight: bold; } + .welcome-value { color: #9cdef2; font-size: 12px; font-weight: bold; letter-spacing: 1px; } + + // ── Shades & Animations ────────────────────────────────────────────────── + .shade2 { background: linear-gradient(to right, black 3px, rgba(19,19,19,0) 15%); } + .shade { background-color: #9cdef2; } + $window_visible: true; + + .animated { + transition: opacity 0.4s ease, transform 0.4s ease; + opacity: 1; + } + + @if not $window_visible { + .animated { + opacity: 0; + pointer-events: none; + } + } + + // ── Fans ───────────────────────────────────────────────────────────────── + .fan-ascii { + font-family: "JetBrainsMono Nerd Font", monospace; + font-size: 15px; + color: #88c0d0; + letter-spacing: 3px; + transition: color 0.3s ease, transform 0.3s ease; + } + + .fan-frame, .fan-frame2 { + padding: 0; + margin: 2px; + font-size: 10px; + min-height: 31.2px; + margin-bottom: 15px; + margin-top: 15px; + margin-left: 5px; + } + + .fan-rpm { font-size: 10px; color: #9cdef2; } + .fan-rpm2 { font-size: 11px; min-width: 30px; color: #9cdef2; padding: 0; } + + // ── Workspaces ─────────────────────────────────────────────────────────── + .workspace-ascii { + font-family: monospace; + font-size: 14px; + color: #61afef; + } + + .workspace-ascii-highlight { + font-family: monospace; + font-size: 20px; + font-weight: bold; + color: #9cdef2; + } + + // ── Terminal & Reactor ─────────────────────────────────────────────────── + .terminal-feed { + font-family: monospace; + font-size: 12px; + color: #08c0d0; + padding-left: 8px; + } + + .reactor-ascii { + font-family: monospace; + font-size: 4px; + color: #9cdef2; + font-weight: bold; + min-height: 140px; + min-width: 280px; + } + + .ascii-core-status { + font-family: monospace; + font-size: 10px; + border-radius: 0px; + color: #9cdef2; + } + + .ascii-core-status2 { + font-family: monospace; + font-size: 14px; + padding: 4px; + border-radius: 0px; + color: #9cdef2; + } + + .log-line { + font-family: monospace; + font-size: 10px; + color: #9cdef2; + padding: 4px; + } + + .ascii-decor1 { + font-family: monospace; + font-size: 12px; + color: #9cdef2; + letter-spacing: 1px; + padding: 6px; + margin: 4px; + font-size: 10px; + } + + // ── Info Panels ────────────────────────────────────────────────────────── + .data-row { + background-color: transparent; + padding: 2px; + } + + .info-left { + background-color: #1e1e1e; + min-width: 1px; + border: 2px solid #61afef; + border-radius: 1px; + } + + .info-left2 { min-height: 1px; } + .info-right-box { + background-color:#fab387; + min-height: 31.2px; + margin-bottom: 15px; + min-width: 26px; + } + + .info-right-text { + font-size: 13px; + font-weight: bold; + color: #1e1e1e; + } + + // ── Power ──────────────────────────────────────────────────────────────── + .power-label { font-size: 12px; color: #fab387; font-family: monospace; } + .power-label2 { font-size: 12px; color: #c4ecf0; font-family: monospace; } + .power-label3 { font-size: 12px; color: #61afef; font-family: monospace; } + .power-value { font-size: 10px; color: #9cdef2; font-family: monospace; margin: 5px; } + .power-header { + font-size: 10px; + font-weight: bold; + color:#56b6c2; + padding: 4px 8px; + min-width: 150px; + } + + .power-header-alt { + font-size: 6px; + font-weight: bold; + color: #61afef; + padding: 4px 8px; + letter-spacing: 1px; + min-width: 15px; + } + ''; + + home.file.".config/eww/eww-state.yml".text = '' + window_visible: true + ''; +} \ No newline at end of file diff --git a/home-manager/20_rofi/01_config.nix b/home-manager/20_rofi/01_config.nix new file mode 100644 index 0000000..1c73405 --- /dev/null +++ b/home-manager/20_rofi/01_config.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +{ + + home.file.".config/rofi/config.rasi".text = '' + /* ── Rofi Config ────────────────────────────── + Location: ~/.config/rofi/config.rasi + Description: Basic configuration + theme import + ─────────────────────────────────────────── */ + + configuration { + modi: "drun,run"; // Available modes + show-icons: true; // Show app icons + font: "JetBrainsMono Nerd Font 12"; // Global font + } + + /* Import active theme */ + @theme "~/.config/rofi/theme.rasi" + ''; +} \ No newline at end of file diff --git a/home-manager/20_rofi/02_theme.nix b/home-manager/20_rofi/02_theme.nix new file mode 100644 index 0000000..f1e8147 --- /dev/null +++ b/home-manager/20_rofi/02_theme.nix @@ -0,0 +1,110 @@ +{ config, pkgs, ... }: + +{ + + home.file.".config/rofi/theme.rasi".text = '' + /* ── Rofi Theme ────────────────────────────── + °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh + shhheersh + Vers 1.0-nix + Description: Custom styling for Rofi launcher + ─────────────────────────────────────────── */ + + /* Global defaults */ + * { + font: "JetBrainsMono Nerd Font 11"; + blur: true; + padding: 10px; + background-color: transparent; + border-radius: 0px; // remove default rounding globally + } + + /* ── Window ──────────────────────────────── */ + window { + width: 750px; + height: 625px; + location: center; + blur: true; + border: 2px; + border-radius: 3px; + border-color: #61afef; + background-color: transparent; // let Hyprland handle opacity + padding: 0px; + margin: 30px 50px; + } + + /* ── Layout ──────────────────────────────── */ + mainbox { + orientation: horizontal; + children: [ "borderbox" ]; + spacing: 0px; + padding: 0px; + } + + borderbox { + orientation: horizontal; + children: [ "imagebox", "contentbox" ]; + padding: 0px; + spacing: 0px; + border-radius: 3px; + } + + contentbox { + orientation: vertical; + children: [ "entry", "listview" ]; + spacing: 0px; + padding: 0px; + expand: true; + } + + /* ── Imagebox ────────────────────────────── */ + imagebox { + background-image: url("~/.config/rofi/image.png"); + background-repeat: false; + size: 300px 625px; + } + + /* ── Elements ────────────────────────────── */ + element { + border-radius: 0px; + } + + element-text, element-icon { + padding: 6px 8px; + spacing: 2px; + text-color: #fab387; + } + + element selected { + background-color: #191919; + text-color: #e5c07b; + border-radius: 3px; + } + + /* ── Input & Prompt ──────────────────────── */ + prompt { + enabled: false; + background-color: transparent; + text-color: #61afef; + padding: 5px 10px; + } + + entry { + padding: 8px; + expand: false; + font: "JetBrainsMono Nerd Font 12"; + text-color: #fab387; + border-radius: 0px 3px 0px 0px; + background-color: #292e36; // input field + } + + /* ── Listview ────────────────────────────── */ + listview { + lines: 1; + background-color: rgba(46, 52, 64, 0.8); // solid background inside blur + border-radius: 0px 0px 3px 0px; + padding: 5px; + } + ''; + +} \ No newline at end of file diff --git a/home-manager/20_rofi/default.nix b/home-manager/20_rofi/default.nix new file mode 100644 index 0000000..5db8178 --- /dev/null +++ b/home-manager/20_rofi/default.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./01_config.nix + ./02_theme.nix + ]; +} \ No newline at end of file diff --git a/home-manager/20_waybar/01_config.nix b/home-manager/20_waybar/01_config.nix new file mode 100644 index 0000000..e53c1c5 --- /dev/null +++ b/home-manager/20_waybar/01_config.nix @@ -0,0 +1,215 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/waybar/config".text = '' + // ───────────────────────────────────────────────────────────────────────── + // °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh shhheersh + // Waybar config + // vers. 1.0.0-nix + // ───────────────────────────────────────────────────────────────────────── + + { + "layer": "top", + "position": "top", + "margin-top": 12, + "margin-bottom": -8, + "width": 2010, + "height": 34, + + // ── Modules Layout ───────────────────────────────────────────────────── + "modules-left": [ + "clock", + "custom/power", + "network", + "bluetooth", + "custom/microphone", + "custom/vpn" + ], + + "modules-center": [ + "custom/workspace-1", + "custom/workspace-2", + "custom/asus-profile", + "custom/workspace-3", + "custom/workspace-4" + ], + + "modules-right": [ + "custom/battery", + "custom/volume", + "custom/brightness" + ], + + // ── Clock ────────────────────────────────────────────────────────────── + "clock": { + "tooltip-format": "{calendar}", + "format-alt": " {:%a, %d %b %Y}", + "format": "[  {:%I:%M %p} ]" + }, + + // ── Network ──────────────────────────────────────────────────────────── + "network": { + "format-wifi": "{icon}", + "format-icons": ["[ 󰤯 ]", "[ 󰤟 ]", "[ 󰤢 ]", "[ 󰤥 ]", "[ 󰤨 ]"], + "format-ethernet": "󰀂", + "format-alt": "󱛇", + "format-disconnected": "󰖪", + "tooltip-format-wifi": "{icon} {essid}\n⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}", + "tooltip-format-ethernet": "󰀂 {ifname}\n⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}", + "tooltip-format-disconnected": "Disconnected", + "on-click": "nm-connection-editor", + "interval": 5, + "nospacing": 1 + }, + + // ── Keyboard ─────────────────────────────────────────────────────────── + "keyboard-state": { + "numlock": true, + "capslock": true, + "format": " {layout}" + }, + + // ── Bluetooth ────────────────────────────────────────────────────────── + "bluetooth": { + "format": "{icon}", + "format-icons": { + "enabled": "[  ]", + "disabled": "[ 󰂲 ]" + }, + "on-click": "~/.config/waybar/scripts/bluetooth-toggle.sh", + "tooltip-format": "Bluetooth is {status}", + "interval": 5 + }, + + + // // ── Asus Profile ─────────────────────────────────────────────────────── + // "custom/asus-profile": { + // "exec": "~/.config/waybar/scripts/asus-profile.sh", + // "interval": 3, + // "format": "{}", + // "tooltip": true, + // "tooltip-format": "Toggle ASUS profile", + // "on-click": "/home/pewds/.config/cycle-profile.sh" + // }, + + // ── Battery (scripted + built-in) ────────────────────────────────────── + "custom/battery": { + "exec": "~/.config/waybar/scripts/battery.sh", + "return-type": "json", + "interval": 10, + "on-click": "xfce4-power-manager-settings" + }, + + + "battery": { + "format": "{icon} {capacity}%", + "format-icons": { + "charging": [ + "󰢜","󰂆","󰂇","󰂈","󰢝","󰂉","󰢞","󰂊","󰂋","󰂅" + ], + "default": [ + "󰁺","󰁻","󰁼","󰁽","󰁾","󰁿","󰂀","󰂁","󰂂","󰁹" + ] + }, + "format-full": "Charged ", + "interval": 5, + "states": { + "warning": 20, + "critical": 10 + }, + "tooltip": true + }, + + // ── Microphone ───────────────────────────────────────────────────────── + "custom/microphone": { + "exec": "~/.config/waybar/scripts/mic.sh", + "interval": 1, + "tooltip": true, + "tooltip-format": "Mic Toggle", + "on-click": "pactl set-source-mute @DEFAULT_SOURCE@ toggle" + }, + + // ── Brightness ───────────────────────────────────────────────────────── + "custom/brightness": { + "exec": "~/.config/waybar/scripts/brightness.sh", + "return-type": "json", + "interval": 2, + "on-click": "~/.config/waybar/scripts/brightness-toggle.sh", + "on-scroll-up": "brightnessctl set +5%", + "on-scroll-down": "brightnessctl set 5%-" + }, + + "backlight": { + "format": "󰛨 {percent}%", + "format-icons": ["󰃞","󰃟","󰃠","󰃝","󰃜","󰃛"], + "class": "flicker-bar", + "on-click": "~/.config/waybar/scripts/brightness-slider.sh" + }, + + // ── Workspaces (custom scripts) ──────────────────────────────────────── + "custom/workspace-1": { + "exec": "~/.config/waybar/scripts/workspaces/workspace-1.sh", + "interval": 1, + "on-click": "hyprctl dispatch workspace 1", + "tooltip": "Switch to workspace 1" + }, + + "custom/workspace-2": { + "exec": "~/.config/waybar/scripts/workspaces/workspace-2.sh", + "interval": 1, + "on-click": "hyprctl dispatch workspace 2", + "tooltip": "Switch to workspace 2" + }, + + "custom/workspace-3": { + "exec": "~/.config/waybar/scripts/workspaces/workspace-3.sh", + "interval": 1, + "on-click": "hyprctl dispatch workspace 3", + "tooltip": "Switch to workspace 3" + }, + + "custom/workspace-4": { + "exec": "~/.config/waybar/scripts/workspaces/workspace-4.sh", + "interval": 1, + "on-click": "hyprctl dispatch workspace 4", + "tooltip": "Switch to workspace 4" + }, + + // ── Volume ───────────────────────────────────────────────────────────── + "custom/volume": { + "exec": "~/.config/waybar/scripts/volume.sh", + "return-type": "json", + "interval": 1, + "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", + "on-scroll-up": "wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+", + "on-scroll-down": "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" + }, + + + // ── VPN ──────────────────────────────────────────────────────────────── + "custom/vpn": { + "exec": "~/.config/waybar/scripts/nordvpn-status.sh", + "interval": 5, + "on-click": "~/.config/waybar/scripts/nordvpn-toggle.sh", + "format": "{}", + "markup": "pango", + "tooltip": true, + "tooltip-format": "VPN Status / Toggle" + }, + + // ── Power ────────────────────────────────────────────────────────────── + "custom/power": { + "format": "[ 󰤆 ]", + "tooltip": true, + "tooltip-format": "Power Menu", + "on-click": "~/.config/waybar/scripts/powermenu.sh" + }, + + // ── Spacer ───────────────────────────────────────────────────────────── + "custom/squares": { + "format": " ", + "tooltip": false + } + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_waybar/02_style.nix b/home-manager/20_waybar/02_style.nix new file mode 100644 index 0000000..a175297 --- /dev/null +++ b/home-manager/20_waybar/02_style.nix @@ -0,0 +1,192 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/waybar/style.css".text = '' + /* + ────────────────────────────────────────────────────────────────────────── + °˖* ૮( • ᴗ 。)っ🍸 pewdiepie/archdaemon/dionysh shhheersh + Waybar CSS styling + vers. 1.0-nix + ────────────────────────────────────────────────────────────────────────── + */ + + /* === Base Waybar Styling =============================================== */ + waybar * { + border: 4px; + border-radius: 4px; + min-height: 0; + font-family: "JetBrainsMono Nerd Font"; + font-size: 14px; + } + + #waybar { + background-color: #3b4252; + border-radius: 2px; + opacity: 0.95; + } + + window#waybar { + background: #282c34; + transition-property: background-color; + transition-duration: 0.5s; + color: #9cdef2; + border: 3px solid #61afef; + border-left: 3px solid #56b6c2; + border-right: 3px solid #56b6c2; + } + + /* === Workspaces ======================================================== */ + #workspaces { + background-color: transparent; + padding-left: 40px; + } + + #workspaces button { + all: initial; + min-width: 0; + box-shadow: inherit; + padding: 6px 6px; + margin: 6px 3px; + border-radius: 4px; + background-color: #2e3440; + color: #56b6c2; + } + + #workspaces button.active { + color: #fab387; + background-color: #56b6c2; + } + + #workspaces button:hover { + color: #2e3440; + background-color: #56b6c2; + } + + /* === Default Module Container Styling ================================== */ + #custom-microphone, #bluetooth, #custom-bluetooth, #custom-brightness, + #custom-volume, #custom-battery, #custom-power, #custom-asus-profile, + #network, #battery, #pulseaudio, #backlight, #custom-vpn, #clock, + #tray { + padding: 6px 12px; + margin: 6px 6px; + background-color: #292d35; + border: 2px solid #61afef; + border-radius: 2px; + } + + /* === Audio ============================================================= */ + #pulseaudio.muted { + background-color: #f38ba8; + color: #1e1e2e; + } + + /* === Bluetooth ========================================================= */ + #bluetooth.disabled { + color: #fab387; + } + + #custom-bluetooth { + color: #56b6c2; + transition: color 0.2s ease-in-out; + } + + /* === Network =========================================================== */ + #network.disconnected { + background-color: #e06c75; + color: #1e1e2e; + } + + /* === Clock ============================================================= */ + #clock { + font-weight: bold; + font-size: 12px; + color: #fab387; + } + + /* === Asus Profile ====================================================== */ + #custom-asus-profile { + font-weight: bold; + font-size: 12px; + color: #e5c07b; + } + + /* === VPN =============================================================== */ + #custom-vpn { + font-weight: bold; + font-size: 12px; + } + + /* === Battery =========================================================== */ + #custom-battery { + border-radius: 2px; + font-weight: normal; + } + + /* 🔴 Critical */ + #custom-battery .battery-critical { + background-color: #bf616a; + color: white; + padding: 2px 6px; + border-radius: 6px; + font-weight: bold; + } + + /* 🟠 Warning */ + #custom-battery .battery-warning { + background-color: #fab387; + color: #2e3440; + padding: 2px 6px; + border-radius: 6px; + } + + /* 🟢 Normal */ + #custom-battery .battery-normal { + color: #ffffff; + } + + /* === Brightness ======================================================== */ + #backlight { + background-color: #3b4252; + } + /* === Tray ============================================================== */ + #tray { + padding: 4px 8px; + background-color: #1e1e2e; + } + /* === Custom Workspace Labels =========================================== */ + #custom-work-left, #custom-work-right { + padding: 6px 6px; + margin: 6px 3px; + } + + #custom-workspace-1:hover, #custom-workspace-2:hover, + #custom-workspace-3:hover, + #custom-workspace-4:hover { + color: #fab387; + transition: all 0.2s ease-in-out; + } + + /* === Hover Effects ===================================================== */ + /* Unified look for all interactive modules */ + #custom-microphone:hover, #custom-volume:hover, #pulseaudio:hover, + #network:hover, #custom-vpn:hover, #bluetooth:hover, + #custom-bluetooth:hover, #custom-power:hover, #custom-asus-profile:hover, + #custom-battery:hover, #battery:hover, #backlight:hover, + #custom-brightness:hover, #clock:hover, #tray:hover { + background-color: #4c566a; + border: 2px solid #56b6c2; + color: #56b6c2; + transition: all 0.2s ease-in-out; + } + /* === Tooltips ========================================================== */ + tooltip { + color: #56b6c2; + background-color: #3b4252; + border: 1px solid #56b6c2; + font-weight: bold; + } + tooltip label { + color: #78bec7; + } + ''; +} \ No newline at end of file diff --git a/home-manager/20_waybar/03_scripts.nix b/home-manager/20_waybar/03_scripts.nix new file mode 100644 index 0000000..08f64d9 --- /dev/null +++ b/home-manager/20_waybar/03_scripts.nix @@ -0,0 +1,301 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/waybar/scripts/asus-profile.sh".text = '' + #!/bin/bash + # ── asus-profile.sh ─────────────────────────────────────── + # Description: Display current ASUS power profile with color + # Usage: Called by Waybar `custom/asus-profile` + # Dependencies: asusctl, awk + # ────────────────────────────────────────────────────────── + + profile=$(asusctl profile -p | awk '/Active profile/ {print $NF}') + + case "$profile" in + Performance) + text="RAZGON" + fg="#bf616a" + ;; + Balanced) + text="STABILIZATION" + fg="#fab387" + ;; + Quiet) + text="REACTOR SLEEP" + fg="#56b6c2" + ;; + *) + text="ASUS ??" + fg="#ffffff" + ;; + esac + echo "$text" + ''; + + home.file.".config/waybar/scripts/battery.sh".text = '' + #!/bin/bash + # ── battery.sh ───────────────────────────────────────────── + # Description: Shows battery % with ASCII bar + dynamic tooltip + # Usage: Waybar `custom/battery` every 10s + # Dependencies: upower, awk, seq, printf + # ────────────────────────────────────────────────────────── + + capacity=$(cat /sys/class/power_supply/BAT0/capacity) + status=$(cat /sys/class/power_supply/BAT0/status) + + # Get detailed info from upower + time_to_empty=$(upower -i /org/freedesktop/UPower/devices/battery_BAT0 | awk -F: '/time to empty/ {print $2}' | xargs) + time_to_full=$(upower -i /org/freedesktop/UPower/devices/battery_BAT0 | awk -F: '/time to full/ {print $2}' | xargs) + + # Icons + charging_icons=(󰢜 󰂆 󰂇 󰂈 󰢝 󰂉 󰢞 󰂊 󰂋 󰂅) + default_icons=(󰁺 󰁻 󰁼 󰁽 󰁾 󰁿 󰂀 󰂁 󰂂 󰁹) + + index=$((capacity / 10)) + [ $index -ge 10 ] && index=9 + + if [[ "$status" == "Charging" ]]; then + icon=${charging_icons[$index]} + elif [[ "$status" == "Full" ]]; then + icon="󰂅" + else + icon=${default_icons[$index]} + fi + + # ASCII bar + filled=$((capacity / 10)) + empty=$((10 - filled)) + bar=$(printf '█%.0s' $(seq 1 $filled)) + pad=$(printf '░%.0s' $(seq 1 $empty)) + ascii_bar="[$bar$pad]" + + # Color thresholds + if [ "$capacity" -lt 20 ]; then + fg="#bf616a" # red + elif [ "$capacity" -lt 55 ]; then + fg="#fab387" # orange + else + fg="#56b6c2" # cyan + fi + + + # JSON output + echo "{\"text\":\"$icon $ascii_bar $capacity%\",\"tooltip\":\"$tooltip\"}" + ''; + + home.file.".config/waybar/scripts/bluetooth-toggle.sh".text = '' + #!/bin/bash + # ── bluetooth-toggle.sh ────────────────────────────────────────────────────── + # Toggle Bluetooth on/off using rfkill. + # Usage: Waybar `bluetooth` module :on-click + # Output: (changes state only) + # ───────────────────────────────────────────────────────────────────────────── + + if rfkill list bluetooth | grep -q "Soft blocked: yes"; then + rfkill unblock bluetooth + else + rfkill block bluetooth + fi + ''; + + home.file.".config/waybar/scripts/brightness.sh".text = '' + #!/bin/bash + # ── brightness.sh ───────────────────────────────────────── + # Description: Shows current brightness with ASCII bar + tooltip + # Usage: Waybar `custom/brightness` every 2s + # Dependencies: brightnessctl, seq, printf, awk + # ───────────────────────────────────────────────────────── + + # Get brightness percentage + brightness=$(brightnessctl get) + max_brightness=$(brightnessctl max) + percent=$((brightness * 100 / max_brightness)) + + # Build ASCII bar + filled=$((percent / 10)) + empty=$((10 - filled)) + bar=$(printf '█%.0s' $(seq 1 $filled)) + pad=$(printf '░%.0s' $(seq 1 $empty)) + ascii_bar="[$bar$pad]" + + # Icon + icon="󰛨" + + # Color thresholds + if [ "$percent" -lt 20 ]; then + fg="#bf616a" # red + elif [ "$percent" -lt 55 ]; then + fg="#fab387" # orange + else + fg="#56b6c2" # cyan + fi + + # Device name (first column from brightnessctl --machine-readable) + device=$(brightnessctl --machine-readable | awk -F, 'NR==1 {print $1}') + + # Tooltip text + tooltip="Brightness: $percent%\nDevice: $device" + + # JSON output + echo "{\"text\":\"$icon $ascii_bar $percent%\",\"tooltip\":\"$tooltip\"}" + ''; + + home.file.".config/waybar/scripts/brightness-toggle.sh".text = '' + #!/bin/bash + # ── brightness-toggle.sh ───────────────────────────── + # Description: Cycle screen brightness between 30%, 60%, and 100% + # Usage: Waybar `custom/brightness` on-click + # Dependencies: brightnessctl + # ───────────────────────────────────────────────────── + + current=$(brightnessctl get) + max=$(brightnessctl max) + percent=$((current * 100 / max)) + + if [ "$percent" -lt 45 ]; then + brightnessctl set 60% + elif [ "$percent" -lt 85 ]; then + brightnessctl set 100% + else + brightnessctl set 30% + fi + ''; + + home.file.".config/waybar/scripts/mic.sh".text = '' + #!/bin/bash + # ── mic.sh ───────────────────────────────────────────────── + # Description: Shows microphone mute/unmute status with icon + # Usage: Called by Waybar `custom/microphone` module every 1s + # Dependencies: pactl (PulseAudio / PipeWire) + # ─────────────────────────────────────────────────────────── + + + if pactl get-source-mute @DEFAULT_SOURCE@ | grep -q 'yes'; then + # Muted → mic-off icon + echo "[  ]" + else + # Active → mic-on icon + echo "[  ]" + fi + ''; + + home.file.".config/waybar/scripts/nordvpn-toggle.sh".text = '' + #!/bin/bash + # ── vpn-toggle.sh ───────────────────────────────────────── + # Description: Toggle VPN on/off via systemd service + # Usage: Called by Waybar `custom/vpn` on click + # Dependencies: systemctl, ip + # ────────────────────────────────────────────────────────── + + if ip a | grep -q "10\.6\.0\."; then + # VPN active → stop service (disconnect) + systemctl stop nordvpn-retry.service + systemctl stop nordvpnd.service + else + # VPN inactive → start service (connect) + systemctl start nordvpn-retry.service + fi + ''; + + home.file.".config/waybar/scripts/nordvpn-status.sh".text = '' + #!/bin/bash + # ── nordvpn-status.sh ────────────────────────────────────── + # Description: Checks if VPN interface is active via IP range + # Usage: Called by Waybar `custom/vpn` every 5s + # Dependencies: ip, curl (optional, for country lookup) + # Output: Pango markup → [ФАНТОМ]: Country or KAPUTT + # Example: [ФАНТОМ]: Japan + # [ФАНТОМ]: KAPUTT + # ─────────────────────────────────────────────────────────── + + #!/bin/bash + + if sudo ipsec statusall 2>/dev/null | grep -q "ESTABLISHED"; then + country=$(curl -s ifconfig.co/country 2>/dev/null) + [[ -z "$country" ]] && country="UNKNOWN" + echo "[УЗЕЛ]: $country" + else + echo "[НЕТ СВЯЗИ]" + fi +''; + + home.file.".config/waybar/scripts/powermenu.sh".text = '' + #!/usr/bin/env bash + # ───────────────────────────────────────────────────────────────────────────── + # Rofi Power Menu + # Provides a simple system power menu integrated with Waybar. + # Example: + # ./powermenu.sh + # # Opens a Rofi menu with power options + # ───────────────────────────────────────────────────────────────────────────── + + rofi_command="rofi -dmenu -p Power" + + options="Shutdown\nReboot\nLogout\nSuspend\nLock" + + chosen="$(echo -e "$options" | $rofi_command)" + case $chosen in + Shutdown) systemctl poweroff ;; + Reboot) systemctl reboot ;; + Logout) hyprctl dispatch exit ;; + Suspend) systemctl suspend ;; + Lock) ~/.config/hyprlock/lock.sh ;; + esac + ''; + + home.file.".config/waybar/scripts/volume.sh".text = '' + #!/bin/bash + # ── volume.sh ───────────────────────────────────────────── + # Description: Shows current audio volume with ASCII bar + tooltip + # Usage: Waybar `custom/volume` every 1s + # Dependencies: wpctl, awk, bc, seq, printf + # ─────────────────────────────────────────────────────────── + + # Get raw volume and convert to int + vol_raw=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{ print $2 }') + vol_int=$(echo "$vol_raw * 100" | bc | awk '{ print int($1) }') + + # Check mute status + is_muted=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED && echo true || echo false) + + # Get default sink description (human-readable) + sink=$(wpctl status | awk '/Sinks:/,/Sources:/' | grep '\*' | cut -d'.' -f2- | sed 's/^\s*//; s/\[.*//') + + # Icon logic + if [ "$is_muted" = true ]; then + icon="" + vol_int=0 + elif [ "$vol_int" -lt 50 ]; then + icon="" + else + icon="" + fi + + # ASCII bar + filled=$((vol_int / 10)) + empty=$((10 - filled)) + bar=$(printf '█%.0s' $(seq 1 $filled)) + pad=$(printf '░%.0s' $(seq 1 $empty)) + ascii_bar="[$bar$pad]" + + # Color logic + if [ "$is_muted" = true ] || [ "$vol_int" -lt 10 ]; then + fg="#bf616a" # red + elif [ "$vol_int" -lt 50 ]; then + fg="#fab387" # orange + else + fg="#56b6c2" # cyan + fi + + # Tooltip text + if [ "$is_muted" = true ]; then + tooltip="Audio: Muted\nOutput: $sink" + else + tooltip="Audio: $vol_int%\nOutput: $sink" + fi + + # Final JSON output + echo "{\"text\":\"$icon $ascii_bar $vol_int%\",\"tooltip\":\"$tooltip\"}" + ''; + +} \ No newline at end of file diff --git a/home-manager/20_waybar/04_workspace.nix b/home-manager/20_waybar/04_workspace.nix new file mode 100644 index 0000000..b7b0add --- /dev/null +++ b/home-manager/20_waybar/04_workspace.nix @@ -0,0 +1,56 @@ +{ config, pkgs, ... }: + +{ + home.file.".config/waybar/scripts/workspaces/workspace-1.sh".text = '' + #!/bin/bash + # workspace-1.sh — highlight workspace 1 if active + + active=$(hyprctl activeworkspace -j | jq '.id') + + if [ "$active" -eq 1 ]; then + echo "[]" + else + echo "[А]" + fi + ''; + + home.file.".config/waybar/scripts/workspaces/workspace-2.sh".text = '' + #!/bin/bash + # workspace-2.sh — highlight workspace 2 if active + + active=$(hyprctl activeworkspace -j | jq '.id') + + if [ "$active" -eq 2 ]; then + echo "[]" + else + echo "[Б]" + fi + ''; + + home.file.".config/waybar/scripts/workspaces/workspace-3.sh".text = '' + #!/bin/bash + # workspace-3.sh — highlight workspace 3 if active + + active=$(hyprctl activeworkspace -j | jq '.id') + + if [ "$active" -eq 3 ]; then + echo "[]" + else + echo "[В]" + fi + ''; + + home.file.".config/waybar/scripts/workspaces/workspace-4.sh".text = '' + #!/bin/bash + # workspace-4.sh — highlight workspace 4 if active + + active=$(hyprctl activeworkspace -j | jq '.id') + + if [ "$active" -eq 4 ]; then + echo "[]" + else + echo "[Г]" + fi + ''; + +} \ No newline at end of file diff --git a/home-manager/20_waybar/default.nix b/home-manager/20_waybar/default.nix new file mode 100644 index 0000000..2def361 --- /dev/null +++ b/home-manager/20_waybar/default.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./01_config.nix + ./02_style.nix + ./03_scripts.nix + ./04_workspace.nix + ]; +} \ No newline at end of file diff --git a/home-manager/30_zsh/01_zshrc.nix b/home-manager/30_zsh/01_zshrc.nix new file mode 100644 index 0000000..2c3a2db --- /dev/null +++ b/home-manager/30_zsh/01_zshrc.nix @@ -0,0 +1,21 @@ +{ config, pkgs, lib, ... }: + +{ + programs.zsh = { + enable = true; + enableCompletion = true; + autosuggestions.enable = true; + syntaxHighlighting.enable = true; + + initExtra = '' + PROMPT='%F{white}%BNixOS%f%F{magenta}_%f%F{blue}persephone%f %F{black}❯%f ' + ZSH_HIGHLIGHT_HIGHLIGHTERS=(main) + + # animated splash if you still want it + if [[ -n $PS1 ]]; then + ~/.config/neofetch/animated-neofetch.sh 0.05 + clear + fi + ''; + }; +} \ No newline at end of file diff --git a/home-manager/30_zsh/default.nix b/home-manager/30_zsh/default.nix new file mode 100644 index 0000000..e4d64f5 --- /dev/null +++ b/home-manager/30_zsh/default.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./01_zshrc.nix + ]; +} \ No newline at end of file diff --git a/home-manager/home.nix b/home-manager/home.nix new file mode 100644 index 0000000..7ad1995 --- /dev/null +++ b/home-manager/home.nix @@ -0,0 +1,68 @@ +{ config, pkgs, ... }: + +{ + home = { + username = "nubfriedrice"; + homeDirectory = "/home/nubfriedrice"; + stateVersion = "25.05"; + }; + + imports = [ + ./10_hypr/default.nix + + ./20_alacritty/default.nix + ./20_cava/default.nix + ./20_eww/default.nix + ./20_rofi/default.nix + ./20_waybar/default.nix + + ./30-neofetch/default.nix + ./30-zsh/default.nix + ]; + + home.packages = [ + pkgs.alacritty + pkgs.brightnessctl + pkgs.cava + pkgs.eww + pkgs.grim + pkgs.hyprpaper + pkgs.lm_sensors + pkgs.networkmanagerapplet + pkgs.num-utils + pkgs.oh-my-zsh + pkgs.playerctl + pkgs.python3 + pkgs.rofi + pkgs.slurp + pkgs.wireplumber + pkgs.wl-clipboard + pkgs.xfce.thunar + pkgs.xfce.xfce4-power-manager + pkgs.zsh-autocomplete + pkgs.zsh-syntax-highlighting + ]; + + fonts.packages = with pkgs; [ + gohufont + nerd-fonts.jetbrains-mono + ]; + + home.sessionPath = [ "$HOME/.local/bin" ]; + + home.sessionVariables = { + EDITOR= "nano"; + GDK_DPI_SCALE = "1"; + HYPRCURSOR_SIZE = "16"; + PAGER= "less"; + PROMPT= "%F{white}%BArchlinux%f%F{magenta}_%f%F{blue}Dionysus%f %F{black}❯%f "; + TERM = "xterm-256color"; + XCURSOR_SIZE = "16"; + XDG_CURRENT_DESKTOP = "Hyprland"; + XFT_DPI = "96"; + XFT_FONT = "GohuFont-11"; + ZSH_HIGHLIGHT_HIGHLIGHTERS= "(main)"; + }; + + programs.home-manager.enable = true; +} \ No newline at end of file diff --git a/nixos/configuration.nix b/nixos/configuration.nix new file mode 100644 index 0000000..8fafacf --- /dev/null +++ b/nixos/configuration.nix @@ -0,0 +1,127 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./hardware-configuration.nix + + ]; + + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + nix.registry.nixpkgs.flake = nixpkgs; + nixpkgs.config.allowUnfree = true; + environment.extraInit = '' + export NIXPKGS_ALLOW_UNFREE=1 + ''; + hardware.enableAllFirmware = true; + + boot.loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + nixpkgs.config.permittedInsecurePackages = [ + "broadcom-sta-6.30.223.271-59-6.12.57" + ]; + + boot.kernelModules = [ "wl" "ipheth" ]; + boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ]; + + networking = { + hostname = "persephone"; + networkmanager.enable = true; + interfaces.wlan0.matchConfig.MACAddress = "ca:12:ab:3c:d5:a9"; + interfaces.wlan0.ipv4.addresses = [ + { + address = "192.168.1.100"; + prefixLength = 24; + } + ]; + ipv4.gateway = "192.168.1.1"; + nameservers = [ "1.1.1.1" "8.8.8.8" ]; + }; + + time.timeZone = "Europe/London"; + i18n.defaultLocale = "en_GB.UTF-8"; + + console = { + font = "Lat2-Terminus16"; + keyMap = lib.mkForce "uk"; + useXkbConfig = true; + }; + + services.xserver.xkb.layout = "gb"; + + programs.hyprland.enable = true; + + services.pipewire = { + enable = true; + alsa.enable = true; + pulse.enable = true; + }; + + environment.systemPackages = with pkgs; [ + appimage-run + btop + exfat + exfat-progs + libappimage + gearlever + git + ntfs3g + tmux + zsh + ]; + + services.flatpak.enable = true; + + programs.steam.enable = true; + + hardware.graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [ + mesa + vulkan-loader + ]; + extraPackages32 = with pkgs.pkgsi686Linux; [ + mesa + vulkan-loader + ]; + }; + + hardware.opengl.driSupport32Bit = true; + + services.libinput.enable = true; + + users.users.nubfriedrice = { + isNormalUser = true; + shell = pkgs.zsh; + extraGroups = [ "wheel" "audio" "video" ]; + }; + + services.xserver.displayManager.lightdm.enable = true; + services.displayManager.autologin = { + enable = true; + user = "nubfriedrice"; + }; + + security.sudo.wheelNeedsPassword = false; + programs.mtr.enable = true; + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + services.openssh.enable = true; + networking.firewall.allowedTCPPorts = [ + 53317 # LocalSend + ]; + + networking.firewall.allowedUDPPorts = [ + 53317 # LocalSend + ]; + + system.copySystemConfiguration = true; + system.stateVersion = "25.11"; + +} \ No newline at end of file