Added nixos configs

This commit is contained in:
2026-02-22 19:25:39 +01:00
parent c0f19a200d
commit 8694deed28
9013 changed files with 118058 additions and 0 deletions
@@ -0,0 +1,72 @@
# IMPORTANT:
# Only packages/attributes that exist in Nixpkgs can be installed.
# Check names on https://search.nixos.org/packages
# A wrong package name (or attribute path) will cause the Nix build to fail.
# system
waybar
wofi
dunst
xdg-utils
desktop-file-utils
playerctl
pamixer
brightnessctl
rofi
home-manager
# browsers
brave
vivaldi
chromium
# hyprland
hyprpaper
# utils
wget
flatpak
nextcloud-client
kdePackages.okular
kdePackages.gwenview
kdePackages.kdeconnect-kde
_1password-gui
docker
tree
ripgrep
gparted
file
htop
wev
solaar
# terminal
kitty
starship
kdePackages.konsole
kdePackages.yakuake
# office
obsidian
onlyoffice-desktopeditors
# development
git
vscode-with-extensions
kdePackages.kate
jetbrains.pycharm
python3
# communication
nextcloud-talk-desktop
signal-desktop
# multimedia
spotify
vlc
# graphic
gimp2
@@ -0,0 +1,4 @@
app.zen_browser.zen
com.github.tchx84.Flatseal
eu.betterbird.Betterbird
com.todoist.Todoist
@@ -0,0 +1,71 @@
# IMPORTANT:
# Only packages/attributes that exist in Nixpkgs can be installed.
# Check names on https://search.nixos.org/packages
# A wrong package name (or attribute path) will cause the Nix build to fail.
# system
waybar
wofi
dunst
xdg-utils
desktop-file-utils
playerctl
pamixer
brightnessctl
rofi
home-manager
# browsers
brave
vivaldi
chromium
# hyprland
hyprpaper
# utils
wget
flatpak
nextcloud-client
kdePackages.okular
kdePackages.gwenview
kdePackages.kdeconnect-kde
_1password-gui
docker
tree
ripgrep
gparted
file
htop
wev
solaar
# terminal
kitty
starship
kdePackages.konsole
kdePackages.yakuake
# office
obsidian
onlyoffice-desktopeditors
# development
git
vscode-with-extensions
kdePackages.kate
jetbrains.pycharm
python3
# communication
nextcloud-talk-desktop
signal-desktop
# multimedia
spotify
vlc
# graphic
gimp2
@@ -0,0 +1,11 @@
# Minimal Hyprland config for greetd
monitor = , preferred, auto, 1
misc {
disable_hyprland_logo = true
disable_splash_rendering = true
}
# Start qtgreet and point it at the correct session paths for NixOS
exec-once = sh -lc 'source /etc/greetd/qtgreet-session-paths; exec qtgreet -w "$WAYLAND_SESSIONS" -x "$X11_SESSIONS"'
@@ -0,0 +1,130 @@
###############
###############
$mainMod = SUPER
# use walker to show exec menu
"$mainMod, Space, exec, walker"
"$mainMod, P, pseudo"
"$mainMod, J, togglesplit"
# grimblast
"$mainMod_SHIFT, p, exec, grimblast -n -f copysave active"
"$mainMod_SHIFT, a, exec, grimblast -n -f copysave area"
"$mainMod_ALT, p, exec, grimblast -n -f copysave output"
"$mainMod_CTRL, p, exec, grimblast -n -f copysave screen"
# Terminal / launcher / kill / reload
$mainMod, RETURN, exec, kitty
$mainMod, D, exec, wofi --show drun
$mainMod, Q, killactive,
$mainMod_SHIFT, Q, exit,
$mainMod_SHIFT, R, exec, hyprctl reload
"$mainMod_SHIFT, S, exec, wlogout"
# Default browser
$mainMod, W, exec, xdg-open https://about:blank
# Focus movement
$mainMod, H, movefocus, l
$mainMod, L, movefocus, r
$mainMod, K, movefocus, u
$mainMod, J, movefocus, d
$mainMod, left, movefocus, l
$mainMod, right, movefocus, r
$mainMod, up, movefocus, u
$mainMod, down, movefocus, d
# Keybindings #
# Move windows
$mainMod_SHIFT, H, movewindow, l
$mainMod_SHIFT, L, movewindow, r
$mainMod_SHIFT, K, movewindow, u
$mainMod_SHIFT, J, movewindow, d
$mainMod_SHIFT, left, movewindow, l
$mainMod_SHIFT, right, movewindow, r
$mainMod_SHIFT, up, movewindow, u
$mainMod_SHIFT, down, movewindow, d
# Resize windows
$mainMod CTRL, H, resizeactive, -30 0
$mainMod CTRL, L, resizeactive, 30 0
$mainMod CTRL, K, resizeactive, 0 -30
$mainMod CTRL, J, resizeactive, 0 30
# Floating / fullscreen
$mainMod, V, togglefloating,
$mainMod, F, fullscreen, 0
$mainMod_SHIFT, F, fullscreen, 1
# Workspaces
$mainMod, 1, workspace, 1
$mainMod, 2, workspace, 2
$mainMod, 3, workspace, 3
$mainMod, 4, workspace, 4
$mainMod, 5, workspace, 5
$mainMod, 6, workspace, 6
$mainMod, 7, workspace, 7
$mainMod, 8, workspace, 8
$mainMod, 9, workspace, 9
$mainMod, 0, workspace, 10
$mainMod_SHIFT, 1, movetoworkspace, 1
$mainMod_SHIFT, 2, movetoworkspace, 2
$mainMod_SHIFT, 3, movetoworkspace, 3
$mainMod_SHIFT, 4, movetoworkspace, 4
$mainMod_SHIFT, 5, movetoworkspace, 5
$mainMod_SHIFT, 6, movetoworkspace, 6
$mainMod_SHIFT, 7, movetoworkspace, 7
$mainMod_SHIFT, 8, movetoworkspace, 8
$mainMod_SHIFT, 9, movetoworkspace, 9
$mainMod_SHIFT, 0, movetoworkspace, 10
# Cycle workspaces
$mainMod, mouse_down, workspace, e+1
$mainMod, mouse_up, workspace, e-1
# Mouse drag
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow
#########################
# Audio (pamixer)
#########################
, XF86AudioRaiseVolume, exec, pamixer -i 5
, XF86AudioLowerVolume, exec, pamixer -d 5
, XF86AudioMute, exec, pamixer -t
, XF86AudioMicMute, exec, pamixer --default-source -t
#########################
# Media (playerctl)
#########################
, XF86AudioPlay, exec, playerctl play-pause
, XF86AudioPause, exec, playerctl pause
, XF86AudioNext, exec, playerctl next
, XF86AudioPrev, exec, playerctl previous
, XF86AudioStop, exec, playerctl stop
#########################
# Brightness (brightnessctl)
#########################
, XF86MonBrightnessUp, exec, brightnessctl set +10%
, XF86MonBrightnessDown, exec, brightnessctl set 10%-
, XF86KbdBrightnessUp, exec, brightnessctl -d '*kbd_backlight*' set +10%
, XF86KbdBrightnessDown, exec, brightnessctl -d '*kbd_backlight*' set 10%-
#########################
# Power / session
#########################
, XF86Sleep, exec, systemctl suspend
, XF86PowerOff, exec, systemctl poweroff
, XF86WakeUp, exec, systemctl suspend
#########################
# Start apps
#########################
$mainMod, E, exec, dolphin
CTRLALT, B, exec, flatpak run eu.betterbird.Betterbird
CTRLALT, S, exec, spotify
CTRLALT, z, exec, flatpak run app.zen_browser.zen
@@ -0,0 +1,58 @@
# --- Variables ---
$mod = SUPER
$term = kitty
$menu = hyprshell run
# --- Environment ---
env = XDG_CURRENT_DESKTOP,Hyprland
env = XDG_SESSION_TYPE,wayland
env = XDG_SESSION_DESKTOP,Hyprland
env = MOZ_ENABLE_WAYLAND,1
# --- Monitor (safe default) ---
monitor = , preferred, auto, 1
# --- Input ---
input {
kb_layout = us
follow_mouse = 1
touchpad {
natural_scroll = true
}
}
# --- General ---
general {
gaps_in = 5
gaps_out = 10
border_size = 2
layout = dwindle
}
animations {
enabled = true
}
decoration {
blur {
enabled = true
size = 8
passes = 2
new_optimizations = true
}
}
misc {
disable_hyprland_logo = false
disable_splash_rendering = false
}
# --- Keybindings live here ---
source = /etc/xdg/hypr/bindings.conf
# --- Autostart ---
exec-once = waybar
#exec-once = sleep 2 & /run/current-system/sw/bin/hyprshell run
@@ -0,0 +1,61 @@
# =========================
# Hyprland config (generated by Nix)
# =========================
# --- Variables ---
$mod = SUPER
$term = kitty
$menu = hyprshell run
# --- Environment ---
env = XDG_CURRENT_DESKTOP,Hyprland
env = XDG_SESSION_TYPE,wayland
env = XDG_SESSION_DESKTOP,Hyprland
env = MOZ_ENABLE_WAYLAND,1
# --- Monitor (safe default) ---
monitor = , preferred, auto, 1
# --- Input ---
input {
kb_layout = us
follow_mouse = 1
touchpad {
natural_scroll = true
}
}
# --- General ---
general {
gaps_in = 5
gaps_out = 10
border_size = 2
layout = dwindle
}
animations {
enabled = true
}
decoration {
blur {
enabled = false
size = 8
passes = 2
new_optimizations = true
}
}
misc {
disable_hyprland_logo = false
disable_splash_rendering = false
}
# --- Keybindings live here ---
source = /etc/xdg/hypr/bindings.conf
# --- Autostart ---
exec-once = waybar
#exec-once = sleep 2 & /run/current-system/sw/bin/hyprshell run
@@ -0,0 +1,4 @@
Host *
AddKeysToAgent yes
ServerAliveInterval 30
ServerAliveCountMax 3
@@ -0,0 +1,17 @@
alias ll='ls -lah'
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias reb-switch='cd ~/nixos && sudo nixos-rebuild switch --flake ~/nixos#traveldroid'
alias reb-test='cd ~/nixos && sudo nixos-rebuild test --flake ~/nixos#traveldroid'
alias reb-vm='cd ~/nixos && sudo nixos-rebuild build-vm --flake ~/nixos#traveldroid && "$(ls -1 ./result/bin/run-*-vm | head -n 1)"'
alias rb='systemctl reboot'
alias po='systemctl poweroff'
alias fpl='flatpak search'
alias fpi='flatpak install'
alias fpr='flatpak run'
alias nxc='ssh henrov@nextcloud.data-pro.nu'
alias nps='xdg-open https://search.nixos.org'
alias vs='code'
alias saveme='sudo nix-env -p /nix/var/nix/profiles/system --set /nix/var/nix/profiles/system-123-link && sudo /nix/var/nix/profiles/system/bin/switch-to-configuration boot'
@@ -0,0 +1,12 @@
# ~/nixos/files/conf/terminal/kitty.conf
# Kitty config (https://sw.kovidgoyal.net/kitty/conf/)
#
# Edit freely; NixOS will inject this file verbatim via programs.kitty.extraConfig.
# Example baseline settings:
background_opacity 0.60
dynamic_background_opacity yes
# Suggested: allow ctrl+shift+v paste (many distros default this already)
map ctrl+shift+v paste_from_clipboard
map ctrl+shift+c copy_to_clipboard
@@ -0,0 +1,279 @@
"$schema" = 'https://starship.rs/config-schema.json'
format = """
[](red)\
$os\
$username\
[](bg:peach fg:red)\
$directory\
[](bg:yellow fg:peach)\
$git_branch\
$git_status\
[](fg:yellow bg:green)\
$c\
$rust\
$golang\
$nodejs\
$php\
$java\
$kotlin\
$haskell\
$python\
[](fg:green bg:sapphire)\
$conda\
[](fg:sapphire bg:lavender)\
$time\
[ ](fg:lavender)\
$cmd_duration\
$line_break\
$character"""
palette = 'catppuccin_mocha'
[os]
disabled = false
style = "bg:red fg:crust"
[os.symbols]
Windows = ""
Ubuntu = "󰕈"
SUSE = ""
Raspbian = "󰐿"
Mint = "󰣭"
Macos = "󰀵"
Manjaro = ""
Linux = "󰌽"
Gentoo = "󰣨"
Fedora = "󰣛"
Alpine = ""
Amazon = ""
Android = ""
AOSC = ""
Arch = "󰣇"
Artix = "󰣇"
CentOS = ""
Debian = "󰣚"
Redhat = "󱄛"
RedHatEnterprise = "󱄛"
[username]
show_always = true
style_user = "bg:red fg:crust"
style_root = "bg:red fg:crust"
format = '[ $user]($style)'
[directory]
style = "bg:peach fg:crust"
format = "[ $path ]($style)"
truncation_length = 3
truncation_symbol = "…/"
[directory.substitutions]
"Documents" = "󰈙 "
"Downloads" = " "
"Music" = "󰝚 "
"Pictures" = " "
"Developer" = "󰲋 "
[git_branch]
symbol = ""
style = "bg:yellow"
format = '[[ $symbol $branch ](fg:crust bg:yellow)]($style)'
[git_status]
style = "bg:yellow"
format = '[[($all_status$ahead_behind )](fg:crust bg:yellow)]($style)'
[nodejs]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[c]
symbol = " "
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[rust]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[golang]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[php]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[java]
symbol = " "
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[kotlin]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[haskell]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version) ](fg:crust bg:green)]($style)'
[python]
symbol = ""
style = "bg:green"
format = '[[ $symbol( $version)(\(#$virtualenv\)) ](fg:crust bg:green)]($style)'
[docker_context]
symbol = ""
style = "bg:sapphire"
format = '[[ $symbol( $context) ](fg:crust bg:sapphire)]($style)'
[conda]
symbol = "  "
style = "fg:crust bg:sapphire"
format = '[$symbol$environment ]($style)'
ignore_base = false
[time]
disabled = false
time_format = "%R"
style = "bg:lavender"
format = '[[  $time ](fg:crust bg:lavender)]($style)'
[line_break]
disabled = false
[character]
disabled = false
success_symbol = '[](bold fg:green)'
error_symbol = '[](bold fg:red)'
vimcmd_symbol = '[](bold fg:green)'
vimcmd_replace_one_symbol = '[](bold fg:lavender)'
vimcmd_replace_symbol = '[](bold fg:lavender)'
vimcmd_visual_symbol = '[](bold fg:yellow)'
[cmd_duration]
show_milliseconds = true
format = " in $duration "
style = "bg:lavender"
disabled = false
show_notifications = true
min_time_to_notify = 45000
[palettes.catppuccin_mocha]
rosewater = "#f5e0dc"
flamingo = "#f2cdcd"
pink = "#f5c2e7"
mauve = "#cba6f7"
red = "#f38ba8"
maroon = "#eba0ac"
peach = "#fab387"
yellow = "#f9e2af"
green = "#a6e3a1"
teal = "#94e2d5"
sky = "#89dceb"
sapphire = "#74c7ec"
blue = "#89b4fa"
lavender = "#b4befe"
text = "#cdd6f4"
subtext1 = "#bac2de"
subtext0 = "#a6adc8"
overlay2 = "#9399b2"
overlay1 = "#7f849c"
overlay0 = "#6c7086"
surface2 = "#585b70"
surface1 = "#45475a"
surface0 = "#313244"
base = "#1e1e2e"
mantle = "#181825"
crust = "#11111b"
[palettes.catppuccin_frappe]
rosewater = "#f2d5cf"
flamingo = "#eebebe"
pink = "#f4b8e4"
mauve = "#ca9ee6"
red = "#e78284"
maroon = "#ea999c"
peach = "#ef9f76"
yellow = "#e5c890"
green = "#a6d189"
teal = "#81c8be"
sky = "#99d1db"
sapphire = "#85c1dc"
blue = "#8caaee"
lavender = "#babbf1"
text = "#c6d0f5"
subtext1 = "#b5bfe2"
subtext0 = "#a5adce"
overlay2 = "#949cbb"
overlay1 = "#838ba7"
overlay0 = "#737994"
surface2 = "#626880"
surface1 = "#51576d"
surface0 = "#414559"
base = "#303446"
mantle = "#292c3c"
crust = "#232634"
[palettes.catppuccin_latte]
rosewater = "#dc8a78"
flamingo = "#dd7878"
pink = "#ea76cb"
mauve = "#8839ef"
red = "#d20f39"
maroon = "#e64553"
peach = "#fe640b"
yellow = "#df8e1d"
green = "#40a02b"
teal = "#179299"
sky = "#04a5e5"
sapphire = "#209fb5"
blue = "#1e66f5"
lavender = "#7287fd"
text = "#4c4f69"
subtext1 = "#5c5f77"
subtext0 = "#6c6f85"
overlay2 = "#7c7f93"
overlay1 = "#8c8fa1"
overlay0 = "#9ca0b0"
surface2 = "#acb0be"
surface1 = "#bcc0cc"
surface0 = "#ccd0da"
base = "#eff1f5"
mantle = "#e6e9ef"
crust = "#dce0e8"
[palettes.catppuccin_macchiato]
rosewater = "#f4dbd6"
flamingo = "#f0c6c6"
pink = "#f5bde6"
mauve = "#c6a0f6"
red = "#ed8796"
maroon = "#ee99a0"
peach = "#f5a97f"
yellow = "#eed49f"
green = "#a6da95"
teal = "#8bd5ca"
sky = "#91d7e3"
sapphire = "#7dc4e4"
blue = "#8aadf4"
lavender = "#b7bdf8"
text = "#cad3f5"
subtext1 = "#b8c0e0"
subtext0 = "#a5adcb"
overlay2 = "#939ab7"
overlay1 = "#8087a2"
overlay0 = "#6e738d"
surface2 = "#5b6078"
surface1 = "#494d64"
surface0 = "#363a4f"
base = "#24273a"
mantle = "#1e2030"
crust = "#181926"
@@ -0,0 +1,14 @@
# ~/nixos/files/conf/terminal/zsh.conf
# Additional zsh configuration sourced for every interactive zsh shell.
# Keep this file POSIX-ish; it is sourced by zsh.
# Example: history settings
HISTFILE="$HOME/.zsh_history"
HISTSIZE=10000
SAVEHIST=10000
setopt HIST_IGNORE_ALL_DUPS
setopt SHARE_HISTORY
# Example: enable starship if you ever disable the zsh integration module
# eval "$(starship init zsh)"
@@ -0,0 +1,8 @@
# transition type: fade, wipe, simple, any, etc.
TRANSITION_TYPE=fade
# duration in seconds (can be decimal)
TRANSITION_DURATION=2
# frames per second
TRANSITION_FPS=60
# override source dir if you ever move it
# SRC_DIR=~/nixos/files/wallpapers/picture
Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

