From fbbd625350eb6b98abc71742e09bfc737652420f Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sat, 29 Jun 2024 02:28:20 +0200 Subject: [PATCH] WIP: home/{hyprland,waybar}: init --- home/home.nix | 10 +- home/programs/hyprland.nix | 273 ++++++++++++++++++++++++++++++++++ home/programs/waybar.nix | 230 ++++++++++++++++++++++++++++ home/services/dunst.nix | 6 +- hosts/common/default.nix | 23 ++- hosts/kasei/configuration.nix | 7 +- 6 files changed, 532 insertions(+), 17 deletions(-) create mode 100644 home/programs/hyprland.nix create mode 100644 home/programs/waybar.nix diff --git a/home/home.nix b/home/home.nix index 4562aa4..5ff6913 100644 --- a/home/home.nix +++ b/home/home.nix @@ -29,6 +29,7 @@ in { ./programs/alacritty.nix ./programs/emacs ./programs/firefox.nix + ./programs/hyprland.nix ./programs/ncmpcpp.nix ./programs/ncmpcpp.nix ./programs/newsboat @@ -36,6 +37,7 @@ in { ./programs/rofi.nix ./programs/taskwarrior.nix ./programs/vscode.nix + ./programs/waybar.nix # ./programs/xmobar ./programs/xmonad ./programs/zathura.nix @@ -43,11 +45,11 @@ in { ./services/dunst.nix ./services/fcitx5.nix ./services/mpd.nix - ./services/picom.nix - ./services/polybar.nix - ./services/screen-locker.nix + # ./services/picom.nix + # ./services/polybar.nix + # ./services/screen-locker.nix # ./services/stalonetray.nix - ./services/sxhkd.nix + # ./services/sxhkd.nix ./services/copyq.nix ]; diff --git a/home/programs/hyprland.nix b/home/programs/hyprland.nix new file mode 100644 index 0000000..b8a15f9 --- /dev/null +++ b/home/programs/hyprland.nix @@ -0,0 +1,273 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.wayland.windowManager.hyprland; +in +{ + home.sessionVariables = { + WLR_NO_HARDWARE_CURSORS = "1"; + WLR_RENDERER_ALLOW_SOFTWARE = "1"; + XDG_CURRENT_DESKTOP = "Hyprland"; + XDG_SESSION_DESKTOP = "Hyprland"; + XDG_SESSION_TYPE = "wayland"; + GDK_BACKEND = "wayland,x11,*"; + QT_QPA_PLATFORM = "wayland;xcb"; + NIXOS_OZONE_WL = "1"; + MOZ_ENABLE_WAYLAND = "1"; + SDL_VIDEODRIVER = "wayland"; + OZONE_PLATFORM = "wayland"; + CLUTTER_BACKEND = "wayland"; + QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; + # QT_QPA_PLATFORMTHEME = "qt6ct"; + QT_AUTO_SCREEN_SCALE_FACTOR = "1"; + + LIBVA_DRIVER_NAME = "nvidia"; + GBM_BACKEND = "nvidia-drm"; + __GLX_VENDOR_LIBRARY_NAME = "nvidia"; + }; + + wayland.windowManager.hyprland = { + enable = true; + + settings = let + scratchpads = [ + (rec { + title = "Floating terminal"; + class = "floatingTerminal"; + command = "alacritty --class ${class} -e tmux new-session -A -s f"; + size = { h = 90; w = 95; }; + keys = [ + "$mod, RETURN" + "$mod, SPACE" + ]; + }) + (rec { + title = "Ncmpcpp"; + class = "floatingNcmpcpp"; + command = "alacritty --class ${class} -e ncmpcpp"; + size = { h = 95; w = 95; }; + keys = [ "$mod, Q" ]; + }) + # "$mod, W, emacs" + # "$mod, E, filebrowser" + # "$mod, X, taskwarriortui" + ]; + in { + "$mod" = "SUPER"; + + # https://github.com/xkbcommon/libxkbcommon/blob/master/include/xkbcommon/xkbcommon-keysyms.h + bind = [ + "$mod SHIFT, Q, exit" + "$mod, R, exec, ${pkgs.rofi}/bin/rofi -show drun" + "$mod, T, togglefloating" + "$mod, F, fakefullscreen" + "$mod, C, exec, hyprctl reload" + + "$mod, BACKSPACE, exec, ${lib.getExe (pkgs.writeShellApplication { + name = "hyprland-kill-windows-except-scratchpads"; + runtimeInputs = [ cfg.package pkgs.jq ]; + text = '' + ACTIVE_WINDOW_CLASS=$(hyprctl activewindow -j | jq -r '.class') + + case "$ACTIVE_WINDOW_CLASS" in + ${lib.pipe scratchpads [ + (map ({ class , ... }: '' + '${class}') + hyprctl dispatch togglespecialworkspace '${class}Ws' + ;; + '')) + (map (lib.splitString "\n")) + (lib.flatten) + (map (x: " " + x)) + (lib.concatStringsSep "\n") + ]} + *) + hyprctl dispatch killactive + ;; + esac + ''; + })}" + + "$mod SHIFT, RETURN, exec, alacritty --class termTerminal -e tmux new-session -A -s term" + "$mod SHIFT, SPACE, exec, alacritty --class termTerminal -e tmux new-session -A -s term" + + "$mod, j, layoutmsg,cyclenext" + "$mod, k, layoutmsg,cycleprev" + "$mod SHIFT, j, layoutmsg, swapnext" + "$mod SHIFT, k, layoutmsg, swapprev" + + "$mod, 1, workspace, 1" + "$mod, 2, workspace, 2" + "$mod, 3, workspace, 3" + "$mod, 4, workspace, 4" + "$mod, 5, workspace, 5" + "$mod, 6, workspace, 6" + "$mod, 7, workspace, 7" + "$mod, 8, workspace, 8" + "$mod, 9, workspace, 9" + + "$mod SHIFT, 1, movetoworkspace, 1" + "$mod SHIFT, 2, movetoworkspace, 2" + "$mod SHIFT, 3, movetoworkspace, 3" + "$mod SHIFT, 4, movetoworkspace, 4" + "$mod SHIFT, 5, movetoworkspace, 5" + "$mod SHIFT, 6, movetoworkspace, 6" + "$mod SHIFT, 7, movetoworkspace, 7" + "$mod SHIFT, 8, movetoworkspace, 8" + "$mod SHIFT, 9, movetoworkspace, 9" + + # TODO: ensure this exists in env + ",XF86MonBrightnessUp, exec, brightnessctl s +5%" + ",XF86MonBrightnessDown, exec, brightnessctl s 5%-" + # TODO: swap out for wireplumber commands + ",XF86AudioLowerVolume, exec, ${pkgs.alsaUtils}/bin/amixer set Master 2%-" + ",XF86AudioRaiseVolume, exec, ${pkgs.alsaUtils}/bin/amixer set Master 2%+" + "$mod ,F7, exec, ${pkgs.alsaUtils}/bin/amixer set Master 2%-" + "$mod ,F8, exec, ${pkgs.alsaUtils}/bin/amixer set Master 2%+" + + "$mod, p, exec, ${pkgs.mpc_cli}/bin/mpc toggle" + ",XF86AudioPlay, exec, ${pkgs.mpc_cli}/bin/mpc toggle" + ",XF86AudioPrev, exec, ${pkgs.mpc_cli}/bin/mpc prev" + ",XF86AudioNext, exec, ${pkgs.mpc_cli}/bin/mpc next" + + "$mod, b, exec, ${pkgs.fcitx5}/bin/fcitx5-remote -s mozc" + "$mod, n, exec, ${pkgs.fcitx5}/bin/fcitx5-remote -s keyboard-no" + "$mod, m, exec, ${pkgs.fcitx5}/bin/fcitx5-remote -s keyboard-us" + + # TODO: ensure exists in environment + "$mod, l, exec, loginctl lock-session" + + # TODO: fix + # "super + minus" = "${pkgs.xcalib}/bin/xcalib -invert -alter" + + # TODO: fix + # "@Print" = "${pkgs.maim}/bin/maim --hidecursor --nokeyboard --select | ${pkgs.xclip}/bin/xclip -selection clipboard -target image/png -in" + + # "shift + @Print" = "${pkgs.maim}/bin/maim --hidecursor --nokeyboard $SCREENSHOT_DIR/$(date +%s).png" + + # TODO: Add boomer as package + # "super + @Print" = "boomer" + ] + ++ + (lib.pipe scratchpads [ + (map ({ keys, command, class, ... }: + (map (key: let + # TODO: rewrite the scratchpad logic to move windows back and forth + # from the special workspaces, rather than overlay the workspaces. + # + # TODO: don't invoke the program upon close toggling the scratchpad + # + # TODO: ensure program becomes in focus upon open toggling the scratchpad + invokeIfNotRunningAndToggleWorkspace = pkgs.writeShellApplication { + name = "hyprland-toggle-scratchpad-${class}"; + runtimeInputs = [ cfg.package pkgs.jq ]; + text = '' + SCRATCHPAD_EXISTS=$(hyprctl clients -j | jq -r '[.[].class]|any(. == "${class}")') + + if [ "$SCRATCHPAD_EXISTS" != "true" ]; then + ${command} & + fi + + hyprctl dispatch togglespecialworkspace '${class}Ws' + ''; + }; + in "${key}, exec, ${lib.getExe invokeIfNotRunningAndToggleWorkspace}" + ) keys) + )) + lib.flatten + ]); + + windowrulev2 = [ + "float,class:(Rofi)" + + "workspace 2,class:(firefox)" + "workspace 2,class:(google-chrome)" + + "workspace 3,class:(Emacs)" + "workspace 3,class:(Code)" + "workspace 3,class:(code-url-handler)" + + "workspace 5,class:(discord)" + "workspace 5,class:(Element)" + ] + ++ + (lib.pipe scratchpads [ + (map ({ class, size, ... }: [ + "workspace special:${class}Ws, class:^${class}$" + "float, class:^${class}$" + "size ${toString size.w}% ${toString size.h}%, class:^${class}$" + "move ${toString ((100 - size.w) / 2)}% ${toString ((100 - size.h) / 2)}%, class:^${class}$" + ])) + lib.flatten + ]); + + monitor = [ + "DP-6, 1920x1080@144.00Hz, 0x0, 1" + "DVI-D-1, 1920x1080@144.00Hz, 1920x0, 1" + ",preferred,auto,1" + ]; + + general = { + gaps_in = 5; + gaps_out = 15; + + border_size = 2; + + "col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg"; + "col.inactive_border" = "rgba(595959aa)"; + + resize_on_border = false; + allow_tearing = false; + layout = "master"; + }; + + decoration = { + rounding = 10; + + # Change transparency of focused and unfocused windows + active_opacity = 1.0; + inactive_opacity = 1.0; + + drop_shadow = true; + shadow_range = 4; + shadow_render_power = 3; + "col.shadow" = "rgba(1a1a1aee)"; + + # https://wiki.hyprland.org/Configuring/Variables/#blur + blur = { + enabled = true; + size = 3; + passes = 1; + + vibrancy = 0.1696; + }; + }; + + animations.enabled = false; + + master = { + new_is_master = false; + }; + + misc = { + force_default_wallpaper = 0; # Set to 0 or 1 to disable the anime mascot wallpapers + disable_hyprland_logo = false; # If true disables the random hyprland logo / anime girl background. :( + }; + + input ={ + kb_layout = "us"; + kb_variant = ""; + kb_model = ""; + kb_options = ""; + kb_rules = ""; + + follow_mouse = 1; + + sensitivity = 0; # -1.0 - 1.0, 0 means no modification. + + touchpad = { + natural_scroll = false; + }; + }; + }; + }; +} diff --git a/home/programs/waybar.nix b/home/programs/waybar.nix new file mode 100644 index 0000000..af5194b --- /dev/null +++ b/home/programs/waybar.nix @@ -0,0 +1,230 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.programs.waybar; + cfgs = cfg.settings.mainBar; +in +{ + programs.waybar = { + enable = true; + systemd.enable = true; + + settings = { + mainBar = { + layer = "top"; + position = "top"; + height = 30; + + # TODO: configure this per machine + output = [ "DP-6" ]; + + modules-left = [ "hyprland/workspaces" ]; + modules-center = [ "clock" ]; + modules-right = [ "mpd" "cpu" "memory" "wireplumber" "pulseaudio/slider" "tray" ]; + + "hyprland/workspaces" = { + all-outputs = true; + disable-scroll = true; + persistent-workspaces = { + ${lib.head cfgs.output} = [ 1 2 3 4 5 6 7 8 ]; + }; + }; + + "mpd" = { + format = "{filename}"; + }; + + "memory" = { + format = "{used}/{total}Gb"; + }; + + "pulseaudio/slider" = { + orientation = "horizontal"; + }; + + "tray" = { + icon-size = 20; + spacing = 8; + }; + }; + }; + + style = let + c = config.colors.defaultColorSet; + in '' + * { + font-family: FiraCode, FontAwesome, Roboto, Helvetica, Arial, sans-serif; + font-size: 13px; + } + + window#waybar { + background-color: ${c.background}; + color: ${c.foreground}; + } + + #pulseaudio-slider trough { + min-height: 10px; + min-width: 100px; + } + + /**** DEFAULT ****/ + + window#waybar.hidden { + opacity: 0.2; + } + + button { + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: inset 0 -3px transparent; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; + } + + /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ + button:hover { + background: inherit; + box-shadow: inset 0 -3px #ffffff; + } + + + #workspaces button.empty { + color: ${c.yellow}; + } + + #workspaces button { + padding: 0 5px; + color: ${c.magenta}; + background-color: transparent; + } + + #workspaces button.visible { + color: ${c.green}; + } + + #workspaces button.urgent { + background-color: ${c.red}; + } + + #workspaces button:hover { + background: rgba(0, 0, 0, 0.2); + } + + #mode { + background-color: #64727D; + box-shadow: inset 0 -3px #ffffff; + } + + #clock, + #battery, + #cpu, + #memory, + #disk, + #temperature, + #backlight, + #network, + #pulseaudio, + #wireplumber, + #custom-media, + #tray, + #mode, + #idle_inhibitor, + #scratchpad, + #power-profiles-daemon, + #mpd { + padding: 0 10px; + color: ${c.foreground}; + } + + #window, + #workspaces { + margin: 0 4px; + } + + /* If workspaces is the leftmost module, omit left margin */ + .modules-left > widget:first-child > #workspaces { + margin-left: 0; + } + + /* If workspaces is the rightmost module, omit right margin */ + .modules-right > widget:last-child > #workspaces { + margin-right: 0; + } + + #clock { + background-color: #64727D; + } + + #cpu { + background-color: ${c.cyan}; + color: #000000; + } + + #memory { + background-color: ${c.yellow}; + color: #000000; + } + + #network { + background-color: #2980b9; + } + + #network.disconnected { + background-color: #f53c3c; + } + + #pulseaudio { + background-color: #f1c40f; + color: #000000; + } + + #pulseaudio.muted { + background-color: #90b1b1; + color: #2a5c45; + } + + #wireplumber { + background-color: #fff0f5; + color: #000000; + } + + #wireplumber.muted { + background-color: #f53c3c; + } + + #tray { + background-color: #2980b9; + } + + #tray > .passive { + -gtk-icon-effect: dim; + } + + #tray > .needs-attention { + -gtk-icon-effect: highlight; + background-color: #eb4d4b; + } + + #mpd { + background-color: #66cc99; + color: #2a5c45; + } + + #mpd.disconnected { + background-color: #f53c3c; + } + + #mpd.stopped { + background-color: #90b1b1; + } + + #mpd.paused { + background-color: #51a37a; + } + ''; + # background-color: rgba(0,0,0,0); + # border-bottom: 3px solid rgba(100, 114, 125, 0.5); + + #style = '' + #''; + }; +} diff --git a/home/services/dunst.nix b/home/services/dunst.nix index fb0f14f..e07f46e 100644 --- a/home/services/dunst.nix +++ b/home/services/dunst.nix @@ -13,9 +13,9 @@ class = "Dunst"; browser = "${pkgs.xdg-utils}/bin/xdg-open"; - offset = let - status-bar-height = config.services.polybar.settings."bar/top".height; - in "15x${toString (status-bar-height + 10)}"; + # offset = let + # status-bar-height = config.services.polybar.settings."bar/top".height; + # in "15x${toString (status-bar-height + 10)}"; corner_radius = 0; font = "Droid Sans 9"; diff --git a/hosts/common/default.nix b/hosts/common/default.nix index cf479f1..bdea11a 100644 --- a/hosts/common/default.nix +++ b/hosts/common/default.nix @@ -265,7 +265,14 @@ in { touchpad.disableWhileTyping = true; }; - displayManager.defaultSession = "none+xmonad"; + displayManager = { + enable = true; + defaultSession = "none+xmonad"; + sddm = { + enable = !config.machineVars.headless; + wayland.enable = true; + }; + }; xserver = { enable = !config.machineVars.headless; @@ -275,12 +282,12 @@ in { options = "caps:escape"; }; - desktopManager = { - xterm.enable = false; - xfce.enable = !config.machineVars.headless; - }; + # desktopManager = { + # xterm.enable = false; + # xfce.enable = !config.machineVars.headless; + # }; - displayManager.lightdm.enable = !config.machineVars.headless; + # displayManager.lightdm.enable = !config.machineVars.headless; windowManager.xmonad = { enable = true; @@ -290,9 +297,7 @@ in { dbus ]; }; - }; - }; programs = { @@ -301,6 +306,8 @@ in { tmux.enable = true; zsh.enable = true; + hyprland.enable = true; + gnupg.agent.enable = true; gnupg.agent.pinentryPackage = pkgs.pinentry-curses; diff --git a/hosts/kasei/configuration.nix b/hosts/kasei/configuration.nix index 9c060dd..d49fef0 100644 --- a/hosts/kasei/configuration.nix +++ b/hosts/kasei/configuration.nix @@ -73,7 +73,7 @@ services = { openssh = { enable = true; - settings.X11Forwarding = true; + # settings.X11Forwarding = true; }; xserver.videoDrivers = [ "nvidia" ]; tailscale.enable = true; @@ -97,7 +97,7 @@ kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages; kernelModules = [ "kvm-amd" ]; blacklistedKernelModules = [ "nouveau" ]; - kernelParams = [ "nomodeset" ]; + # kernelParams = [ "nomodeset" ]; supportedFilesystems = [ "zfs" ]; loader = { @@ -150,6 +150,9 @@ nvidia = { modesetting.enable = true; nvidiaSettings = true; + powerManagement.enable = false; + powerManagement.finegrained = false; + open = false; }; }; }