From 8224513e07f4df4891500270942ff96708f507bd Mon Sep 17 00:00:00 2001 From: Thomas Syms Date: Sun, 10 Aug 2025 22:39:39 -0300 Subject: [PATCH] Add Hyprland and Greetd configurations; update desktop settings and user examples --- home/panotaka/Bellerophon.nix | 3 +- home/panotaka/common/core/default.nix | 4 - home/panotaka/common/core/shell/nushell.nix | 6 + home/panotaka/common/core/shell/zsh.nix | 19 +++ .../optional/desktops/hyprland/default.nix | 48 ++++++ .../optional/desktops/hyprland/hypridle.nix | 37 +++++ .../optional/desktops/hyprland/hyprlock.nix | 13 ++ .../desktops/hyprland/zenbook-screen.nix | 140 ++++++++++++++++++ hosts/common/optional/greetd.nix | 15 ++ hosts/common/optional/hyprland.nix | 18 +++ .../theming/themes/tokyonight/default.nix | 6 + .../users/exampleSecondUser/default.nix | 85 +++++------ hosts/nixos/Bellerophon/default.nix | 4 +- 13 files changed, 347 insertions(+), 51 deletions(-) create mode 100644 home/panotaka/common/core/shell/nushell.nix create mode 100644 home/panotaka/common/core/shell/zsh.nix create mode 100644 home/panotaka/common/optional/desktops/hyprland/default.nix create mode 100644 home/panotaka/common/optional/desktops/hyprland/hypridle.nix create mode 100644 home/panotaka/common/optional/desktops/hyprland/hyprlock.nix create mode 100644 home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix create mode 100644 hosts/common/optional/greetd.nix create mode 100644 hosts/common/optional/hyprland.nix diff --git a/home/panotaka/Bellerophon.nix b/home/panotaka/Bellerophon.nix index 8c513f5..7fa9380 100644 --- a/home/panotaka/Bellerophon.nix +++ b/home/panotaka/Bellerophon.nix @@ -10,7 +10,8 @@ # # FIXME(starter): add or remove any optional config directories or files ehre common/optional/browsers - common/optional/desktops + common/optional/desktops/hyprland + common/optional/desktops/hyprland/zenbook-screen.nix common/optional/comms common/optional/media common/optional/coding diff --git a/home/panotaka/common/core/default.nix b/home/panotaka/common/core/default.nix index e38d289..06517ce 100644 --- a/home/panotaka/common/core/default.nix +++ b/home/panotaka/common/core/default.nix @@ -37,10 +37,6 @@ in { sessionPath = [ "$HOME/.local/bin" ]; - sessionVariables = { - FLAKE = "$HOME/src/nix/nix-config"; - SHELL = "bash"; - }; }; home.packages = with pkgs; [ diff --git a/home/panotaka/common/core/shell/nushell.nix b/home/panotaka/common/core/shell/nushell.nix new file mode 100644 index 0000000..143b566 --- /dev/null +++ b/home/panotaka/common/core/shell/nushell.nix @@ -0,0 +1,6 @@ +{pkgs, ...}: { + programs.nushell = { + enable = true; + configFile.source = null; # Use default config, or set to a custom file if desired + }; +} diff --git a/home/panotaka/common/core/shell/zsh.nix b/home/panotaka/common/core/shell/zsh.nix new file mode 100644 index 0000000..37ac10c --- /dev/null +++ b/home/panotaka/common/core/shell/zsh.nix @@ -0,0 +1,19 @@ +{pkgs, ...}: { + programs.zsh = { + enable = true; + enableCompletion = true; + syntaxHighlighting.enable = true; + autosuggestions.enable = true; + history = { + save = 10000; + share = true; + }; + plugins = [ + { + name = "zsh-autopair"; + src = pkgs.zsh-autopair; + } + # Add more plugins here as needed + ]; + }; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/default.nix b/home/panotaka/common/optional/desktops/hyprland/default.nix new file mode 100644 index 0000000..80c3d8f --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/default.nix @@ -0,0 +1,48 @@ +{ + config, + lib, + pkgs, + ... +}: { + imports = [ + ./hyprlock.nix + ./hypridle.nix + ]; + + # Misc settingsmanager configuration + wayland.windowManager.hyprland = { + enable = true; + plugins = with pkgs.hyprlandPlugins; [ + # Add any additional Hyprland plugins here + hyprspace + ]; + settings = { + # Set mod key + "$mod" = "SUPER"; + # Enable inverted (natural) scrolling on touchpad + "input:touchpad:natural_scroll" = true; + # Disable middle click on touchpad + "input:touchpad:clickfinger_behavior" = false; + "input:touchpad:middle_button_emulation" = false; + # Enable 3-finger swipe to change workspaces + "gestures:workspace_swipe" = true; + + "gestures:workspace_swipe_fingers" = 3; + "plugin:overview:reverseSwipe" = true; + # Keybinds + bind = [ + # Launch terminal (kitty) + "$mod,RETURN,exec,kitty" + # Launch browser (zen) + "$mod,B,exec,zen" + # Close window + "$mod,Q,killactive" + # Logout + "$mod SHIFT,E,exit" + + # Overview + "$mod,TAB,overview:toggle" + ]; + }; + }; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/hypridle.nix b/home/panotaka/common/optional/desktops/hyprland/hypridle.nix new file mode 100644 index 0000000..fde468e --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/hypridle.nix @@ -0,0 +1,37 @@ +{pkgs, ...}: { + services.hypridle = { + enable = true; + settings = { + general = { + lock_cmd = "pidof hyprlock || hyprlock"; + before_sleep_cmd = "loginctl lock-session"; + after_sleep_cmd = "hyprctl dispatch dpms on"; + }; + + listener = [ + { + timeout = 150; + on-timeout = "brightnessctl -s set 10"; + on-resume = "brightnessctl -r"; + } + { + timeout = 300; + on-timeout = "loginctl lock-session"; + } + { + timeout = 330; + on-timeout = "hyprctl dispatch dpms off"; + on-resume = "hyprctl dispatch dpms on"; + } + { + timeout = 1800; + on-timeout = "systemctl suspend"; + } + ]; + }; + }; + + home.packages = with pkgs; [ + hypridle + ]; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix b/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix new file mode 100644 index 0000000..d678924 --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix @@ -0,0 +1,13 @@ +{pkgs, ...}: { + programs.hyprlock = { + enable = true; + }; + + wayland.windowManager.hyprland.keybinds = [ + "$mod,L,exec,hyprlock" + ]; + + home.packages = with pkgs; [ + hyprlock + ]; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix b/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix new file mode 100644 index 0000000..9e338c8 --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix @@ -0,0 +1,140 @@ +{pkgs, ...}: let + # Configuration variables from your script + preferred_resolution = "2880x1800"; + refresh_rate = "120"; + ui_scale = "1.5"; + y_offset = "1200"; + vrr_mode = "1"; # 0 = off, 1 = on, 2 = fullscreen only + + # Inline scripts adapted from your bash script + zenbook-top = pkgs.writeShellScriptBin "zenbook-top" '' + echo "Setting to top screen only" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,disable" + ''; + + zenbook-bottom = pkgs.writeShellScriptBin "zenbook-bottom" '' + echo "Setting to bottom screen only" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,disable" + ''; + + zenbook-both = pkgs.writeShellScriptBin "zenbook-both" '' + echo "Setting to both screens" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,${preferred_resolution}@${refresh_rate},0x${y_offset},${ui_scale},vrr,${vrr_mode}" + ''; + + zenbook-left-up = pkgs.writeShellScriptBin "zenbook-left-up" '' + echo "Setting to left-right layout" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,${preferred_resolution}@${refresh_rate},${y_offset}x0,${ui_scale},vrr,${vrr_mode}" + ''; + + zenbook-right-up = pkgs.writeShellScriptBin "zenbook-right-up" '' + echo "Setting to right-left layout" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,${preferred_resolution}@${refresh_rate},${y_offset}x0,${ui_scale},vrr,${vrr_mode}" + ''; + + zenbook-normal = pkgs.writeShellScriptBin "zenbook-normal" '' + # Check if lid is closed + lid_closed=false + if grep -q closed /proc/acpi/button/lid/*/state 2>/dev/null; then + lid_closed=true + fi + + # Check if keyboard is attached (USB dock detection) + keyboard_attached=false + if ${pkgs.usbutils}/bin/lsusb | grep 0b05:1b2c; then + keyboard_attached=true + fi + + if [ "$lid_closed" = true ] && [ "$keyboard_attached" = true ]; then + echo "Lid closed and keyboard attached — disabling both screens" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,disable" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,disable" + elif [ "$lid_closed" = true ]; then + echo "Lid closed — disabling top screen" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,disable" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + elif [ "$keyboard_attached" = true ]; then + echo "Keyboard attached — disabling bottom screen" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-1,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + ${pkgs.hyprland}/bin/hyprctl keyword monitor "eDP-2,disable" + else + echo "Normal mode — enabling both screens" + ${zenbook-both}/bin/zenbook-both + fi + ''; + + zenbook-toggle = pkgs.writeShellScriptBin "zenbook-toggle" '' + # Check current state and toggle + enabled_count=$(${pkgs.hyprland}/bin/hyprctl monitors | grep -c "eDP.*" || echo "0") + if [ "$enabled_count" -eq 1 ]; then + ${zenbook-both}/bin/zenbook-both + else + ${zenbook-top}/bin/zenbook-top + fi + ''; + + # Event-driven display management (from your original script) + zenbook-watch-displays = pkgs.writeShellScriptBin "zenbook-watch-displays" '' + ${zenbook-normal}/bin/zenbook-normal + while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/; do + ${zenbook-normal}/bin/zenbook-normal + done + ''; + + zenbook-set-displays = pkgs.writeShellScriptBin "zenbook-set-displays" '' + sleep 1 + ${zenbook-normal}/bin/zenbook-normal + ''; + + # Auto-run display setup on startup + zenbook-autostart = pkgs.writeShellScriptBin "zenbook-autostart" '' + # Initial display setup + ${zenbook-normal}/bin/zenbook-normal + + # Start USB monitoring in background + ${zenbook-watch-displays}/bin/zenbook-watch-displays & + ''; +in { + # Zenbook dual-screen display configuration + wayland.windowManager.hyprland.settings = { + # Monitor configuration for Zenbook dual screens + monitor = [ + # Primary display (eDP-1) - top screen + "eDP-1,${preferred_resolution}@${refresh_rate},0x0,${ui_scale},vrr,${vrr_mode}" + # Secondary display (eDP-2) - bottom screen positioned below primary + "eDP-2,${preferred_resolution}@${refresh_rate},0x${y_offset},${ui_scale},vrr,${vrr_mode}" + # Fallback for any other monitors + ",preferred,auto,1" + ]; + + # VRR and performance optimizations + misc = { + # Enable Variable Frame Rate to save power when screen is static + vfr = true; + }; + + # Auto-start the event-driven display management + exec-once = [ + "${zenbook-autostart}/bin/zenbook-autostart" + ]; + }; + + # Add the scripts to home packages + home.packages = [ + zenbook-top + zenbook-bottom + zenbook-both + zenbook-left-up + zenbook-right-up + zenbook-normal + zenbook-toggle + zenbook-watch-displays + zenbook-set-displays + zenbook-autostart + ]; +} diff --git a/hosts/common/optional/greetd.nix b/hosts/common/optional/greetd.nix new file mode 100644 index 0000000..f4e8d23 --- /dev/null +++ b/hosts/common/optional/greetd.nix @@ -0,0 +1,15 @@ +{pkgs, ...}: { + services.greetd = { + enable = true; + settings = { + default_session = { + command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd ${pkgs.hyprland}/bin/Hyprland"; + user = "greeter"; + }; + }; + }; + + # Disable conflicting getty services on tty1 + systemd.services."getty@tty1".enable = false; + systemd.services."autovt@tty1".enable = false; +} diff --git a/hosts/common/optional/hyprland.nix b/hosts/common/optional/hyprland.nix new file mode 100644 index 0000000..3693264 --- /dev/null +++ b/hosts/common/optional/hyprland.nix @@ -0,0 +1,18 @@ +{ + config, + pkgs, + inputs, + ... +}: { + programs.hyprland = { + enable = true; + # You can add more configuration options here as needed + # For example, to set a basic config file: + # settings = { + # ... + # }; + portalPackage = pkgs.xdg-desktop-portal-hyprland; + }; + + environment.sessionVariables.NIXOS_OZONE_WL = "1"; +} diff --git a/hosts/common/optional/theming/themes/tokyonight/default.nix b/hosts/common/optional/theming/themes/tokyonight/default.nix index bef51bc..d456af8 100644 --- a/hosts/common/optional/theming/themes/tokyonight/default.nix +++ b/hosts/common/optional/theming/themes/tokyonight/default.nix @@ -13,6 +13,12 @@ in { stylix.base16Scheme = "${tinted-schemes}/base16/tokyo-city-dark.yaml"; + stylix.cursor = { + package = pkgs.qogir-icon-theme; + name = "Qogir"; + size = 24; + }; + stylix.fonts = { serif = { package = pkgs.noto-fonts; diff --git a/hosts/common/users/exampleSecondUser/default.nix b/hosts/common/users/exampleSecondUser/default.nix index ef438c0..0623a63 100644 --- a/hosts/common/users/exampleSecondUser/default.nix +++ b/hosts/common/users/exampleSecondUser/default.nix @@ -1,67 +1,64 @@ # FIXME(starter): this is an example of how a secondary user called "exampleSecondUser" can be declared. # NOTE that this file's parent directory matches the username! # Modify the directory name and all instances of `exampleSecondUser` in this file to a real username to -# make use of this file. You'll also need to import this file in the relevant `nix-config/hosts/[platform]/[hostname]/default.nix` +# make use of this file. You'll also need to import this file in the relevant `nix-config/hosts/[platform]/[hostname]/default.nix` # host file for the user to be created on the host. # NOTE that this file also assumes you will be declaring the user's password via sops. # . # If you have no need for secondary users, simple delete this file and its parent directory, and ensure that # your `nix-confitg/hosts/[platform]/[hostname]/default.nix` files do not import this file. - # # Basic user for viewing exampleSecondUser # - { inputs, lib, pkgs, config, ... -}: -let +}: let hostSpec = config.hostSpec; secretsSubPath = "passwords/exampleSecondUser"; in -{ - # Decrypt passwords/exampleSecondUser to /run/secrets-for-users/ so it can be used to create the user - sops.secrets.${secretsSubPath}.neededForUsers = true; - users.mutableUsers = false; # Required for password to be set via sops during system activation! + { + # Decrypt passwords/exampleSecondUser to /run/secrets-for-users/ so it can be used to create the user + sops.secrets.${secretsSubPath}.neededForUsers = true; + users.mutableUsers = false; # Required for password to be set via sops during system activation! - users.users.exampleSecondUser = { - isNormalUser = true; - hashedPasswordFile = config.sops.secrets.${secretsSubPath}.path; - shell = pkgs.zsh; # default shell - extraGroups = [ - "audio" - "video" - ]; + users.users.exampleSecondUser = { + isNormalUser = true; + hashedPasswordFile = config.sops.secrets.${secretsSubPath}.path; + shell = pkgs.zsh; # default shell + extraGroups = [ + "audio" + "video" + ]; - packages = [ pkgs.home-manager ]; - }; -} -# Import this user's personal/home configurations -// lib.optionalAttrs (inputs ? "home-manager") { - home-manager = { - extraSpecialArgs = { - inherit pkgs inputs; - hostSpec = config.hostSpec; + packages = [pkgs.home-manager]; }; - users.exampleSecondUser.imports = lib.flatten ( - lib.optional (!hostSpec.isMinimal) [ - ( - { config, ... }: - import (lib.custom.relativeToRoot "home/exampleSecondUser/${hostSpec.hostName}.nix") { - inherit - pkgs - inputs - config - lib - hostSpec - ; - } - ) - ] - ); - }; -} + } + # Import this user's personal/home configurations + // lib.optionalAttrs (inputs ? "home-manager") { + home-manager = { + extraSpecialArgs = { + inherit pkgs inputs; + hostSpec = config.hostSpec; + }; + users.exampleSecondUser.imports = lib.flatten ( + lib.optional (!hostSpec.isMinimal) [ + ( + {config, ...}: + import (lib.custom.relativeToRoot "home/exampleSecondUser/${hostSpec.hostName}.nix") { + inherit + pkgs + inputs + config + lib + hostSpec + ; + } + ) + ] + ); + }; + } diff --git a/hosts/nixos/Bellerophon/default.nix b/hosts/nixos/Bellerophon/default.nix index 7d566bd..d557279 100644 --- a/hosts/nixos/Bellerophon/default.nix +++ b/hosts/nixos/Bellerophon/default.nix @@ -74,8 +74,8 @@ "hosts/common/optional/services/docker.nix" "hosts/common/optional/services/tailscale.nix" "hosts/common/optional/audio.nix" # pipewire and cli controls - "hosts/common/optional/kde.nix" - "hosts/common/optional/sddm.nix" + "hosts/common/optional/hyprland.nix" + "hosts/common/optional/greetd.nix" "hosts/common/optional/flatpak.nix" "hosts/common/optional/thermal-management.nix"