+48
View File
@@ -0,0 +1,48 @@
{
"nodes": {
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1770915843,
"narHash": "sha256-ZwU5wXKNqpOQvjNz6aBp1j5peiBZow1++6pLnk5VAhs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "6a1f7101d2c3ee87d485a87880d73b4665c6a4bd",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1770562336,
"narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d6c71932130818840fc8fe9509cf50be8c64634f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"home-manager": "home-manager",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
+65
View File
@@ -0,0 +1,65 @@
{
description = "NixOS baseline everywhere + per-host exceptions + HM deviations";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager, ... }:
let
lib = nixpkgs.lib;
# Helper: make a NixOS system for a host
mkHost =
{ hostname
, system ? "x86_64-linux"
, username ? "henrov"
}:
lib.nixosSystem {
inherit system;
modules = [
# --- Host entrypoint ---
./hosts/${hostname}/configuration.nix
# --- Shared baseline for ALL machines ---
./modules/nixos/base.nix
# --- Home Manager as a NixOS module ---
home-manager.nixosModules.home-manager
# --- HM integration settings ---
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
# Your user HM entrypoint
home-manager.users.${username} = import ./home/${username}/home.nix;
}
];
specialArgs = {
inherit self hostname username;
};
};
in
{
nixosConfigurations = {
traveldroid = mkHost {
hostname = "traveldroid";
system = "x86_64-linux";
username = "henrov";
};
# Add more hosts like this:
# workstation = mkHost { hostname = "workstation"; system = "x86_64-linux"; username = "henrov"; };
# laptop = mkHost { hostname = "laptop"; system = "x86_64-linux"; username = "henrov"; };
};
};
}
+17
View File
@@ -0,0 +1,17 @@
{ config, pkgs, lib, ... }:
{
imports = [
../../modules/home-manager/base.nix
];
home.username = "henrov";
home.homeDirectory = "/home/henrov";
# Required by Home Manager. Pick the version you first started using HM with.
# If unsure: use the current stable release version you're targeting.
home.stateVersion = "25.11";
# Let Home Manager manage itself.
programs.home-manager.enable = true;
}
@@ -0,0 +1,33 @@
{ config, pkgs, lib, ... }:
{
imports = [
../../modules/nixos/base.nix
./hardware-configuration.nix
./graphics-effects.nix
./hardware.nix
./disk.nix
];
# Bootloader
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
system.stateVersion = "25.11";
# Basic system identity / networking
networking.hostName = "traveldroid";
# Keyboard (Xwayland / X11 apps)
services.xserver.xkb = {
layout = "us";
variant = "";
};
networking.networkmanager.enable = false;
systemd.services."NetworkManager-wait-online".enable = false;
# Enable flakes
nix.settings.experimental-features = [ "nix-command" "flakes" ];
}
@@ -0,0 +1 @@
{ ... }: { }
@@ -0,0 +1,87 @@
{ config, lib, pkgs, ... }:
# ====================== WALLPAPER=========================
let
# Source of wallpapers in your repo (as you specified)
srcDir = "~/nixos/files/wallpapers/picture";
# Note: this is interpreted as a shell-style KEY=VALUE file.
confFile = "~/nixos/files/conf/wallpaper/wallpaper.conf";
setWallpaperScript = pkgs.writeShellScript "set-hourly-wallpaper" ''
set -euo pipefail
# --- Defaults (can be overridden by wallpaper.conf) ---
TRANSITION_TYPE="fade" # e.g. fade, wipe, simple, any
TRANSITION_DURATION="2" # seconds (can be decimals)
TRANSITION_FPS="60" # frames per second
SRC_DIR="${srcDir}"
# Load overrides (shell KEY=VALUE)
if [ -f "${confFile}" ]; then
# shellcheck disable=SC1090
. "${confFile}"
fi
DEST_DIR="$HOME/Pictures/Wallpapers"
mkdir -p "$DEST_DIR"
# Copy source wallpapers into user's Pictures/Wallpapers
# -r recursive, -u update if newer
# If the folder is empty or missing, don't crash the session.
if [ -d "$SRC_DIR" ]; then
cp -ru "$SRC_DIR"/. "$DEST_DIR"/ 2>/dev/null || true
fi
# Pick a random image from DEST_DIR
img="$(
find "$DEST_DIR" -type f \
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) \
| shuf -n 1
)"
[ -n "''${img:-}" ] || exit 0
# Ensure swww daemon is running (per-user)
if ! ${pkgs.swww}/bin/swww query >/dev/null 2>&1; then
${pkgs.swww}/bin/swww-daemon >/dev/null 2>&1 &
sleep 0.4
fi
# Smooth transition wallpaper set
exec ${pkgs.swww}/bin/swww img "$img" \
--transition-type "''${TRANSITION_TYPE}" \
--transition-duration "''${TRANSITION_DURATION}" \
--transition-fps "''${TRANSITION_FPS}"
'';
in
{
# Packages needed by the script + swww
environment.systemPackages = with pkgs; [
swww
bash
coreutils
findutils
util-linux
];
# Run for ANY logged-in user via systemd user units
# (each user session has its own systemd --user instance)
systemd.user.services.wallpaper-rotate = {
description = "Copy wallpapers to ~/Pictures/Wallpapers and set a random wallpaper with transition";
serviceConfig = {
Type = "oneshot";
ExecStart = "${setWallpaperScript}";
};
};
systemd.user.timers.wallpaper-rotate = {
description = "Hourly wallpaper rotation timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "2min";
OnUnitActiveSec = "1h";
RandomizedDelaySec = "5min";
Unit = "wallpaper-rotate.service";
};
};
}
@@ -0,0 +1,40 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/f08fc2a7-0b2b-4cbb-a65a-8b6e7ee4cec9";
fsType = "btrfs";
options = [ "subvol=@" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/f08fc2a7-0b2b-4cbb-a65a-8b6e7ee4cec9";
fsType = "btrfs";
options = [ "subvol=@home" ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/25C1-E4F2";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
swapDevices =
[ { device = "/dev/disk/by-uuid/f771a317-26a2-4524-a458-42ba22b29e67"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
@@ -0,0 +1 @@
{ ... }: { }
@@ -0,0 +1,226 @@
{ config, pkgs, lib, ... }:
let
cfg = config.dataPro.wallpaper; # custom namespace
# Where we keep a runtime-editable config for the user.
runtimeConfDir = "${config.xdg.configHome}/wallpaper";
runtimeConfPath = "${runtimeConfDir}/wallpaper.conf";
rotateScript = pkgs.writeShellScript "wallpaper-rotate" ''
set -euo pipefail
export PATH=${lib.makeBinPath [
pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gawk
pkgs.util-linux
pkgs.swww
]}
# Defaults (can be overridden by wallpaper.conf)
SOURCE_DIR="${cfg.sourceDir}"
TARGET_DIR="${cfg.targetDir}"
ROTATION_DIR="${cfg.rotationDir}"
TRANSITION_TYPE="fade"
TRANSITION_DURATION="2.5"
TRANSITION_FPS="60"
PICK_MODE="random" # random | sequential
LAST_FILE="${config.xdg.stateHome}/wallpaper/last.txt"
# Load user config if present (KEY=VALUE lines; '#' comments allowed)
if [ -f "${runtimeConfPath}" ]; then
# shellcheck disable=SC1090
. "${runtimeConfPath}"
fi
mkdir -p "$TARGET_DIR" "${config.xdg.stateHome}/wallpaper"
# Ensure swww-daemon is running
if ! pgrep -x swww-daemon >/dev/null 2>&1; then
swww-daemon >/dev/null 2>&1 &
sleep 0.3
fi
# Pick image
if [ ! -d "$ROTATION_DIR" ]; then
echo "Rotation directory does not exist: $ROTATION_DIR" >&2
exit 0
fi
# Build list once per run
mapfile -d '' -t imgs < <(
find "$ROTATION_DIR" -type f \
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) \
-print0
)
if [ "${#imgs[@]}" -eq 0 ]; then
echo "No images found in: $ROTATION_DIR" >&2
exit 0
fi
img=""
if [ "$PICK_MODE" = "sequential" ]; then
last=""
if [ -f "$LAST_FILE" ]; then
last="$(cat "$LAST_FILE" || true)"
fi
# Sort for stable order
IFS=$'\n' sorted=($(printf '%s\n' "${imgs[@]}" | sort))
unset IFS
# Find next after last
next=""
found_last=0
for f in "${sorted[@]}"; do
if [ "$found_last" -eq 1 ]; then
next="$f"
break
fi
if [ "$f" = "$last" ]; then
found_last=1
fi
done
if [ -z "$next" ]; then
next="${sorted[0]}"
fi
img="$next"
printf '%s' "$img" > "$LAST_FILE"
else
# random
img="$(printf '%s\0' "${imgs[@]}" | shuf -z -n 1 | tr -d '\0')"
fi
# Smooth transition wallpaper set
swww img "$img" \
--transition-type "$TRANSITION_TYPE" \
--transition-duration "$TRANSITION_DURATION" \
--transition-fps "$TRANSITION_FPS"
'';
in
{
options.dataPro.wallpaper = {
enable = lib.mkEnableOption "Hourly wallpaper rotation with swww (Hyprland/Wayland)";
# You asked to make this easy to change:
sourceDir = lib.mkOption {
type = lib.types.str;
default = "${config.home.homeDirectory}/nixos/files/wallpaper/picture";
description = "Folder containing wallpapers to rotate (source of truth).";
};
targetDir = lib.mkOption {
type = lib.types.str;
default = "${config.home.homeDirectory}/wallpaper";
description = "Folder in the user's home where wallpapers are copied to.";
};
rotationDir = lib.mkOption {
type = lib.types.str;
default = "${config.home.homeDirectory}/wallpaper/picture";
description = "Folder used by the rotator to pick wallpapers from (usually inside targetDir).";
};
};
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.swww
pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gawk
pkgs.util-linux
];
# Copy wallpapers from sourceDir into rotationDir (real copy) at activation.
home.activation.wallpaperCopy = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -euo pipefail
mkdir -p "${cfg.targetDir}" "${cfg.rotationDir}"
if [ -d "${cfg.sourceDir}" ]; then
# Copy source into rotationDir (contents only).
cp -a "${cfg.sourceDir}/." "${cfg.rotationDir}/"
fi
'';
# Install a runtime-editable config into ~/.config/wallpaper/wallpaper.conf
# First-time copy from repo if present; then never overwrite if user edited it.
home.activation.wallpaperConf = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -euo pipefail
mkdir -p "${runtimeConfDir}"
if [ ! -f "${runtimeConfPath}" ]; then
if [ -f "${config.home.homeDirectory}/nixos/files/conf/wallpaper/wallpaper.conf" ]; then
cp -a "${config.home.homeDirectory}/nixos/files/conf/wallpaper/wallpaper.conf" "${runtimeConfPath}"
else
cat > "${runtimeConfPath}" <<'EOF'
# wallpaper.conf — runtime settings for the wallpaper rotator (swww)
# Lines are KEY=VALUE. '#' starts a comment.
# Folder to copy wallpapers from (source of truth)
#SOURCE_DIR="$HOME/nixos/files/wallpaper/picture"
# Where wallpapers are copied to (a folder in your home)
#TARGET_DIR="$HOME/wallpaper"
# Folder used for rotation (where images are selected from)
#ROTATION_DIR="$HOME/wallpaper/picture"
# random | sequential
#PICK_MODE="random"
# swww transition settings
#TRANSITION_TYPE="fade"
#TRANSITION_DURATION="2.5"
#TRANSITION_FPS="60"
EOF
fi
fi
'';
# Start swww daemon on graphical session start
systemd.user.services.swww-daemon = {
Unit = {
Description = "swww wallpaper daemon";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${pkgs.swww}/bin/swww-daemon";
Restart = "on-failure";
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
};
# Rotate wallpaper hourly
systemd.user.services.wallpaper-rotate = {
Unit = {
Description = "Rotate wallpaper (hourly)";
After = [ "swww-daemon.service" ];
};
Service = {
Type = "oneshot";
ExecStart = "${rotateScript}";
};
};
systemd.user.timers.wallpaper-rotate = {
Unit = {
Description = "Hourly wallpaper rotation timer";
};
Timer = {
OnBootSec = "2m";
OnUnitActiveSec = "1h";
Unit = "wallpaper-rotate.service";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}
@@ -0,0 +1,67 @@
{ config, lib, pkgs, ... }:
let
moduleName = "hm-default-apps";
in
{
# Ensure update-mime-database is available
home.packages = with pkgs; [
shared-mime-info
];
# Teach the MIME DB that *.nix files are text/x-nix
xdg.dataFile."mime/packages/custom-text-types.xml".text = ''
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="text/x-nix">
<comment>Nix expression</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.nix"/>
</mime-type>
<mime-type type="text/x-ini">
<comment>Configuration file</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.conf"/>
</mime-type>
</mime-info>
'';
# Rebuild user MIME database after HM writes xdg.dataFile files
home.activation.updateMimeDatabase =
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
${pkgs.shared-mime-info}/bin/update-mime-database ${config.xdg.dataHome}/mime
'';
xdg.mimeApps.enable = true;
xdg.mimeApps.defaultApplications = {
# Nix files
"text/x-nix" = [ "org.kde.kate.desktop" ];
"text/plain" = [ "org.kde.kate.desktop" ];
"text/x-ini" = [ "org.kde.kate.desktop" ];
"application/x-desktop" = [ "org.kde.kate.desktop" ];
# Zen Browser (Flatpak)
"x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ];
"x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ];
"text/html" = [ "app.zen_browser.zen.desktop" ];
# Email
"x-scheme-handler/mailto" = [ "eu.betterbird.Betterbird.desktop" ];
"message/rfc822" = [ "eu.betterbird.Betterbird.desktop" ];
# Calendar (common handlers)
"text/calendar" = [ "eu.betterbird.Betterbird.desktop" ];
"application/ics" = [ "eu.betterbird.Betterbird.desktop" ];
"application/calendar" = [ "eu.betterbird.Betterbird.desktop" ];
"x-scheme-handler/webcal" = [ "eu.betterbird.Betterbird.desktop" ];
"x-scheme-handler/webcals" = [ "eu.betterbird.Betterbird.desktop" ];
# File manager
"inode/directory" = [ "org.kde.dolphin.desktop" ];
};
home.file.".nixlog/loaded.${moduleName}-module-loaded".text = "loaded\n";
}
@@ -0,0 +1,26 @@
{ config, pkgs, lib, ... }:
{
imports = [
# Shell (deviations)
./shell/zsh.nix
./shell/starship.nix
# Dev (deviations)
./dev/git.nix
./dev/ssh-client.nix
./dev/direnv.nix
# Desktop overrides (deviations)
./desktop/hyprland-overrides.nix
./desktop/waybar-overrides.nix
./desktop/hyprshell.nix
# apps
./apps/default-apps.nix
];
# Home Manager should manage XDG base dirs consistently
xdg.enable = true;
}
@@ -0,0 +1 @@
{ ... }: { }
@@ -0,0 +1,39 @@
{ config, lib, pkgs, ... }:
let
moduleName = "hm-hyprshell";
# Absolute path in your home repo (string is fine here, but we must convert properly)
repoDir = "${config.home.homeDirectory}/nixos/files/conf/hyprshell";
in
{
xdg.enable = true;
# Symlink the whole directory into ~/.config/hyprshell
xdg.configFile."hyprshell" = {
source = config.lib.file.mkOutOfStoreSymlink repoDir;
recursive = true;
};
home.packages = [ pkgs.hyprshell ];
systemd.user.services.hyprshell = {
Unit = {
Description = "Hyprshell";
PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${pkgs.hyprshell}/bin/hyprshell run";
Restart = "on-failure";
RestartSec = 1;
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
};
home.file.".nixlog/loaded.${moduleName}-module-loaded".text = "loaded\n";
}
@@ -0,0 +1 @@
{ ... }: { }
@@ -0,0 +1 @@
{ ... }: { }
@@ -0,0 +1 @@
{ ... }: { }
@@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
let
confDir = "${config.home.homeDirectory}/nixos/files/conf/ssh";
sshClientConf = "${confDir}/ssh-client.conf";
in
{
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks."*" = {
addKeysToAgent = "yes";
serverAliveInterval = 30;
serverAliveCountMax = 3;
};
# Load your extra SSH config from a file in ~/nixos/files/conf/ssh/
extraConfig = ''
Include ${config.home.homeDirectory}/nixos/files/conf/ssh/ssh-client.conf
'';
};
# Home Manager's ssh-agent (NOT programs.ssh.startAgent; that's NixOS)
services.ssh-agent = {
enable = true;
# Optional: if you use zsh, this helps export SSH_AUTH_SOCK in your shell
enableZshIntegration = true;
};
}
@@ -0,0 +1,22 @@
# /home/henrov/nixos/modules/home-manager/shell/starship.nix
#
# Home Manager Starship prompt configuration.
# Configuration is sourced from: ~/nixos/files/conf/terminal/starship.toml
{ config, lib, pkgs, ... }:
let
# From: nixos/modules/home-manager/shell -> nixos/files/conf/terminal
confDir = ../../../files/conf/terminal;
in
{
programs.starship = {
enable = true;
# Let Starship hook into shells managed by Home Manager.
enableZshIntegration = true;
enableBashIntegration = true;
settings = builtins.fromTOML (builtins.readFile (confDir + "/starship.toml"));
};
}
@@ -0,0 +1,41 @@
# /home/henrov/nixos/modules/home-manager/shell/zsh.nix
#
# Home Manager Zsh + Kitty baseline.
# Configuration is sourced from:
# ~/nixos/files/conf/terminal/aliases.conf
# ~/nixos/files/conf/terminal/zsh.conf
# ~/nixos/files/conf/terminal/kitty.conf
{ config, lib, pkgs, ... }:
let
# From: nixos/modules/home-manager/shell -> nixos/files/conf/terminal
confDir = ../../../files/conf/terminal;
in
{
home.packages = with pkgs; [
kitty
];
programs.zsh = {
enable = true;
enableCompletion = true;
dotDir = config.home.homeDirectory;
# Load shared, editable snippets.
initContent = ''
# Shared aliases
if [ -f "${confDir}/aliases.conf" ]; then
source "${confDir}/aliases.conf"
fi
# Shared zsh config snippets
if [ -f "${confDir}/zsh.conf" ]; then
source "${confDir}/zsh.conf"
fi
'';
};
programs.kitty.enable = true;
xdg.configFile."kitty/kitty.conf".source = confDir + "/kitty.conf";
}
@@ -0,0 +1,81 @@
{ config, pkgs, lib, ... }:
let
# Adjust this path if your module lives elsewhere in the repo
flatpakConfPath = ../../../files/conf/apps/flatpak.conf;
# Parse flatpak.conf: ignore empty lines and comments
flatpakApps =
let
lines = lib.splitString "\n" (builtins.readFile flatpakConfPath);
cleaned = map (l: lib.strings.trim l) lines;
in
builtins.filter (l: l != "" && !(lib.hasPrefix "#" l)) cleaned;
# Shell script that:
# - adds Flathub if missing
# - installs missing apps
# - (optional) removes apps not in the list
syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" ''
set -euo pipefail
# Ensure Flathub remote exists (system-wide)
if ! flatpak remotes --system --columns=name | grep -qx flathub; then
flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
fi
desired_apps=(
${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)}
)
# Install desired apps if missing
for app in "''${desired_apps[@]}"; do
if ! flatpak info --system "$app" >/dev/null 2>&1; then
flatpak install --system -y --noninteractive flathub "$app"
fi
done
# OPTIONAL: remove system apps not listed (uncomment to enforce strictly)
# installed="$(flatpak list --system --app --columns=application | sed '/^$/d')"
# for app in $installed; do
# keep=0
# for want in "''${desired_apps[@]}"; do
# if [ "$app" = "$want" ]; then keep=1; break; fi
# done
# if [ "$keep" -eq 0 ]; then
# flatpak uninstall --system -y --noninteractive "$app" || true
# fi
# done
'';
in
{
# Native NixOS Flatpak support
services.flatpak.enable = true; # enables Flatpak on NixOS :contentReference[oaicite:1]{index=1}
# Strongly recommended for Flatpak desktop integration
# (Adjust portals to your DE/WM if you want, this is a safe default.)
xdg.portal = {
enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
# Ensure the config file is present on the system (optional but convenient)
environment.etc."flatpak/flatpak.conf".source = flatpakConfPath;
# Run sync after boot and after rebuilds, once networking is up
systemd.services.flatpak-sync = {
description = "Install Flatpak apps listed in flatpak.conf";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = syncFlatpaks;
};
# Re-run when the config changes (best-effort)
restartTriggers = [ flatpakConfPath ];
path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ];
};
}
@@ -0,0 +1,41 @@
{ lib, pkgs, ... }:
let
# Adjust this path if you place apps.nix elsewhere in the repo.
# Best practice: keep it relative to the flake repo so flakes can read it.
packagesConfPath = ../../../files/conf/apps/packages.conf;
raw = builtins.readFile packagesConfPath;
# Split into lines, trim whitespace, drop empty lines and comment lines.
lines =
let
all = lib.splitString "\n" raw;
trimmed = map lib.strings.trim all;
in
builtins.filter (l: l != "" && !(lib.hasPrefix "#" l)) trimmed;
# Resolve a name like:
# "wget" -> pkgs.wget
# "kdePackages.okular" -> pkgs.kdePackages.okular
# "_1password-gui" -> pkgs."_1password-gui"
resolvePkg = name:
let
parts = lib.splitString "." name;
found = lib.attrByPath parts null pkgs;
in
if found == null then
throw ''
apps.nix: Package "${name}" from ${toString packagesConfPath} not found in pkgs.
Only packages available on https://search.nixos.org/packages can be installed.
Fix the name (or attribute path) and rebuild.
''
else
found;
packages = map resolvePkg lines;
in
{
environment.systemPackages = packages;
}
@@ -0,0 +1,56 @@
# ~/nixos/modules/nixos/base.nix
#
# Shared baseline for ALL hosts.
# Keep this predictable: explicit imports (no auto-import).
# Host-specific exceptions belong in hosts/<host>/*.nix
#
{ config, pkgs, lib, ... }:
let
moduleName = "nixos-base";
in
{
imports = [
# Core system baseline
./core/nix.nix
./core/locale.nix
./core/users.nix
./core/security.nix
./core/fonts.nix
# Networking baseline
./networking/networkmanager.nix
./networking/firewall.nix
# Desktop baseline (Wayland/Hyprland)
./desktop/audio.nix
./desktop/portals.nix
./desktop/wm-hyprland.nix
./desktop/greeter.nix
# Apps baseline
./apps/flatpak.nix
./apps/packages.nix
# Services baseline
./services/sshd.nix
./services/printing.nix
#./services/syncthing.nix
];
desktop.greeter.enable = true;
#make sure existing files can be overwritten
home-manager.backupFileExtension = "hm-bak";
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,33 @@
# Baseline fonts for the system (NixOS 25.05+ / 26.05 compatible)
#
# Note:
# - `noto-fonts-cjk` was deprecated/split into:
# - noto-fonts-cjk-sans
# - noto-fonts-cjk-serif
{ config, lib, pkgs, ... }:
let
moduleName = "nixos-fonts";
has = name: builtins.hasAttr name pkgs;
in
{
fonts = {
# Keep your existing setup idea: install baseline font packages system-wide
packages =
(with pkgs; [
noto-fonts
noto-fonts-color-emoji
])
# CJK split (new)
++ lib.optionals (has "noto-fonts-cjk-sans") [ pkgs.noto-fonts-cjk-sans ]
++ lib.optionals (has "noto-fonts-cjk-serif") [ pkgs.noto-fonts-cjk-serif ];
# Optional: common baseline toggle (leave as-is if you already set it elsewhere)
# enableDefaultPackages = lib.mkDefault true;
};
# Breadcrumb for debugging
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,10 @@
{ config, pkgs, lib, ... }:
let
moduleName = "nixos-locale";
in
{
time.timeZone = "Europe/Amsterdam";
i18n.defaultLocale = "en_US.UTF-8";
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,54 @@
# ~/nixos/modules/nixos/core/nix.nix
#
# Purpose:
# - Shared baseline Nix configuration for ALL hosts
# - Flakes enabled
# - Reasonable garbage collection defaults
# - Allow unfree packages (needed for Brave/Vivaldi/Opera etc.)
{ config, lib, pkgs, ... }:
let
moduleName = "nixos-core-nix";
in
{
# Required for Brave/Vivaldi/Opera and other proprietary software.
nixpkgs.config.allowUnfree = true;
nix = {
# Enable flakes + nix-command everywhere (baseline)
settings.experimental-features = [ "nix-command" "flakes" ];
# Why:
# - Keeps the store from growing forever
# - Still allows rollbacks for a while
settings.auto-optimise-store = true;
# Reasonable default: allow Nix to use all CPU cores
settings.max-jobs = lib.mkDefault "auto";
};
# Automatic cleanup of old generations and store garbage
#
# Why:
# - On multi-machine setups, store growth is one of the main annoyances.
# - This is safe and keeps machines tidy.
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 14d";
};
# Keep a limited number of boot entries / system generations
#
# Why:
# - Still safe for rollbacks
# - Prevents /boot from filling up on some setups
boot.loader.systemd-boot.configurationLimit = lib.mkDefault 10;
nix.settings.download-buffer-size = 67108864;
# Optional: breadcrumb for debugging module load order
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,39 @@
# ~/nixos/modules/nixos/core/security.nix
#
# Purpose:
# - Security primitives that are shared across all hosts:
# - polkit (desktop authorization framework)
# - sudo baseline (privilege escalation)
#
# Keep this file conservative: it should not introduce host-specific behavior.
{ config, lib, pkgs, ... }:
{
# Polkit is commonly needed on desktop systems (including Wayland compositors)
# for privileged actions (network, power, mounting, etc.).
security.polkit.enable = true;
# Sudo baseline.
security.sudo = {
enable = true;
# Hardening: only wheel members can *execute* sudo at all.
# This reduces exposure if a non-wheel user exists.
execWheelOnly = true;
# Keep password requirement (safer baseline).
# If you want passwordless sudo for wheel, override elsewhere.
wheelNeedsPassword = true;
# Optional: sane defaults; adjust as you like.
extraConfig = ''
Defaults timestamp_timeout=5
Defaults pwfeedback
'';
};
# If you want to fully manage users declaratively (stronger security posture),
# you can enable this — but it can surprise you if you expect to use `passwd`.
# users.mutableUsers = false;
}
@@ -0,0 +1,29 @@
{ config, pkgs, lib, ... }:
let
username = "henrov";
initialpwd= "Welkom01!";
moduleName = "nixos-users";
in
{
users.users.${username} = {
#initialPassword = initialpwd;
isNormalUser = true;
# Add your user to groups needed for admin + network + typical desktop input/video access
extraGroups = [
"wheel"
"networkmanager"
"video"
"input"
"audio"
];
# If you want zsh explicitly per-user (instead of defaultUserShell):
# shell = pkgs.zsh;
};
# If you want a simple "proof this module was applied" marker at the *system* level:
# (This creates /etc/nixos-users.loaded)
environment.etc."nixos-users.loaded".text = "loaded\n";
}
@@ -0,0 +1,60 @@
# ~/nixos/modules/nixos/desktop/audio.nix
#
# Baseline audio stack:
# - PipeWire as the audio server
# - PulseAudio compatibility via pipewire-pulse
# - ALSA compatibility (+ 32-bit ALSA for games/legacy)
# - WirePlumber session manager
# - RTKit for better realtime scheduling (often reduces crackling under load)
#
# IMPORTANT (NixOS option churn):
# - On some nixpkgs revisions the old `hardware.pulseaudio` option was renamed to
# `services.pulseaudio`. We set the *services* one explicitly.
# - Avoid `lib.mkForce` on pulseaudio enable/disable here because certain revisions
# have had type/override weirdness; use plain booleans instead.
{ config, lib, pkgs, ... }:
let
moduleName = "nixos-audio";
in
{
# ---- Disable the standalone PulseAudio daemon ----
#
# We want PipeWire to provide PulseAudio compatibility (pipewire-pulse),
# not a separate pulseaudio service.
services.pulseaudio.enable = false;
# ---- PipeWire ----
services.pipewire = {
enable = true;
# PulseAudio compatibility server (pipewire-pulse)
pulse.enable = true;
# ALSA compatibility (+ 32-bit for Steam/older apps)
alsa = {
enable = true;
support32Bit = true;
};
# Recommended policy/session manager
wireplumber.enable = true;
# Optional JACK compatibility (leave off unless you need it)
jack.enable = false;
};
# Realtime scheduling broker commonly used by PipeWire
security.rtkit.enable = true;
# Useful tooling
environment.systemPackages = with pkgs; [
pavucontrol
helvum
alsa-utils
];
# Breadcrumb for debugging module load order
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,91 @@
{ config, pkgs, lib, ... }:
let
cfg = config.desktop.greeter;
in
{
options.desktop.greeter = {
enable = lib.mkEnableOption "greetd + tuigreet greeter (starts Hyprland)";
greeterConfSource = lib.mkOption {
type = lib.types.path;
default = ../../../files/conf/greeter/greeter.conf;
description = "Path to greeter.conf in your repo; will be installed to /etc/xdg/greeter/greeter.conf";
};
vt = lib.mkOption {
type = lib.types.int;
default = 1;
description = "Virtual terminal (VT) greetd runs on (typically 1).";
};
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "--time" "--remember" "--remember-session" "--asterisks" ];
description = "Extra command-line arguments passed to tuigreet.";
};
useDbusRunSession = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Wrap Hyprland with dbus-run-session (often helps session env).";
};
installGreeterPackages = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Add tuigreet (and optional qtgreet) to systemPackages.";
};
enableTty1Fix = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Ensure greetd owns tty1 (avoids boot console overriding greetd).";
};
};
config = lib.mkIf cfg.enable {
# greetd + tuigreet configuration
services.greetd = {
enable = true;
settings = {
terminal.vt = cfg.vt;
default_session = {
# greetd service runs the greeter as this user
user = "greetd";
# Build: tuigreet ... --cmd <Hyprland>
command =
let
hyprCmd =
if cfg.useDbusRunSession
then "${pkgs.dbus}/bin/dbus-run-session ${pkgs.hyprland}/bin/Hyprland"
else "${pkgs.hyprland}/bin/Hyprland";
tuigreetArgs = lib.concatStringsSep " " cfg.extraArgs;
in
"${pkgs.tuigreet}/bin/tuigreet ${tuigreetArgs} --cmd ${hyprCmd}";
};
};
};
# Install your custom greeter config into /etc/xdg/greeter/greeter.conf
environment.etc."xdg/greeter/greeter.conf".source = cfg.greeterConfSource;
# Supporting bits (Wayland sessions almost always want these)
services.dbus.enable = lib.mkDefault true;
security.polkit.enable = lib.mkDefault true;
# Optional: keep greeter tools available system-wide
environment.systemPackages = lib.mkIf cfg.installGreeterPackages (with pkgs; [
tuigreet
qtgreet
]);
# Fix "Graphical System started" but no greeter: ensure tty1 isnt stolen by console/getty
boot.kernelParams = lib.mkIf cfg.enableTty1Fix [ "console=tty1" ];
systemd.services."getty@tty1".enable = lib.mkIf cfg.enableTty1Fix false;
systemd.services."autovt@tty1".enable = lib.mkIf cfg.enableTty1Fix false;
};
}
@@ -0,0 +1,67 @@
# Atomic responsibility:
# - System-wide XDG basics
# - System-wide xdg-desktop-portal + chosen backends
# - A sane portals.conf selection (prevents “wrong backend” surprises)
#
# Notes:
# - Keep ALL portal-related config here (do not also configure xdg.portal in wm-hyprland.nix).
# - xdg.portal.config.common sets defaults via portals.conf(5) and is supported by NixOS. :contentReference[oaicite:0]{index=0}
# - If you enable xdg.portal.wlr.enable elsewhere, it auto-adds xdg-desktop-portal-wlr to extraPortals. :contentReference[oaicite:1]{index=1}
# (We do NOT do that here because Hyprland typically uses xdg-desktop-portal-hyprland instead.)
# - xdg-desktop-portal-gtk is commonly needed for OpenURI/FileChooser support. :contentReference[oaicite:2]{index=2}
{ config, lib, pkgs, ... }:
{
##########################################################################
# XDG basics (system)
##########################################################################
xdg = {
menus.enable = true;
mime.enable = true;
};
##########################################################################
# Portals (system)
##########################################################################
xdg.portal = {
enable = true;
# Prefer Hyprland portal for compositor-integrated features (screensharing, etc),
# and GTK for things like OpenURI/FileChooser compatibility.
extraPortals = with pkgs; [
xdg-desktop-portal-hyprland
xdg-desktop-portal-gtk
];
# Explicit portal routing via portals.conf (prevents “random backend chosen” issues).
# This writes /etc/xdg/xdg-desktop-portal/portals.conf. :contentReference[oaicite:3]{index=3}
config.common = {
# Default backend order for interfaces where multiple backends exist.
default = [ "hyprland" "gtk" ];
# (Optional, but often helpful) Ensure GTK handles common UX portals reliably.
"org.freedesktop.impl.portal.FileChooser" = [ "gtk" ];
"org.freedesktop.impl.portal.OpenURI" = [ "gtk" ];
};
};
##########################################################################
# Environment defaults (system)
##########################################################################
environment.sessionVariables = {
# Encourage GTK apps to use portals for file picker / open-uri on Wayland.
GTK_USE_PORTAL = "1";
# Desktop identity hints used by some apps / portal logic.
# (Set once here; dont duplicate in HM and NixOS.)
XDG_CURRENT_DESKTOP = "Hyprland";
XDG_SESSION_DESKTOP = "Hyprland";
};
##########################################################################
# Optional: small, non-invasive tooling for troubleshooting
##########################################################################
environment.systemPackages = with pkgs; lib.mkAfter [
xdg-utils
];
}
@@ -0,0 +1,17 @@
{ config, lib, pkgs, ... }:
let
repoHyprDir = ../../../files/conf/hypr;
in
{
programs.hyprland.enable = true;
services.dbus.enable = lib.mkDefault true;
security.polkit.enable = lib.mkDefault true;
# Publish to XDG config dir so Hyprland finds it
environment.etc."xdg/hypr".source = repoHyprDir;
# Optional breadcrumb
environment.etc."nixlog/loaded.nixos-desktop-wm-hyprland".text = "loaded\n";
}
@@ -0,0 +1,57 @@
{ config, lib, pkgs, ... }:
let
moduleName = "nixos-firewall";
# Why:
# - You had LAN-specific allow rules. Keeping the CIDR as a single variable
# makes it easy to override per-host or per-network later.
#
# If your LAN changes, override this value in hosts/<host>/networking.nix.
homeLanCidr = "192.168.2.0/24";
in
{
# Why:
# - Use nftables backend (modern default direction).
# - Matches your existing config and plays nicely with custom rules.
networking.nftables.enable = true;
networking.firewall = {
enable = true;
# Why:
# - Strong baseline: nothing inbound is open unless explicitly allowed.
# - You then selectively allow what you need (SSH ports live in sshd.nix).
allowedTCPPorts = [ ];
allowedUDPPorts = [ ];
# Why:
# - These are “quality of life” LAN services you had already:
# - KDE Connect: TCP/UDP 1714-1764
# - mDNS: UDP 5353 (printer discovery / Avahi-style discovery)
#
# Notes:
# - These rules ONLY allow traffic originating from homeLanCidr.
# - On other networks they effectively do nothing.
# - If you dont use KDE Connect or mDNS, delete these blocks.
extraInputRules = ''
# KDE Connect (TCP/UDP 1714-1764) from home LAN
ip saddr ${homeLanCidr} tcp dport 1714-1764 accept
ip saddr ${homeLanCidr} udp dport 1714-1764 accept
# mDNS / discovery (UDP 5353) from home LAN
ip saddr ${homeLanCidr} udp dport 5353 accept
'';
# Optional baseline knobs (kept conservative):
#
# Why:
# - Logging refused packets can be noisy on laptops that roam networks.
# - Leave disabled by default; enable temporarily for debugging.
logRefusedConnections = lib.mkDefault false;
};
# Optional: leave a breadcrumb in /etc for debugging module load order
# (handy while refactoring; remove once stable).
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,34 @@
{ config, lib, pkgs, ... }:
{
# Keep NetworkManager off (avoids nm-applet + keyring + agent ecosystem)
networking.networkmanager.enable = false;
# iwd provides Wi-Fi auth/roaming; configurable via networking.wireless.iwd.settings
networking.wireless.iwd = {
enable = true;
# Optional but useful defaults
settings = {
Settings = {
AutoConnect = true;
};
Network = {
EnableIPv6 = true;
};
};
};
# GUI (with tray indicator via `iwgtk -i`)
environment.systemPackages = with pkgs; [
iwd
iwgtk
];
# Allow non-root Wi-Fi control (common pattern for iwd tooling)
users.users.henrov.extraGroups = [ "netdev" ];
# Ensure you still get IP addresses (default on NixOS is usually OK,
# but this makes it explicit)
networking.useDHCP = lib.mkDefault true;
}
@@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
let
moduleName = "nixos-printers";
in
{
# ---- Printing (CUPS) ----
services.printing = {
enable = true;
# Good general compatibility. Many modern printers work driverless (IPP Everywhere),
# but these help with older models and various formats.
drivers = with pkgs; [
cups-filters
gutenprint
];
};
# ---- Network printer discovery (mDNS / DNS-SD) ----
services.avahi = {
enable = true;
# Resolve .local names + discover services on IPv4
nssmdns4 = true;
# You're controlling firewall rules in firewall.nix
openFirewall = false;
};
# ---- Optional GUI tool to add/manage printers ----
environment.systemPackages = with pkgs; [
system-config-printer
];
# allow admin actions in printer GUI (usually already present on desktop systems)
security.polkit.enable = true;
environment.etc."nixlog/loaded.${moduleName}".text = "loaded\n";
}
@@ -0,0 +1,18 @@
# SSH client only (no server).
# - Installs OpenSSH client tools (ssh, scp, sftp, ssh-keygen, etc.)
# - Enables ssh-agent for user sessions
{ config, lib, pkgs, ... }:
{
# Install the OpenSSH client tools
environment.systemPackages = with pkgs; [
#openssh
];
# Start ssh-agent automatically for users (handy baseline)
programs.ssh.startAgent = true;
# Explicitly ensure the SSH server is NOT enabled
services.openssh.enable = false;
}