Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33385d5275 | ||
|
|
19bf815be8 | ||
|
|
0152438472 | ||
|
|
f9b07deb19 | ||
|
|
6e55d375d2 | ||
|
|
0e066cb4d7 | ||
|
|
bd64283f04 | ||
|
|
6025b6c4f1 | ||
|
|
92b04773b2 | ||
|
|
783a7a3390 | ||
|
|
0ef4354c1a | ||
|
|
192a978d46 | ||
|
|
a4519904b6 | ||
|
|
83a6e45bf4 | ||
|
|
2ba6f3466f | ||
|
|
b3f5b4b406 | ||
|
|
2e680f2519 | ||
|
|
445183f826 | ||
|
|
aec980e6fe | ||
|
|
68f732ec4b | ||
|
|
dc382dcfcc | ||
|
|
b1a06034f1 | ||
|
|
aa3e8cc263 | ||
|
|
b680255bc5 | ||
|
|
a3f7af4e39 | ||
|
|
cd5c8a0034 | ||
|
|
1f14f020ed | ||
|
|
05affb6b1f |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,13 +1,10 @@
|
|||||||
hosts/nas/*.conf
|
hosts/nas/*.conf
|
||||||
hosts/nas/*.users
|
hosts/nas/*.users
|
||||||
result*
|
result
|
||||||
*.raw
|
*.raw
|
||||||
.codegpt
|
.codegpt
|
||||||
.direnv
|
.direnv
|
||||||
shell.nix
|
shell.nix
|
||||||
.vscode
|
.vscode
|
||||||
**/*/*.py
|
**/*/*.py
|
||||||
.envrc
|
.envrc
|
||||||
.DS_Store
|
|
||||||
*.qcow2
|
|
||||||
keys
|
|
||||||
33
.sops.yaml
33
.sops.yaml
@@ -1,6 +1,5 @@
|
|||||||
# See https://github.com/Mic92/dotfiles/blob/d6114726d859df36ccaa32891c4963ae5717ef7f/nixos/.sops.yaml
|
# See https://github.com/Mic92/dotfiles/blob/d6114726d859df36ccaa32891c4963ae5717ef7f/nixos/.sops.yaml
|
||||||
keys:
|
keys:
|
||||||
- &matt-pgp CBCB9B18A6B8930B0B6ABFD1CCB8CBEB30633684
|
|
||||||
- &matt age157jemphjzg6zmk373vpccuguyw6e75qnkqmz8pcnn2yue85p939swqqhy0
|
- &matt age157jemphjzg6zmk373vpccuguyw6e75qnkqmz8pcnn2yue85p939swqqhy0
|
||||||
- &matt_pi4 age13g9a4d4jrvckfddpgn8sm4kjtzajr67le56pfdg78ktr5pd09phq32j89u
|
- &matt_pi4 age13g9a4d4jrvckfddpgn8sm4kjtzajr67le56pfdg78ktr5pd09phq32j89u
|
||||||
- &matt_pi5 age1wpvfpv5n32lruk7c0da4uaeapsmhjxdvg8z4ljehn06l6g2y0e0sum404l
|
- &matt_pi5 age1wpvfpv5n32lruk7c0da4uaeapsmhjxdvg8z4ljehn06l6g2y0e0sum404l
|
||||||
@@ -13,14 +12,12 @@ keys:
|
|||||||
- &steamdeck age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
- &steamdeck age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
||||||
- &matt_macbook-pro age19daqsncuzeh3j6cwk8uxp6yfj8h0qtz02jxlwwy4v8j0mfgznsvq30440g
|
- &matt_macbook-pro age19daqsncuzeh3j6cwk8uxp6yfj8h0qtz02jxlwwy4v8j0mfgznsvq30440g
|
||||||
- &macbook-pro age19w4zafpwnq9yhzuf8r5te2yhq7xlqj76rcgzcz935hllyrz4yvws4jn6ca
|
- &macbook-pro age19w4zafpwnq9yhzuf8r5te2yhq7xlqj76rcgzcz935hllyrz4yvws4jn6ca
|
||||||
- &nuc age102el4snus37dj807rwvsmlvwu2sg2d8rw3vfmtntgczfkz04l9nshetcq0
|
- &nuc age1wurzgc20e6ye79wsg85vvqk4aj3mmc0llxshcy9532ex8f4c6dqql76c78
|
||||||
- &admin_nuc age102el4snus37dj807rwvsmlvwu2sg2d8rw3vfmtntgczfkz04l9nshetcq0
|
- &admin_nuc age1luyejgmqjj0esydlr2jxqkg48vexmx57gdz7cy5gq7rz8kf5cups2rnfa9
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *matt_pi4
|
- *matt_pi4
|
||||||
- *matt_pi5
|
- *matt_pi5
|
||||||
@@ -37,27 +34,21 @@ creation_rules:
|
|||||||
- *nuc
|
- *nuc
|
||||||
- path_regex: nas-secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: nas-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *desktop
|
- *desktop
|
||||||
- *admin
|
- *admin
|
||||||
- *jallen-nas
|
- *jallen-nas
|
||||||
- path_regex: desktop-secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: desktop-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *desktop
|
- *desktop
|
||||||
- *admin
|
- *admin
|
||||||
- *jallen-nas
|
- *jallen-nas
|
||||||
- path_regex: steamdeck-secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: steamdeck-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *desktop
|
- *desktop
|
||||||
- *deck
|
- *deck
|
||||||
@@ -66,9 +57,7 @@ creation_rules:
|
|||||||
- *jallen-nas
|
- *jallen-nas
|
||||||
- path_regex: pi4-secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: pi4-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *matt_pi4
|
- *matt_pi4
|
||||||
- *matt_pi5
|
- *matt_pi5
|
||||||
@@ -79,9 +68,7 @@ creation_rules:
|
|||||||
- *jallen-nas
|
- *jallen-nas
|
||||||
- path_regex: pi5-secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: pi5-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *matt_pi4
|
- *matt_pi4
|
||||||
- *matt_pi5
|
- *matt_pi5
|
||||||
@@ -92,9 +79,7 @@ creation_rules:
|
|||||||
- *jallen-nas
|
- *jallen-nas
|
||||||
- path_regex: mac-secrets/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: mac-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- age:
|
||||||
- *matt-pgp
|
|
||||||
age:
|
|
||||||
- *matt
|
- *matt
|
||||||
- *matt_pi5
|
- *matt_pi5
|
||||||
- *desktop
|
- *desktop
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
mount -t tmpfs -o mode=755 none /mnt
|
|
||||||
mkdir -p /mnt/{boot,home,root,etc,nix,var/log}
|
|
||||||
mount /dev/sdb1 /mnt/boot
|
|
||||||
mount /dev/sdb3 -o compress=zstd,subvol=home /mnt/home
|
|
||||||
mount /dev/sdb3 -o compress=zstd,noatime,subvol=root /mnt/root
|
|
||||||
mount /dev/sdb3 -o compress=zstd,noatime,subvol=etc /mnt/etc
|
|
||||||
mount /dev/sdb3 -o compress=zstd,noatime,subvol=nix /mnt/nix
|
|
||||||
mount /dev/sdb3 -o compress=zstd,noatime,subvol=log /mnt/var/log
|
|
||||||
|
|
||||||
wpa_passphrase "Joey's Jungle 5G" "kR8v&3Qd" > 5g.conf
|
|
||||||
wpa_supplicant -i wlp6s0 -c 5g.conf -B
|
|
||||||
dhcpcd
|
|
||||||
|
|
||||||
keyctl link @u @s
|
|
||||||
clevis decrypt < "/etc/clevis/nas_pool.jwe" | bcachefs unlock /dev/disk/by-label/nas_pool
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
let
|
let
|
||||||
inherit (inputs) pre-commit-hooks-nix;
|
inherit (inputs) pre-commit-hooks-nix;
|
||||||
in
|
in
|
||||||
pre-commit-hooks-nix.lib.${pkgs.stdenv.hostPlatform.system}.run {
|
pre-commit-hooks-nix.lib.${pkgs.system}.run {
|
||||||
src = ../..;
|
src = ../..;
|
||||||
hooks = {
|
hooks = {
|
||||||
pre-commit-hook-ensure-sops.enable = true;
|
pre-commit-hook-ensure-sops.enable = true;
|
||||||
|
|||||||
1
echo
1
echo
@@ -1 +0,0 @@
|
|||||||
{"text": "\ue312 49\u00b0F", "tooltip": " Overcast 49\u00b0\n<span foreground=\"#585858\" font-weight=\"bold\"> .--. </span>Feels like: 49\u00b0\n<span foreground=\"#585858\" font-weight=\"bold\"> .-( ). </span>Wind: 2mph \u2199\n<span foreground=\"#585858\" font-weight=\"bold\"> (___.__)__) </span>Humidity: 80%\n Moon phase: Waxing Crescent \ud83c\udf12\n\nToday, <b>Mon Nov 24 2025</b>\n\uf2c7 53\u00b0F \uf2ca 38\u00b0F\ue34c 07:23 AM \ue34d 04:36 PM\n03 PM \udb81\udd95 52\u00b0 Partly Cloudy , Overcast 33%, Sunshine 73%\n06 PM \ue313 44\u00b0 Mist, Overcast 83%, Sunshine 8%\n09 PM \ue313 43\u00b0 Fog, Overcast 93%, Sunshine 5%\nTomorrow, <b>Tue Nov 25 2025</b>\n\uf2c7 43\u00b0F \uf2ca 34\u00b0F\ue34c 07:24 AM \ue34d 04:36 PM\n12 AM \ue313 43\u00b0 Fog, Fog 6%, Overcast 81%, Sunshine 19%\n03 AM \ue313 42\u00b0 Fog, Overcast 89%, Sunshine 8%\n06 AM \ue313 41\u00b0 Fog, Fog 6%, Overcast 92%, Sunshine 11%\n09 AM \ue313 40\u00b0 Fog, Fog 6%, Overcast 88%, Sunshine 5%\n12 PM \ue317 39\u00b0 Moderate rain at times, Overcast 90%, Rain 100%\n03 PM \ue308 34\u00b0 Light rain, Overcast 93%, Rain 100%\n06 PM \ue318 31\u00b0 Moderate rain, Overcast 88%, Rain 100%\n09 PM \ue31a 24\u00b0 Moderate snow, Overcast 89%, Rain 100%, Snow 100%\n<b>Wed Nov 26 2025</b>\n\uf2c7 36\u00b0F \uf2ca 25\u00b0F\ue34c 07:26 AM \ue34d 04:35 PM\n12 AM \ue312 21\u00b0 Overcast , Overcast 87%, Sunshine 8%\n03 AM \ue312 14\u00b0 Overcast , Frost 25%, Overcast 94%, Sunshine 13%\n06 AM \ue312 11\u00b0 Overcast , Frost 80%, Overcast 89%, Sunshine 8%\n09 AM \ue312 13\u00b0 Overcast , Frost 79%, Overcast 80%, Sunshine 5%\n12 PM \ue33d 18\u00b0 Cloudy , Frost 77%, Overcast 89%, Sunshine 17%\n03 PM \ue30d 24\u00b0 Sunny, Frost 29%, Sunshine 90%\n06 PM \udb81\udd94 22\u00b0 Clear , Frost 78%, Sunshine 94%\n09 PM \udb83\udf31 15\u00b0 Partly Cloudy , Frost 85%, Overcast 39%, Sunshine 83%\n"}
|
|
||||||
924
flake.lock
generated
924
flake.lock
generated
File diff suppressed because it is too large
Load Diff
94
flake.nix
94
flake.nix
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
|
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||||
|
|
||||||
# The name "snowfall-lib" is required due to how Snowfall Lib processes your
|
# The name "snowfall-lib" is required due to how Snowfall Lib processes your
|
||||||
# flake's inputs.
|
# flake's inputs.
|
||||||
snowfall-lib = {
|
snowfall-lib = {
|
||||||
url = "github:mjallen18/lib";
|
url = "github:snowfallorg/lib";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
impermanence.url = "github:nix-community/impermanence";
|
impermanence.url = "github:nix-community/impermanence";
|
||||||
|
|
||||||
lanzaboote.url = "github:nix-community/lanzaboote/v0.4.3";
|
lanzaboote.url = "github:nix-community/lanzaboote/v0.4.2";
|
||||||
|
|
||||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||||
|
|
||||||
@@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
authentik-nix.url = "github:nix-community/authentik-nix";
|
authentik-nix.url = "github:nix-community/authentik-nix";
|
||||||
|
|
||||||
|
crowdsec.url = "git+https://codeberg.org/kampka/nix-flake-crowdsec.git";
|
||||||
|
|
||||||
nixai.url = "github:olafkfreund/nix-ai-help";
|
nixai.url = "github:olafkfreund/nix-ai-help";
|
||||||
|
|
||||||
disko = {
|
disko = {
|
||||||
@@ -81,19 +83,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
lsfg-vk = {
|
lsfg-vk = {
|
||||||
url = "github:pabloaul/lsfg-vk-flake";
|
url = "github:mjallen18/lsfg-vk-flake/main";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
nix-plist-manager.url = "github:sushydev/nix-plist-manager";
|
|
||||||
|
|
||||||
nix-rosetta-builder = {
|
|
||||||
url = "github:cpick/nix-rosetta-builder";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
stylix = {
|
|
||||||
url = "github:nix-community/stylix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -116,23 +106,19 @@
|
|||||||
modules.nixos = with inputs; [
|
modules.nixos = with inputs; [
|
||||||
authentik-nix.nixosModules.default
|
authentik-nix.nixosModules.default
|
||||||
chaotic.nixosModules.default
|
chaotic.nixosModules.default
|
||||||
|
crowdsec.nixosModules.crowdsec
|
||||||
|
crowdsec.nixosModules.crowdsec-firewall-bouncer
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
impermanence.nixosModules.impermanence
|
impermanence.nixosModules.impermanence
|
||||||
lanzaboote.nixosModules.lanzaboote
|
lanzaboote.nixosModules.lanzaboote
|
||||||
sops-nix.nixosModules.sops
|
sops-nix.nixosModules.sops
|
||||||
home-manager.nixosModules.home-manager
|
home-manager.nixosModules.home-manager
|
||||||
nix-index-database.nixosModules.nix-index
|
|
||||||
stylix.nixosModules.stylix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# common darwin modules
|
# common darwin modules
|
||||||
modules.darwin = with inputs; [
|
modules.darwin = with inputs; [
|
||||||
nix-homebrew.darwinModules.nix-homebrew
|
nix-homebrew.darwinModules.nix-homebrew
|
||||||
home-manager.darwinModules.home-manager
|
home-manager.darwinModules.home-manager
|
||||||
nix-plist-manager.darwinModules.default
|
|
||||||
nix-rosetta-builder.darwinModules.default
|
|
||||||
nix-index-database.darwinModules.nix-index
|
|
||||||
stylix.darwinModules.stylix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Host config
|
# Host config
|
||||||
@@ -140,7 +126,7 @@
|
|||||||
# ######################################################
|
# ######################################################
|
||||||
# Desktop #
|
# Desktop #
|
||||||
# ######################################################
|
# ######################################################
|
||||||
matt-nixos = {
|
desktop = {
|
||||||
modules = with inputs; [
|
modules = with inputs; [
|
||||||
nixos-hardware.nixosModules.common-cpu-amd
|
nixos-hardware.nixosModules.common-cpu-amd
|
||||||
nixos-hardware.nixosModules.common-cpu-amd-pstate
|
nixos-hardware.nixosModules.common-cpu-amd-pstate
|
||||||
@@ -155,7 +141,7 @@
|
|||||||
# ######################################################
|
# ######################################################
|
||||||
# NAS #
|
# NAS #
|
||||||
# ######################################################
|
# ######################################################
|
||||||
jallen-nas = {
|
nas = {
|
||||||
modules = with inputs; [
|
modules = with inputs; [
|
||||||
nixos-hardware.nixosModules.common-pc
|
nixos-hardware.nixosModules.common-pc
|
||||||
nixos-hardware.nixosModules.common-cpu-amd
|
nixos-hardware.nixosModules.common-cpu-amd
|
||||||
@@ -164,6 +150,7 @@
|
|||||||
nixos-hardware.nixosModules.common-hidpi
|
nixos-hardware.nixosModules.common-hidpi
|
||||||
home-manager.nixosModules.home-manager
|
home-manager.nixosModules.home-manager
|
||||||
];
|
];
|
||||||
|
# overlays = with inputs; [ crowdsec.overlays.default ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# ######################################################
|
# ######################################################
|
||||||
@@ -186,7 +173,7 @@
|
|||||||
# ######################################################
|
# ######################################################
|
||||||
# NUC #
|
# NUC #
|
||||||
# ######################################################
|
# ######################################################
|
||||||
nuc-nixos = {
|
nuc = {
|
||||||
modules = with inputs; [
|
modules = with inputs; [
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
nixos-hardware.nixosModules.common-cpu-amd
|
nixos-hardware.nixosModules.common-cpu-amd
|
||||||
@@ -202,17 +189,11 @@
|
|||||||
# Pi4 #
|
# Pi4 #
|
||||||
# ######################################################
|
# ######################################################
|
||||||
pi4 = {
|
pi4 = {
|
||||||
specialArgs = {
|
|
||||||
nixpkgs = inputs.nixpkgs-stable;
|
|
||||||
};
|
|
||||||
modules = with inputs; [
|
modules = with inputs; [
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
nixos-raspberrypi.nixosModules.raspberry-pi-4.base
|
nixos-raspberrypi.nixosModules.raspberry-pi-4.base
|
||||||
nixos-raspberrypi.nixosModules.raspberry-pi-4.display-vc4
|
nixos-raspberrypi.nixosModules.raspberry-pi-4.display-vc4
|
||||||
nixos-raspberrypi.nixosModules.nixpkgs-rpi
|
|
||||||
nixos-raspberrypi.nixosModules.trusted-nix-caches
|
|
||||||
nixos-raspberrypi.lib.inject-overlays
|
nixos-raspberrypi.lib.inject-overlays
|
||||||
nixos-raspberrypi.lib.inject-overlays-global
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -220,19 +201,12 @@
|
|||||||
# Pi5 #
|
# Pi5 #
|
||||||
# ######################################################
|
# ######################################################
|
||||||
pi5 = {
|
pi5 = {
|
||||||
specialArgs = {
|
|
||||||
nixpkgs = inputs.nixpkgs-stable;
|
|
||||||
};
|
|
||||||
modules = with inputs; [
|
modules = with inputs; [
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.base
|
nixos-raspberrypi.nixosModules.raspberry-pi-5.base
|
||||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.display-vc4
|
nixos-raspberrypi.nixosModules.raspberry-pi-5.display-vc4
|
||||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.bluetooth
|
nixos-raspberrypi.nixosModules.raspberry-pi-5.bluetooth
|
||||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.page-size-16k
|
|
||||||
nixos-raspberrypi.nixosModules.nixpkgs-rpi
|
|
||||||
nixos-raspberrypi.nixosModules.trusted-nix-caches
|
|
||||||
nixos-raspberrypi.lib.inject-overlays
|
nixos-raspberrypi.lib.inject-overlays
|
||||||
nixos-raspberrypi.lib.inject-overlays-global
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -247,9 +221,31 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
overlays = with inputs; [
|
overlays = with inputs; [ nix-vscode-extensions.overlays.default ];
|
||||||
nix-vscode-extensions.overlays.default
|
|
||||||
];
|
homes = {
|
||||||
|
modules = with inputs; [
|
||||||
|
nix-index-database.homeModules.nix-index
|
||||||
|
sops-nix.homeManagerModules.sops
|
||||||
|
];
|
||||||
|
|
||||||
|
overlays = with inputs; [
|
||||||
|
nix-vscode-extensions.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
users = {
|
||||||
|
# "matt@desktop" = {
|
||||||
|
# modules = with inputs; [
|
||||||
|
# sops-nix.homeManagerModules.sops
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
"deck@steamdeck" = {
|
||||||
|
modules = with inputs; [
|
||||||
|
steam-rom-manager.homeManagerModules.default
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Configure Snowfall Lib, all of these settings are optional.
|
# Configure Snowfall Lib, all of these settings are optional.
|
||||||
@@ -268,24 +264,8 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
channels-config = {
|
|
||||||
allowUnfree = true;
|
|
||||||
permittedInsecurePackages = [
|
|
||||||
# ...
|
|
||||||
"libsoup-2.74.3"
|
|
||||||
"mbedtls-2.28.10"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs-builder = channels: {
|
outputs-builder = channels: {
|
||||||
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
|
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
|
||||||
|
|
||||||
# Add mjallen-lib to the flake outputs
|
|
||||||
overlays = {
|
|
||||||
mjallen-lib = _final: _prev: {
|
|
||||||
mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
namespace,
|
home,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
update-switch = "darwin-rebuild switch --flake ~/nix-config";
|
update-switch = "darwin-rebuild switch --flake ~/nix-config";
|
||||||
update-flake = "nix flake update ~/nix-config";
|
update-flake = "nix flake update ~/nix-config";
|
||||||
@@ -15,9 +14,8 @@ let
|
|||||||
age
|
age
|
||||||
cpufetch
|
cpufetch
|
||||||
deadnix
|
deadnix
|
||||||
|
direnv
|
||||||
nixfmt-rfc-style
|
nixfmt-rfc-style
|
||||||
nodePackages.nodejs
|
|
||||||
uv
|
|
||||||
sops
|
sops
|
||||||
tree
|
tree
|
||||||
wget
|
wget
|
||||||
@@ -31,7 +29,7 @@ in
|
|||||||
homeDirectory = "/Users/mattjallen";
|
homeDirectory = "/Users/mattjallen";
|
||||||
packages = lib.mkForce packages;
|
packages = lib.mkForce packages;
|
||||||
sessionVariables = {
|
sessionVariables = {
|
||||||
NH_DARWIN_FLAKE = lib.mkForce "/Users/mattjallen/nix-config";
|
NH_DARWIN_FLAKE = "${home.homeDirectory}/nix-config#mac";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,238 +39,20 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.nix-plist-manager = {
|
|
||||||
enable = true;
|
|
||||||
options = {
|
|
||||||
applications = {
|
|
||||||
finder = {
|
|
||||||
settings = {
|
|
||||||
general = {
|
|
||||||
showTheseItemsOnTheDesktop = {
|
|
||||||
hardDisks = false;
|
|
||||||
externalDisks = true;
|
|
||||||
cdsDvdsAndiPods = false;
|
|
||||||
connectedServers = false;
|
|
||||||
};
|
|
||||||
openFoldersInTabsInsteadOfNewWindows = true;
|
|
||||||
};
|
|
||||||
sidebar = {
|
|
||||||
recentTags = true;
|
|
||||||
};
|
|
||||||
advanced = {
|
|
||||||
removeItemsFromTheTrashAfter30Days = true;
|
|
||||||
showAllFilenameExtensions = true;
|
|
||||||
showWarningBeforeChangingAnExtension = true;
|
|
||||||
showWarningBeforeRemovingFromiCloudDrive = true;
|
|
||||||
showWarningBeforeEmptyingTheTrash = true;
|
|
||||||
keepFoldersOnTop = {
|
|
||||||
inWindowsWhenSortingByName = true;
|
|
||||||
onDesktop = true;
|
|
||||||
};
|
|
||||||
whenPerformingASearch = "Search This Mac";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
menuBar = {
|
|
||||||
view = {
|
|
||||||
showTabBar = true;
|
|
||||||
showSidebar = true;
|
|
||||||
showPathBar = true;
|
|
||||||
showStatusBar = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemSettings = {
|
|
||||||
appearance = {
|
|
||||||
appearance = "Dark";
|
|
||||||
accentColor = "Multicolor";
|
|
||||||
# clickInTheScrollBarTo = "Jump to the next page";
|
|
||||||
sidebarIconSize = "Medium";
|
|
||||||
showScrollBars = "When scrolling";
|
|
||||||
};
|
|
||||||
controlCenter = {
|
|
||||||
wifi = true;
|
|
||||||
bluetooth = true;
|
|
||||||
airdrop = true;
|
|
||||||
stageManager = true;
|
|
||||||
focusModes = "active";
|
|
||||||
screenMirroring = "active";
|
|
||||||
display = "never";
|
|
||||||
sound = "always";
|
|
||||||
nowPlaying = "active";
|
|
||||||
accessibilityShortcuts = "unset";
|
|
||||||
musicRecognition = {
|
|
||||||
showInMenuBar = false;
|
|
||||||
showInControlCenter = true;
|
|
||||||
};
|
|
||||||
hearing = "unset";
|
|
||||||
fastUserSwitching = {
|
|
||||||
showInMenuBar = false;
|
|
||||||
showInControlCenter = true;
|
|
||||||
};
|
|
||||||
keyboardBrightness = {
|
|
||||||
showInMenuBar = false;
|
|
||||||
showInControlCenter = true;
|
|
||||||
};
|
|
||||||
battery = {
|
|
||||||
showInMenuBar = false;
|
|
||||||
showInControlCenter = false;
|
|
||||||
};
|
|
||||||
batteryShowPercentage = true;
|
|
||||||
# menuBarOnly = {
|
|
||||||
# spotlight = false;
|
|
||||||
# siri = true;
|
|
||||||
# };
|
|
||||||
# automaticallyHideAndShowTheMenuBar = "In Full Screen Only";
|
|
||||||
};
|
|
||||||
desktopAndDock = {
|
|
||||||
desktopAndStageManager = {
|
|
||||||
showItems = {
|
|
||||||
onDesktop = true;
|
|
||||||
inStageManager = true;
|
|
||||||
};
|
|
||||||
clickWallpaperToRevealDesktop = "Always";
|
|
||||||
stageManager = false;
|
|
||||||
showRecentAppsInStageManager = true;
|
|
||||||
showWindowsFromAnApplication = "All at Once";
|
|
||||||
};
|
|
||||||
dock = {
|
|
||||||
animateOpeningApplications = true;
|
|
||||||
automaticallyHideAndShowTheDock = enabled;
|
|
||||||
doubleClickAWindowsTitleBarTo = "Minimize";
|
|
||||||
magnification = disabled;
|
|
||||||
minimizeWindowsIntoApplicationIcon = true;
|
|
||||||
minimizeWindowsUsing = "Genie Effect";
|
|
||||||
positionOnScreen = "Bottom";
|
|
||||||
showIndicatorsForOpenApplications = true;
|
|
||||||
showSuggestedAndRecentAppsInDock = false;
|
|
||||||
size = 64; # 16 - 128
|
|
||||||
# persistentApps = [
|
|
||||||
# { app = "/Applications/Clock.app"; }
|
|
||||||
# { folder = "/Applications"; }
|
|
||||||
# { app = "/Applications/Safari.app"; }
|
|
||||||
# { app = "/Applications/Firefox.app"; }
|
|
||||||
# { app = "/Applications/Tabby.app"; }
|
|
||||||
# { app = "/Applications/Termius.app"; }
|
|
||||||
# { app = "/Applications/Muic.app"; }
|
|
||||||
# { app = "/Applications/Vesktop.app"; }
|
|
||||||
# { app = "/Applications/Messages.app"; }
|
|
||||||
# { app = "/Applications/Calendar.app"; }
|
|
||||||
# { app = "/Applications/Reminders.app"; }
|
|
||||||
# { app = "/Applications/Notes.app"; }
|
|
||||||
# { app = "/Applications/Weather.app"; }
|
|
||||||
# { app = "/Applications/Maps.app"; }
|
|
||||||
# { app = "/Applications/App Store.app"; }
|
|
||||||
# { app = "/Applications/System Settings.app"; }
|
|
||||||
# { app = "/Applications/ChatGPT.app"; }
|
|
||||||
# { app = "/Applications/Nextcloud.app"; }
|
|
||||||
# { app = "/Applications/VSCodium.app"; }
|
|
||||||
# { app = "/Applications/Omnissa Horizon Client.app"; }
|
|
||||||
# { app = "/Applications/Proton Pass.app"; }
|
|
||||||
# { app = "/Applications/OrcaSlicer.app"; }
|
|
||||||
# { app = "/Applications/AlDente.app"; }
|
|
||||||
# ];
|
|
||||||
# persistentOthers = [
|
|
||||||
# "~/Downloads"
|
|
||||||
# ];
|
|
||||||
};
|
|
||||||
hotCorners = {
|
|
||||||
# ["-" "Mission Control" "Application Windows" "Desktop" "Start Screen Saver" "Disable Screen Saver" "Dashboard" "Put Display to Sleep" "Launchpad" "Notification Center" "Lock Screen" "Quick Note"]
|
|
||||||
topLeft = "-";
|
|
||||||
topRight = "-";
|
|
||||||
bottomLeft = "-";
|
|
||||||
bottomRight = "-";
|
|
||||||
};
|
|
||||||
missionControl = {
|
|
||||||
automaticallyRearrangeSpacesBasedOnMostRecentUse = true;
|
|
||||||
displaysHaveSeparateSpaces = true;
|
|
||||||
dragWindowsToTopOfScreenToEnterMissionControl = true;
|
|
||||||
groupWindowsByApplication = true;
|
|
||||||
whenSwitchingToAnApplicationSwitchToAspaceWithOpenWindowsForTheApplication = true;
|
|
||||||
};
|
|
||||||
widgets = {
|
|
||||||
showWidgets = {
|
|
||||||
onDesktop = true;
|
|
||||||
inStageManager = true;
|
|
||||||
};
|
|
||||||
widgetStyle = "Automatic";
|
|
||||||
useIphoneWidgets = true;
|
|
||||||
};
|
|
||||||
windows = {
|
|
||||||
askToKeepChangesWhenClosingDocuments = true;
|
|
||||||
closeWindowsWhenQuittingAnApplication = true;
|
|
||||||
dragWindowsToScreenEdgesToTile = true;
|
|
||||||
dragWindowsToMenuBarToFillScreen = true;
|
|
||||||
holdOptionKeyWhileDraggingWindowsToTile = true;
|
|
||||||
preferTabsWhenOpeningDocuments = "In Full Screen";
|
|
||||||
tiledWindowsHaveMargin = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
focus = {
|
|
||||||
shareAcrossDevices = true;
|
|
||||||
};
|
|
||||||
# general.dateAndTime."24HourTime" = false;
|
|
||||||
notifications = {
|
|
||||||
notificationCenter = {
|
|
||||||
showPreviews = "When Unlocked";
|
|
||||||
summarizeNotifications = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
sound = {
|
|
||||||
soundEffects = {
|
|
||||||
alertSound = "Boop";
|
|
||||||
alertVolume = 0.7;
|
|
||||||
playFeedbackWhenVolumeIsChanged = true;
|
|
||||||
playUserInterfaceSoundEffects = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
spotlight = {
|
|
||||||
helpAppleImproveSearch = false;
|
|
||||||
# searchResults = {
|
|
||||||
# applications = true;
|
|
||||||
# calculator = true;
|
|
||||||
# contacts = true;
|
|
||||||
# conversion = true;
|
|
||||||
# definition = true;
|
|
||||||
# developer = true;
|
|
||||||
# documents = true;
|
|
||||||
# eventsAndReminders = true;
|
|
||||||
# folders = true;
|
|
||||||
# fonts = false;
|
|
||||||
# images = true;
|
|
||||||
# mailAndMessages = true;
|
|
||||||
# movies = true;
|
|
||||||
# music = true;
|
|
||||||
# other = false;
|
|
||||||
# pdfDocuments = true;
|
|
||||||
# presentations = true;
|
|
||||||
# siriSuggestions = false;
|
|
||||||
# systemSettings = true;
|
|
||||||
# tips = false;
|
|
||||||
# websites = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Manage bug in compilations - who uses manpages in 2024 anyways? :P
|
# Manage bug in compilations - who uses manpages in 2024 anyways? :P
|
||||||
manual.manpages = enabled;
|
manual.manpages.enable = false;
|
||||||
|
|
||||||
# Override defaults that arent supported
|
# Override defaults that arent supported
|
||||||
programs = {
|
programs = {
|
||||||
mangohud = lib.mkForce disabled;
|
mangohud.enable = lib.mkForce false;
|
||||||
|
|
||||||
nh = {
|
nh = {
|
||||||
flake = lib.mkForce "/Users/mattjallen/nix-config";
|
flake = "${home.homeDirectory}/nix-config";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
pass-secret-service = lib.mkForce disabled;
|
pass-secret-service.enable = lib.mkForce false;
|
||||||
nextcloud-client = lib.mkForce disabled;
|
nextcloud-client.enable = lib.mkForce false;
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
{
|
{ pkgs, lib, ... }:
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
theme = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
||||||
update-flake = "nix flake update mac-nixpkgs mac-nixos-apple-silicon mac-home-manager mac-impermanence mac-sops-nix --flake /etc/nixos";
|
update-flake = "nix flake update mac-nixpkgs mac-nixos-apple-silicon mac-home-manager mac-impermanence mac-sops-nix --flake /etc/nixos";
|
||||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||||
};
|
};
|
||||||
|
fontName = "JetBrainsMono NFM";
|
||||||
|
fontPackage = pkgs.nerd-fonts.jetbrains-mono;
|
||||||
# Displays
|
# Displays
|
||||||
display = {
|
display = {
|
||||||
input = "eDP-1";
|
input = "eDP-1";
|
||||||
@@ -25,29 +22,17 @@ in
|
|||||||
home.homeDirectory = "/home/matt";
|
home.homeDirectory = "/home/matt";
|
||||||
home.stateVersion = "23.11";
|
home.stateVersion = "23.11";
|
||||||
|
|
||||||
${namespace} = {
|
mjallen = {
|
||||||
programs.hyprland = {
|
desktop.hyprland = {
|
||||||
enable = true;
|
enable = true;
|
||||||
primaryDisplay = "eDP-1";
|
primaryDisplay = "eDP-1";
|
||||||
debug.disableScaleChecks = true;
|
|
||||||
|
|
||||||
monitorv2 = [
|
wallpaper = [
|
||||||
{
|
"${display.input}, /run/wallpaper.jpg"
|
||||||
name = display.input;
|
];
|
||||||
mode = "${display.resolution}@${display.refreshRate}";
|
|
||||||
position = "0x0";
|
monitor = [
|
||||||
scale = 1.25;
|
"${display.input},${display.resolution}@${display.refreshRate},0x0,1.25,bitdepth,10,cm,hdr,sdrbrightness,1.2,sdrsaturation,0.98"
|
||||||
extra = [
|
|
||||||
"bitdepth"
|
|
||||||
"10"
|
|
||||||
"cm"
|
|
||||||
"hdr"
|
|
||||||
"sdrbrightness"
|
|
||||||
"1.2"
|
|
||||||
"sdrsaturation"
|
|
||||||
"0.98"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
workspace = [
|
workspace = [
|
||||||
@@ -59,31 +44,25 @@ in
|
|||||||
windowRule = [
|
windowRule = [
|
||||||
"size 2160 3356, tag:horizonrdp"
|
"size 2160 3356, tag:horizonrdp"
|
||||||
];
|
];
|
||||||
|
|
||||||
hyprpaper = {
|
|
||||||
wallpaperPath = "/run/wallpaper.jpg";
|
|
||||||
};
|
|
||||||
|
|
||||||
keybinds = {
|
|
||||||
bind = [
|
|
||||||
"$mod, A, exec, chromium --app=\"https://music.apple.com\""
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultApps = {
|
defaultApps = {
|
||||||
browser = pkgs.firefox;
|
browser = pkgs.firefox;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
programs = {
|
programs = {
|
||||||
btop = enabled;
|
btop.enable = true;
|
||||||
kitty = {
|
kitty = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
font = {
|
||||||
|
name = fontName;
|
||||||
|
package = fontPackage;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
mako = {
|
mako = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
fontName = fontName;
|
||||||
};
|
};
|
||||||
nwg-dock = enabled;
|
nwg-dock.enable = true;
|
||||||
nwg-drawer = enabled;
|
nwg-drawer.enable = true;
|
||||||
nwg-panel = {
|
nwg-panel = {
|
||||||
enable = true;
|
enable = true;
|
||||||
defaultApps = {
|
defaultApps = {
|
||||||
@@ -95,10 +74,19 @@ in
|
|||||||
|
|
||||||
layer = "bottom";
|
layer = "bottom";
|
||||||
|
|
||||||
temperature = {
|
modules-right = [
|
||||||
cpu = enabled;
|
"temperature"
|
||||||
gpu = enabled;
|
"temperature#gpu"
|
||||||
};
|
"keyboard-state#capslock"
|
||||||
|
"keyboard-state#numlock"
|
||||||
|
"wireplumber#sink"
|
||||||
|
"bluetooth"
|
||||||
|
"network"
|
||||||
|
"idle_inhibitor"
|
||||||
|
"clock"
|
||||||
|
"battery"
|
||||||
|
"custom/weather"
|
||||||
|
];
|
||||||
|
|
||||||
extraModules = {
|
extraModules = {
|
||||||
"custom/lights" = {
|
"custom/lights" = {
|
||||||
@@ -113,27 +101,25 @@ in
|
|||||||
|
|
||||||
extraModulesStyle = ''
|
extraModulesStyle = ''
|
||||||
#custom-lights {
|
#custom-lights {
|
||||||
color: @base0C;
|
color: ${theme.frost.nord8};
|
||||||
opacity: 0.85;
|
background-color: ${theme.polarNight.nord0};
|
||||||
background-color: @base00;
|
${theme.defaultOpacity}
|
||||||
|
${theme.borderLeft}
|
||||||
}
|
}
|
||||||
|
|
||||||
#custom-lights:hover {
|
#custom-lights:hover {
|
||||||
background: @base03;
|
background: ${theme.polarNight.nord3};
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
windowOffset = 75;
|
windowOffset = 75;
|
||||||
};
|
};
|
||||||
wlogout = enabled;
|
wlogout.enable = true;
|
||||||
wofi = enabled;
|
wofi.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
pkgs.${namespace}.bolt-launcher
|
|
||||||
pkgs.${namespace}.librepods
|
|
||||||
|
|
||||||
iw
|
iw
|
||||||
iwd
|
iwd
|
||||||
orca-slicer
|
orca-slicer
|
||||||
@@ -141,7 +127,7 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
password-store = enabled;
|
password-store.enable = true;
|
||||||
|
|
||||||
zsh.shellAliases = shellAliases;
|
zsh.shellAliases = shellAliases;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
{ lib, namespace, ... }:
|
{ lib, ... }:
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home.username = "matt";
|
home.username = "matt";
|
||||||
|
|
||||||
${namespace} = {
|
mjallen = {
|
||||||
shell-aliases = {
|
shell-aliases = {
|
||||||
enable = true;
|
enable = true;
|
||||||
flakeInputs = [
|
flakeInputs = [
|
||||||
@@ -56,11 +53,11 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
mangohud = lib.mkForce enabled;
|
mangohud.enable = lib.mkForce true;
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
nextcloud-client = lib.mkForce disabled;
|
nextcloud-client.enable = lib.mkForce false;
|
||||||
kdeconnect = {
|
kdeconnect = {
|
||||||
enable = false;
|
enable = false;
|
||||||
indicator = false;
|
indicator = false;
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
||||||
@@ -62,7 +59,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
nextcloud-client = lib.mkForce disabled;
|
nextcloud-client.enable = false;
|
||||||
kdeconnect = {
|
kdeconnect = {
|
||||||
enable = false;
|
enable = false;
|
||||||
indicator = false;
|
indicator = false;
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "root";
|
|
||||||
services = {
|
|
||||||
nextcloud-client = lib.mkForce disabled;
|
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
{
|
{ config, lib, ... }:
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
shellAliases = {
|
||||||
|
update-boot = "nixos-rebuild boot --max-jobs 10";
|
||||||
|
update-switch = "nixos-rebuild switch --max-jobs 10";
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.username = "root";
|
home = {
|
||||||
|
username = "root";
|
||||||
|
homeDirectory = lib.mkForce "/${config.home.username}";
|
||||||
|
enableNixpkgsReleaseCheck = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
zsh.shellAliases = shellAliases;
|
||||||
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
nextcloud-client = lib.mkForce disabled;
|
nextcloud-client.enable = lib.mkForce false;
|
||||||
kdeconnect = {
|
kdeconnect = {
|
||||||
enable = false;
|
enable = false;
|
||||||
indicator = false;
|
indicator = false;
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "root";
|
|
||||||
services = {
|
|
||||||
nextcloud-client = lib.mkForce disabled;
|
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
{ pkgs, namespace, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
home.username = "admin";
|
home.username = "admin";
|
||||||
|
|
||||||
${namespace} = {
|
# mjallen.home.enable = true;
|
||||||
|
|
||||||
|
mjallen = {
|
||||||
shell-aliases = {
|
shell-aliases = {
|
||||||
enable = true;
|
enable = true;
|
||||||
buildHost = ""; # NAS builds locally
|
buildHost = ""; # NAS builds locally
|
||||||
@@ -10,6 +12,7 @@
|
|||||||
"nas-nixpkgs"
|
"nas-nixpkgs"
|
||||||
"nas-authentik-nix"
|
"nas-authentik-nix"
|
||||||
"nas-cosmic"
|
"nas-cosmic"
|
||||||
|
"nas-crowdsec"
|
||||||
"nas-home-manager"
|
"nas-home-manager"
|
||||||
"nas-impermanence"
|
"nas-impermanence"
|
||||||
"nas-lanzaboote"
|
"nas-lanzaboote"
|
||||||
@@ -70,4 +73,14 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# services.nixai = {
|
||||||
|
# enable = true;
|
||||||
|
# mcp = {
|
||||||
|
# enable = true;
|
||||||
|
# # Optional: custom socket path (uses `$HOME` expansion)
|
||||||
|
# socketPath = "$HOME/.local/share/nixai/mcp.sock";
|
||||||
|
# };
|
||||||
|
# # Optional: integrate with VS Code
|
||||||
|
# vscodeIntegration = true;
|
||||||
|
# };
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, ... }:
|
{ ... }:
|
||||||
let
|
let
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10";
|
update-boot = "sudo nixos-rebuild boot --max-jobs 10";
|
||||||
@@ -12,21 +12,4 @@ in
|
|||||||
programs = {
|
programs = {
|
||||||
zsh.shellAliases = shellAliases;
|
zsh.shellAliases = shellAliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Configure systemd user service for protonmail-bridge
|
|
||||||
systemd.user.services.protonmail-bridge = {
|
|
||||||
Service = {
|
|
||||||
Environment = [
|
|
||||||
"GNUPGHOME=/home/admin/.gnupg"
|
|
||||||
"PASSWORD_STORE_DIR=/home/admin/.local/password-store"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
protonmail-bridge = {
|
|
||||||
enable = true;
|
|
||||||
extraPackages = with pkgs; [ pass libsecret ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{ lib, pkgs, namespace, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10";
|
update-switch = "sudo nixos-rebuild switch --max-jobs 10";
|
||||||
@@ -11,7 +10,7 @@ in
|
|||||||
{
|
{
|
||||||
home.username = "deck";
|
home.username = "deck";
|
||||||
|
|
||||||
${namespace}.desktop.gnome = enabled;
|
mjallen.desktop.gnome.enable = true;
|
||||||
|
|
||||||
sops = {
|
sops = {
|
||||||
age.keyFile = "/home/deck/.config/sops/age/keys.txt";
|
age.keyFile = "/home/deck/.config/sops/age/keys.txt";
|
||||||
@@ -41,7 +40,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
emulators = {
|
emulators = {
|
||||||
ryujinx = enabled;
|
ryujinx.enable = true;
|
||||||
|
|
||||||
dolphin-gamecube = {
|
dolphin-gamecube = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -59,8 +58,8 @@ in
|
|||||||
extraArgs = "-b -e \"\${filePath}\"";
|
extraArgs = "-b -e \"\${filePath}\"";
|
||||||
};
|
};
|
||||||
|
|
||||||
pcsx2 = enabled;
|
pcsx2.enable = true;
|
||||||
mgba = enabled;
|
mgba.enable = true;
|
||||||
|
|
||||||
"Non-SRM Shortcuts" = {
|
"Non-SRM Shortcuts" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -78,7 +77,7 @@ in
|
|||||||
heroic
|
heroic
|
||||||
mgba
|
mgba
|
||||||
prismlauncher
|
prismlauncher
|
||||||
ryubing
|
ryujinx-greemdev
|
||||||
omnissa-horizon-client
|
omnissa-horizon-client
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
60
homes/x86_64-linux/matt@desktop/default.nix
Executable file
60
homes/x86_64-linux/matt@desktop/default.nix
Executable file
@@ -0,0 +1,60 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.username = "matt";
|
||||||
|
|
||||||
|
mjallen = {
|
||||||
|
sops = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
shell-aliases = {
|
||||||
|
enable = true;
|
||||||
|
flakeInputs = [
|
||||||
|
"desktop-nixpkgs"
|
||||||
|
"desktop-chaotic"
|
||||||
|
"desktop-home-manager"
|
||||||
|
"desktop-impermanence"
|
||||||
|
"desktop-lanzaboote"
|
||||||
|
"desktop-nixos-hardware"
|
||||||
|
"desktop-sops-nix"
|
||||||
|
"desktop-steam-rom-manager"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
remmina = {
|
||||||
|
enable = true;
|
||||||
|
addRdpMimeTypeAssoc = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
password-store.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
bottles
|
||||||
|
compose2nix
|
||||||
|
discord
|
||||||
|
distrobox
|
||||||
|
heroic
|
||||||
|
omnissa-horizon-client
|
||||||
|
jq
|
||||||
|
lutris
|
||||||
|
lzip
|
||||||
|
morph
|
||||||
|
orca-slicer
|
||||||
|
piper
|
||||||
|
prismlauncher
|
||||||
|
protontricks
|
||||||
|
protonvpn-gui
|
||||||
|
python3
|
||||||
|
runelite
|
||||||
|
smile
|
||||||
|
unigine-heaven
|
||||||
|
via
|
||||||
|
virt-manager
|
||||||
|
vorta
|
||||||
|
waydroid-helper
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
displayLeft = {
|
|
||||||
input = "DP-1";
|
|
||||||
resolution = "3840x2160";
|
|
||||||
refreshRate = "120.00000";
|
|
||||||
};
|
|
||||||
displayRight = {
|
|
||||||
input = "DP-2";
|
|
||||||
resolution = "3840x2160";
|
|
||||||
refreshRate = "240.00000";
|
|
||||||
};
|
|
||||||
theme = config.mjallen.theme.palette;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "matt";
|
|
||||||
|
|
||||||
${namespace} = {
|
|
||||||
sops = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
shell-aliases = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs = {
|
|
||||||
hyprland = {
|
|
||||||
enable = true;
|
|
||||||
primaryDisplay = "DP-1";
|
|
||||||
|
|
||||||
monitorv2 = [
|
|
||||||
{
|
|
||||||
name = displayLeft.input;
|
|
||||||
mode = "${displayLeft.resolution}@${displayLeft.refreshRate}";
|
|
||||||
position = "0x0";
|
|
||||||
scale = 1.0;
|
|
||||||
extra = [
|
|
||||||
"bitdepth"
|
|
||||||
"10"
|
|
||||||
"cm"
|
|
||||||
"hdr"
|
|
||||||
"sdrbrightness"
|
|
||||||
"1.2"
|
|
||||||
"sdrsaturation"
|
|
||||||
"0.98"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = displayRight.input;
|
|
||||||
mode = "${displayRight.resolution}@${displayRight.refreshRate}";
|
|
||||||
position = "3840x0";
|
|
||||||
scale = 1.0;
|
|
||||||
extra = [
|
|
||||||
"bitdepth"
|
|
||||||
"10"
|
|
||||||
"cm"
|
|
||||||
"hdr"
|
|
||||||
"sdrbrightness"
|
|
||||||
"1.5"
|
|
||||||
"sdrsaturation"
|
|
||||||
"0.98"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
workspace = [
|
|
||||||
"name:firefox, monitor:${displayRight.input}, default:false, special, class:(.*firefox.*)"
|
|
||||||
"name:discord, monitor:${displayRight.input}, default:true, special, title:(.*vesktop.*), title:(.*Apple Music.*)"
|
|
||||||
"name:steam, monitor:${displayLeft.input}, default:false, special, class:(.*[Ss]team.*)"
|
|
||||||
];
|
|
||||||
|
|
||||||
windowRule = [
|
|
||||||
"size 2160 7680, tag:horizonrdp"
|
|
||||||
];
|
|
||||||
|
|
||||||
autostartCommands = [
|
|
||||||
"[silent] firefox"
|
|
||||||
"[silent] discord"
|
|
||||||
"[silent] chromium --app=\"https://music.apple.com\""
|
|
||||||
"[silent] steam"
|
|
||||||
];
|
|
||||||
|
|
||||||
hyprpaper = {
|
|
||||||
wallpaperPath = "/run/wallpaper.jpg";
|
|
||||||
};
|
|
||||||
|
|
||||||
keybinds = {
|
|
||||||
bind = [
|
|
||||||
"$mod, A, exec, chromium --app=\"https://music.apple.com\""
|
|
||||||
"$mod, C, exec, discord"
|
|
||||||
"$mod, G, exec, steam"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultApps = {
|
|
||||||
browser = pkgs.firefox;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
btop = enabled;
|
|
||||||
kitty = enabled;
|
|
||||||
mako = enabled;
|
|
||||||
nwg-dock = enabled;
|
|
||||||
nwg-drawer = enabled;
|
|
||||||
nwg-panel = {
|
|
||||||
enable = true;
|
|
||||||
defaultApps = {
|
|
||||||
browser = pkgs.firefox;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
waybar = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
layer = "bottom";
|
|
||||||
|
|
||||||
network.interface = "wlp9s0";
|
|
||||||
temperature = {
|
|
||||||
cpu = enabled;
|
|
||||||
gpu = enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraModules = {
|
|
||||||
"custom/lights" = {
|
|
||||||
tooltip = false;
|
|
||||||
exec = "waybar-hass --get_light light.living_room_lights";
|
|
||||||
interval = "once";
|
|
||||||
format = "{text}"; # "";
|
|
||||||
on-click = "waybar-hass --toggle_light light.living_room_lights";
|
|
||||||
return-type = "json";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
extraModulesStyle = ''
|
|
||||||
#custom-lights {
|
|
||||||
color: @base0C;
|
|
||||||
background-color: @base00;
|
|
||||||
opacity: 0.85;
|
|
||||||
border-left: 5px solid @base0C;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-lights:hover {
|
|
||||||
background: @base03;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
wlogout = enabled;
|
|
||||||
wofi = enabled;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
remmina = {
|
|
||||||
enable = true;
|
|
||||||
addRdpMimeTypeAssoc = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
programs = {
|
|
||||||
password-store = enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
pkgs.${namespace}.bolt-launcher
|
|
||||||
pkgs.${namespace}.librepods
|
|
||||||
|
|
||||||
bottles
|
|
||||||
compose2nix
|
|
||||||
discord
|
|
||||||
distrobox
|
|
||||||
heroic
|
|
||||||
omnissa-horizon-client
|
|
||||||
jq
|
|
||||||
lutris
|
|
||||||
lzip
|
|
||||||
morph
|
|
||||||
orca-slicer
|
|
||||||
piper
|
|
||||||
prismlauncher
|
|
||||||
protontricks
|
|
||||||
protonvpn-gui
|
|
||||||
python3
|
|
||||||
runelite
|
|
||||||
smile
|
|
||||||
unigine-heaven
|
|
||||||
via
|
|
||||||
virt-manager
|
|
||||||
vorta
|
|
||||||
waydroid-helper
|
|
||||||
];
|
|
||||||
|
|
||||||
specialisation = {
|
|
||||||
"cosmic".configuration = {
|
|
||||||
${namespace} = {
|
|
||||||
programs = {
|
|
||||||
hyprland = lib.mkForce disabled;
|
|
||||||
kitty = lib.mkForce disabled;
|
|
||||||
mako = lib.mkForce disabled;
|
|
||||||
nwg-dock = lib.mkForce disabled;
|
|
||||||
nwg-drawer = lib.mkForce disabled;
|
|
||||||
nwg-panel = lib.mkForce disabled;
|
|
||||||
waybar = lib.mkForce disabled;
|
|
||||||
wlogout = lib.mkForce disabled;
|
|
||||||
wofi = lib.mkForce disabled;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "root";
|
|
||||||
services = {
|
|
||||||
nextcloud-client = lib.mkForce disabled;
|
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "root";
|
|
||||||
services = {
|
|
||||||
nextcloud-client = lib.mkForce disabled;
|
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "root";
|
|
||||||
services = {
|
|
||||||
nextcloud-client = lib.mkForce disabled;
|
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
17
homes/x86_64-linux/root@nuc/default.nix
Executable file
17
homes/x86_64-linux/root@nuc/default.nix
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
shellAliases = {
|
||||||
|
update-boot = "nixos-rebuild boot --max-jobs 10";
|
||||||
|
update-switch = "nixos-rebuild switch --max-jobs 10";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home = {
|
||||||
|
username = "root";
|
||||||
|
homeDirectory = lib.mkForce "/${config.home.username}";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
zsh.shellAliases = shellAliases;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.username = "root";
|
|
||||||
services = {
|
|
||||||
nextcloud-client = lib.mkForce disabled;
|
|
||||||
kdeconnect = {
|
|
||||||
enable = false;
|
|
||||||
indicator = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
130
lib/README.md
130
lib/README.md
@@ -1,130 +0,0 @@
|
|||||||
# mjallen-lib Utility Functions
|
|
||||||
|
|
||||||
This directory contains utility functions that can be used to enhance your Nix configuration. These functions are inspired by the khanelinix repository and provide a more explicit and modular approach to building Nix configurations.
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
- `default.nix`: Main entry point that imports and exposes all utility functions
|
|
||||||
- `module/`: Utilities for module creation and option handling
|
|
||||||
- `file/`: Utilities for file handling and module discovery
|
|
||||||
- `system/`: Utilities for system configuration building
|
|
||||||
|
|
||||||
## How to Use
|
|
||||||
|
|
||||||
### 1. Import the Library
|
|
||||||
|
|
||||||
The library is already imported in your flake.nix file through the outputs-builder:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
outputs-builder = channels: {
|
|
||||||
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
|
|
||||||
|
|
||||||
# Add mjallen-lib to the flake outputs
|
|
||||||
overlays = {
|
|
||||||
mjallen-lib = final: prev: {
|
|
||||||
mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
This makes the mjallen-lib available to all your modules through the extended lib.
|
|
||||||
|
|
||||||
### 2. Use the Module Utilities
|
|
||||||
|
|
||||||
The module utilities provide functions for creating modules with consistent options:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen.module) mkModule mkOpt mkBoolOpt;
|
|
||||||
in
|
|
||||||
mkModule {
|
|
||||||
name = "mymodule";
|
|
||||||
description = "My awesome module";
|
|
||||||
options = {
|
|
||||||
setting1 = mkOpt lib.types.str "default" "Description of setting1";
|
|
||||||
setting2 = mkBoolOpt false "Description of setting2";
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
# Module implementation
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Use the File Utilities
|
|
||||||
|
|
||||||
The file utilities provide functions for file handling and module discovery:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen.file) safeImport importModulesRecursive;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Import a file with error handling
|
|
||||||
myConfig = safeImport ./my-config.nix {};
|
|
||||||
|
|
||||||
# Import all modules recursively
|
|
||||||
imports = importModulesRecursive ./modules;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Use the System Utilities
|
|
||||||
|
|
||||||
The system utilities provide functions for building system configurations:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen.system.common) mkHomeManagerConfig;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Build home-manager configurations
|
|
||||||
homeManagerConfig = mkHomeManagerConfig {
|
|
||||||
extendedLib = lib;
|
|
||||||
inputs = inputs;
|
|
||||||
system = "x86_64-linux";
|
|
||||||
matchingHomes = { ... };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Available Functions
|
|
||||||
|
|
||||||
### Module Utilities
|
|
||||||
|
|
||||||
- `mkModule`: Create a module with common options
|
|
||||||
- `mkOpt`: Create an option with a type, default value, and description
|
|
||||||
- `mkOpt'`: Create an option with a type and default value (no description)
|
|
||||||
- `mkBoolOpt`: Create a boolean option with a default value and description
|
|
||||||
- `mkBoolOpt'`: Create a boolean option with a default value (no description)
|
|
||||||
- `enabled`: Standard enable pattern
|
|
||||||
- `disabled`: Standard disable pattern
|
|
||||||
- `capitalize`: Capitalize a string
|
|
||||||
- `boolToNum`: Convert a boolean to a number
|
|
||||||
- `default-attrs`: Apply mkDefault to all attributes
|
|
||||||
- `force-attrs`: Apply mkForce to all attributes
|
|
||||||
- `nested-default-attrs`: Apply default-attrs to nested attributes
|
|
||||||
- `nested-force-attrs`: Apply force-attrs to nested attributes
|
|
||||||
|
|
||||||
### File Utilities
|
|
||||||
|
|
||||||
- `readFile`: Read a file and return its contents
|
|
||||||
- `pathExists`: Check if a file exists
|
|
||||||
- `safeImport`: Import a nix file with error handling
|
|
||||||
- `scanDir`: Scan a directory and return directory names
|
|
||||||
- `getFile`: Get a file path relative to the flake root
|
|
||||||
- `importModulesRecursive`: Recursively discover and import all Nix modules in a directory tree
|
|
||||||
- `scanSystems`: Recursively scan systems directory structure
|
|
||||||
- `filterNixOSSystems`: Filter systems for NixOS (Linux)
|
|
||||||
- `filterDarwinSystems`: Filter systems for Darwin (macOS)
|
|
||||||
- `scanHomes`: Scan homes directory structure for home configurations
|
|
||||||
|
|
||||||
### System Utilities
|
|
||||||
|
|
||||||
- `mkExtendedLib`: Extend the nixpkgs lib with mjallen-lib
|
|
||||||
- `mkNixpkgsConfig`: Create a nixpkgs configuration
|
|
||||||
- `mkHomeConfigs`: Create home configurations for a system and hostname
|
|
||||||
- `mkHomeManagerConfig`: Create a home-manager configuration
|
|
||||||
- `mkSpecialArgs`: Create special arguments for a system configuration
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib)
|
|
||||||
concatLists
|
|
||||||
concatMapStrings
|
|
||||||
foldl'
|
|
||||||
genList
|
|
||||||
hasSuffix
|
|
||||||
imap0
|
|
||||||
length
|
|
||||||
mod
|
|
||||||
nameValuePair
|
|
||||||
stringToCharacters
|
|
||||||
sublist
|
|
||||||
substring
|
|
||||||
take
|
|
||||||
;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
base64Table = builtins.listToAttrs (
|
|
||||||
imap0 (i: c: nameValuePair c i) (
|
|
||||||
# The '=' is included so the main algorithm doesn't fail before we can trim the result
|
|
||||||
stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
# Generated using python3:
|
|
||||||
# print(''.join([ chr(n) for n in range(1, 256) ]), file=open('ascii', 'w'))
|
|
||||||
ascii = builtins.readFile ./ascii;
|
|
||||||
|
|
||||||
decode =
|
|
||||||
str:
|
|
||||||
let
|
|
||||||
paddingCount =
|
|
||||||
if hasSuffix "==" str then
|
|
||||||
2
|
|
||||||
else if hasSuffix "=" str then
|
|
||||||
1
|
|
||||||
else
|
|
||||||
0;
|
|
||||||
|
|
||||||
numbers64 = map (c: base64Table.${c}) (stringToCharacters str);
|
|
||||||
|
|
||||||
allBytes = concatLists (
|
|
||||||
genList (
|
|
||||||
i:
|
|
||||||
let
|
|
||||||
v = foldl' (acc: el: acc * 64 + el) 0 (sublist (i * 4) 4 numbers64);
|
|
||||||
in
|
|
||||||
[
|
|
||||||
(mod (v / 256 / 256) 256)
|
|
||||||
(mod (v / 256) 256)
|
|
||||||
(mod v 256)
|
|
||||||
]
|
|
||||||
) (length numbers64 / 4)
|
|
||||||
);
|
|
||||||
|
|
||||||
finalBytes = take (length allBytes - paddingCount) allBytes;
|
|
||||||
|
|
||||||
in
|
|
||||||
concatMapStrings (n: substring (n - 1) 1 ascii) finalBytes;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
mjallen-lib = {
|
|
||||||
# Import module utilities
|
|
||||||
module = import ./module { inherit inputs; };
|
|
||||||
|
|
||||||
# Import file utilities
|
|
||||||
file = import ./file { inherit inputs; };
|
|
||||||
|
|
||||||
# Import system utilities
|
|
||||||
system = import ./system { inherit inputs; };
|
|
||||||
|
|
||||||
# Import reverse proxy utilities
|
|
||||||
reverseproxy = import ./reverseproxy { inherit inputs; };
|
|
||||||
|
|
||||||
# Import examples
|
|
||||||
examples = import ./examples { inherit inputs; };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Import all examples
|
|
||||||
sops = import ./sops.nix;
|
|
||||||
homeSops = import ./home-sops.nix;
|
|
||||||
fileUtils = import ./file-utils.nix;
|
|
||||||
systemUtils = import ./system-utils.nix;
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen.file)
|
|
||||||
readFile
|
|
||||||
pathExists
|
|
||||||
safeImport
|
|
||||||
scanDir
|
|
||||||
getFile
|
|
||||||
importModulesRecursive
|
|
||||||
scanSystems
|
|
||||||
filterNixOSSystems
|
|
||||||
filterDarwinSystems
|
|
||||||
scanHomes
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Example of reading a file
|
|
||||||
myFileContent = readFile ./example.txt;
|
|
||||||
|
|
||||||
# Example of checking if a file exists
|
|
||||||
fileExists = pathExists ./example.txt;
|
|
||||||
|
|
||||||
# Example of safely importing a file
|
|
||||||
myConfig = safeImport ./my-config.nix { };
|
|
||||||
|
|
||||||
# Example of scanning a directory
|
|
||||||
directoryContents = scanDir ./modules;
|
|
||||||
|
|
||||||
# Example of getting a file path relative to the flake root
|
|
||||||
flakeFile = getFile "flake.nix";
|
|
||||||
|
|
||||||
# Example of importing modules recursively
|
|
||||||
modules = importModulesRecursive ./modules;
|
|
||||||
|
|
||||||
# Example of scanning systems
|
|
||||||
allSystems = scanSystems ./systems;
|
|
||||||
|
|
||||||
# Example of filtering systems
|
|
||||||
nixosSystems = filterNixOSSystems allSystems;
|
|
||||||
darwinSystems = filterDarwinSystems allSystems;
|
|
||||||
|
|
||||||
# Example of scanning homes
|
|
||||||
allHomes = scanHomes ./homes;
|
|
||||||
|
|
||||||
# Example of using these functions together
|
|
||||||
nixosConfigurations = lib.mapAttrs' (
|
|
||||||
_name:
|
|
||||||
{ system, hostname, ... }:
|
|
||||||
{
|
|
||||||
name = hostname;
|
|
||||||
value = lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
modules = [
|
|
||||||
{ networking.hostName = hostname; }
|
|
||||||
]
|
|
||||||
++ importModulesRecursive ./modules/nixos;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) nixosSystems;
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen.module) mkModule mkOpt;
|
|
||||||
in
|
|
||||||
mkModule {
|
|
||||||
name = "sops";
|
|
||||||
description = "SOPS secret management for home-manager";
|
|
||||||
options = {
|
|
||||||
defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
|
|
||||||
|
|
||||||
sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [ ] "SSH Key paths to use.";
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
age
|
|
||||||
sops
|
|
||||||
ssh-to-age
|
|
||||||
];
|
|
||||||
|
|
||||||
sops = {
|
|
||||||
inherit (config.mjallen.sops) defaultSopsFile;
|
|
||||||
defaultSopsFormat = "yaml";
|
|
||||||
|
|
||||||
age = {
|
|
||||||
generateKey = true;
|
|
||||||
keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
|
|
||||||
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ] ++ config.mjallen.sops.sshKeyPaths;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# Example usage of the reverse proxy utilities
|
|
||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen-lib.reverseproxy)
|
|
||||||
mkReverseProxy
|
|
||||||
mkReverseProxies
|
|
||||||
templates
|
|
||||||
middlewares
|
|
||||||
urls
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Example 1: Simple reverse proxy for a local service
|
|
||||||
simpleProxy = mkReverseProxy {
|
|
||||||
name = "myapp";
|
|
||||||
subdomain = "myapp";
|
|
||||||
url = "http://127.0.0.1:3000";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 2: Authenticated service with custom middlewares
|
|
||||||
authProxy = mkReverseProxy {
|
|
||||||
name = "admin-panel";
|
|
||||||
subdomain = "admin";
|
|
||||||
url = "http://127.0.0.1:8080";
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 3: Container-based service
|
|
||||||
containerProxy = mkReverseProxy {
|
|
||||||
name = "nextcloud";
|
|
||||||
subdomain = "cloud";
|
|
||||||
url = urls.container "nextcloud" 80;
|
|
||||||
middlewares = middlewares.basic;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 4: Multiple proxies at once
|
|
||||||
multipleProxies = mkReverseProxies [
|
|
||||||
{
|
|
||||||
name = "grafana";
|
|
||||||
subdomain = "grafana";
|
|
||||||
url = urls.localhost 3000;
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "prometheus";
|
|
||||||
subdomain = "prometheus";
|
|
||||||
url = urls.localhost 9090;
|
|
||||||
middlewares = middlewares.internal;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "alertmanager";
|
|
||||||
subdomain = "alerts";
|
|
||||||
url = urls.localhost 9093;
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# Example 5: Using templates for common patterns
|
|
||||||
webappExample = templates.webapp {
|
|
||||||
name = "webapp";
|
|
||||||
subdomain = "app";
|
|
||||||
port = 8080;
|
|
||||||
};
|
|
||||||
|
|
||||||
authWebappExample = templates.authWebapp {
|
|
||||||
name = "secure-app";
|
|
||||||
subdomain = "secure";
|
|
||||||
port = 9000;
|
|
||||||
};
|
|
||||||
|
|
||||||
containerExample = templates.containerService {
|
|
||||||
name = "gitea";
|
|
||||||
subdomain = "git";
|
|
||||||
containerName = "gitea";
|
|
||||||
port = 3000;
|
|
||||||
};
|
|
||||||
|
|
||||||
internalExample = templates.internalService {
|
|
||||||
name = "internal-api";
|
|
||||||
subdomain = "api-internal";
|
|
||||||
port = 8000;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 6: Custom domain and advanced configuration
|
|
||||||
customProxy = mkReverseProxy {
|
|
||||||
name = "custom-service";
|
|
||||||
subdomain = "custom";
|
|
||||||
url = "http://10.0.1.100:8080";
|
|
||||||
domain = "example.com";
|
|
||||||
priority = 20;
|
|
||||||
rule = "Host(`custom.example.com`) && PathPrefix(`/api`)";
|
|
||||||
middlewares = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"rate-limit"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example usage in a Traefik configuration:
|
|
||||||
#
|
|
||||||
# mjallen.services.traefik = {
|
|
||||||
# enable = true;
|
|
||||||
# extraServices = multipleProxies.extraServices;
|
|
||||||
# extraRouters = multipleProxies.extraRouters;
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# Or for individual proxies:
|
|
||||||
#
|
|
||||||
# mjallen.services.traefik = {
|
|
||||||
# enable = true;
|
|
||||||
# extraServices = [ simpleProxy.service ];
|
|
||||||
# extraRouters = [{
|
|
||||||
# inherit (simpleProxy.router) subdomain entryPoints middlewares;
|
|
||||||
# service = simpleProxy.router.service;
|
|
||||||
# }];
|
|
||||||
# };
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.mjallen.module) mkModule mkOpt mkBoolOpt;
|
|
||||||
in
|
|
||||||
mkModule {
|
|
||||||
name = "sops";
|
|
||||||
description = "SOPS secret management";
|
|
||||||
options = {
|
|
||||||
defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
|
|
||||||
|
|
||||||
generateAgeKey = mkBoolOpt true "Whether to automatically generate an age key if one doesn't exist.";
|
|
||||||
|
|
||||||
ageKeyPath =
|
|
||||||
mkOpt (lib.types.nullOr lib.types.str) null
|
|
||||||
"Custom path to the age key file. If null, will use the default path.";
|
|
||||||
|
|
||||||
sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [
|
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
|
||||||
] "SSH Key paths to use.";
|
|
||||||
|
|
||||||
validateSopsFiles = mkBoolOpt false "Whether to validate that sops files exist.";
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
sops = {
|
|
||||||
inherit (config.mjallen.sops) defaultSopsFile validateSopsFiles;
|
|
||||||
|
|
||||||
age = {
|
|
||||||
inherit (config.mjallen.sops) generateAgeKey;
|
|
||||||
|
|
||||||
keyFile =
|
|
||||||
if config.mjallen.sops.ageKeyPath != null then
|
|
||||||
config.mjallen.sops.ageKeyPath
|
|
||||||
else
|
|
||||||
"${config.users.users.${config.mjallen.user.name}.home}/.config/sops/age/keys.txt";
|
|
||||||
|
|
||||||
sshKeyPaths = config.mjallen.sops.sshKeyPaths;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
let
|
|
||||||
inherit (inputs.self.mjallen-lib.system.common)
|
|
||||||
mkExtendedLib
|
|
||||||
mkNixpkgsConfig
|
|
||||||
mkHomeConfigs
|
|
||||||
mkHomeManagerConfig
|
|
||||||
mkSpecialArgs
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Example of creating NixOS configurations
|
|
||||||
nixosConfigurations =
|
|
||||||
let
|
|
||||||
# Get all systems
|
|
||||||
allSystems = inputs.self.mjallen-lib.file.scanSystems ../systems;
|
|
||||||
|
|
||||||
# Filter for NixOS systems
|
|
||||||
nixosSystems = inputs.self.mjallen-lib.file.filterNixOSSystems allSystems;
|
|
||||||
in
|
|
||||||
inputs.nixpkgs.lib.mapAttrs' (
|
|
||||||
_name:
|
|
||||||
{ system, hostname, ... }:
|
|
||||||
let
|
|
||||||
# Create extended lib with mjallen-lib
|
|
||||||
extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
|
|
||||||
|
|
||||||
# Find matching home configurations for this system
|
|
||||||
matchingHomes = mkHomeConfigs {
|
|
||||||
flake = inputs.self;
|
|
||||||
inherit system hostname;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create home-manager configuration
|
|
||||||
homeManagerConfig = mkHomeManagerConfig {
|
|
||||||
inherit
|
|
||||||
extendedLib
|
|
||||||
inputs
|
|
||||||
system
|
|
||||||
matchingHomes
|
|
||||||
;
|
|
||||||
isNixOS = true;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
name = hostname;
|
|
||||||
value = inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
|
|
||||||
# Pass special arguments to modules
|
|
||||||
specialArgs = mkSpecialArgs {
|
|
||||||
inherit inputs hostname extendedLib;
|
|
||||||
username = "mjallen";
|
|
||||||
};
|
|
||||||
|
|
||||||
modules = [
|
|
||||||
# Set lib to extended lib
|
|
||||||
{ _module.args.lib = extendedLib; }
|
|
||||||
|
|
||||||
# Configure nixpkgs
|
|
||||||
{
|
|
||||||
nixpkgs = {
|
|
||||||
inherit system;
|
|
||||||
}
|
|
||||||
// mkNixpkgsConfig inputs.self;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Import home-manager module
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
|
|
||||||
# Auto-inject home configurations
|
|
||||||
homeManagerConfig
|
|
||||||
|
|
||||||
# Import all nixos modules recursively
|
|
||||||
../${system}/${hostname}
|
|
||||||
]
|
|
||||||
++ (extendedLib.mjallen.file.importModulesRecursive ../modules/nixos);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) nixosSystems;
|
|
||||||
|
|
||||||
# Example of creating home-manager configurations
|
|
||||||
homeConfigurations =
|
|
||||||
let
|
|
||||||
# Get all homes
|
|
||||||
allHomes = inputs.self.mjallen-lib.file.scanHomes ../homes;
|
|
||||||
in
|
|
||||||
inputs.nixpkgs.lib.mapAttrs' (
|
|
||||||
_name:
|
|
||||||
{
|
|
||||||
system,
|
|
||||||
username,
|
|
||||||
hostname,
|
|
||||||
userAtHost,
|
|
||||||
path,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
# Create extended lib with mjallen-lib
|
|
||||||
extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
name = userAtHost;
|
|
||||||
value = inputs.home-manager.lib.homeManagerConfiguration {
|
|
||||||
pkgs = import inputs.nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
inherit ((mkNixpkgsConfig inputs.self)) config overlays;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraSpecialArgs = {
|
|
||||||
inherit
|
|
||||||
inputs
|
|
||||||
hostname
|
|
||||||
username
|
|
||||||
system
|
|
||||||
;
|
|
||||||
inherit (inputs) self;
|
|
||||||
lib = extendedLib;
|
|
||||||
};
|
|
||||||
|
|
||||||
modules = [
|
|
||||||
# Set lib to extended lib
|
|
||||||
{ _module.args.lib = extendedLib; }
|
|
||||||
|
|
||||||
# Import the home configuration
|
|
||||||
path
|
|
||||||
]
|
|
||||||
++ (extendedLib.mjallen.file.importModulesRecursive ../modules/home);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) allHomes;
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
{ inputs, ... }@args:
|
|
||||||
let
|
|
||||||
# Get self from args or default to ../.. (the flake root)
|
|
||||||
self = if args ? self then args.self else ../..;
|
|
||||||
|
|
||||||
inherit (inputs.nixpkgs.lib)
|
|
||||||
genAttrs
|
|
||||||
filterAttrs
|
|
||||||
hasPrefix
|
|
||||||
foldl'
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Read a file and return its contents
|
|
||||||
readFile = path: builtins.readFile path;
|
|
||||||
|
|
||||||
# Check if a file exists
|
|
||||||
pathExists = path: builtins.pathExists path;
|
|
||||||
|
|
||||||
# Import a nix file with error handling
|
|
||||||
safeImport = path: default: if builtins.pathExists path then import path else default;
|
|
||||||
|
|
||||||
# Scan a directory and return directory names
|
|
||||||
scanDir = path: builtins.attrNames (builtins.readDir path);
|
|
||||||
|
|
||||||
# Get a file path relative to the flake root (similar to Snowfall's get-file)
|
|
||||||
getFile = relativePath: self + "/${relativePath}";
|
|
||||||
|
|
||||||
# Recursively discover and import all Nix modules in a directory tree
|
|
||||||
importModulesRecursive =
|
|
||||||
path:
|
|
||||||
let
|
|
||||||
# Helper function to recursively walk directories
|
|
||||||
walkDir =
|
|
||||||
currentPath:
|
|
||||||
let
|
|
||||||
currentEntries = builtins.readDir currentPath;
|
|
||||||
entryNames = builtins.attrNames currentEntries;
|
|
||||||
|
|
||||||
# Get all directories that contain default.nix
|
|
||||||
directoriesWithDefault = builtins.filter (
|
|
||||||
name:
|
|
||||||
currentEntries.${name} == "directory" && builtins.pathExists (currentPath + "/${name}/default.nix")
|
|
||||||
) entryNames;
|
|
||||||
|
|
||||||
# Get ALL directories (to recurse into)
|
|
||||||
allDirectories = builtins.filter (name: currentEntries.${name} == "directory") entryNames;
|
|
||||||
|
|
||||||
# Import directories that have default.nix
|
|
||||||
directoryImports = map (name: currentPath + "/${name}") directoriesWithDefault;
|
|
||||||
|
|
||||||
# Recursively walk ALL subdirectories
|
|
||||||
subDirImports = builtins.concatLists (map (dir: walkDir (currentPath + "/${dir}")) allDirectories);
|
|
||||||
|
|
||||||
in
|
|
||||||
directoryImports ++ subDirImports;
|
|
||||||
|
|
||||||
in
|
|
||||||
walkDir path;
|
|
||||||
|
|
||||||
# Recursively scan systems directory structure
|
|
||||||
scanSystems =
|
|
||||||
systemsPath:
|
|
||||||
let
|
|
||||||
systemArchs = builtins.attrNames (builtins.readDir systemsPath);
|
|
||||||
|
|
||||||
generateSystemConfigs =
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
systemPath = systemsPath + "/${system}";
|
|
||||||
hosts = builtins.attrNames (builtins.readDir systemPath);
|
|
||||||
in
|
|
||||||
genAttrs hosts (hostname: {
|
|
||||||
inherit system hostname;
|
|
||||||
path = systemPath + "/${hostname}";
|
|
||||||
});
|
|
||||||
in
|
|
||||||
foldl' (acc: system: acc // generateSystemConfigs system) { } systemArchs;
|
|
||||||
|
|
||||||
# Filter systems for NixOS (Linux)
|
|
||||||
filterNixOSSystems =
|
|
||||||
systems:
|
|
||||||
filterAttrs (
|
|
||||||
_name: { system, ... }: hasPrefix "x86_64-linux" system || hasPrefix "aarch64-linux" system
|
|
||||||
) systems;
|
|
||||||
|
|
||||||
# Filter systems for Darwin (macOS)
|
|
||||||
filterDarwinSystems =
|
|
||||||
systems:
|
|
||||||
filterAttrs (
|
|
||||||
_name: { system, ... }: hasPrefix "aarch64-darwin" system || hasPrefix "x86_64-darwin" system
|
|
||||||
) systems;
|
|
||||||
|
|
||||||
# Scan homes directory structure for home configurations
|
|
||||||
scanHomes =
|
|
||||||
homesPath:
|
|
||||||
let
|
|
||||||
systemArchs = builtins.attrNames (builtins.readDir homesPath);
|
|
||||||
|
|
||||||
generateHomeConfigs =
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
systemPath = homesPath + "/${system}";
|
|
||||||
userAtHosts = builtins.attrNames (builtins.readDir systemPath);
|
|
||||||
|
|
||||||
parseUserAtHost =
|
|
||||||
userAtHost:
|
|
||||||
let
|
|
||||||
# Split "username@hostname" into parts
|
|
||||||
parts = builtins.split "@" userAtHost;
|
|
||||||
username = builtins.head parts;
|
|
||||||
hostname = builtins.elemAt parts 2; # After split: [username, "@", hostname]
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit
|
|
||||||
system
|
|
||||||
username
|
|
||||||
hostname
|
|
||||||
userAtHost
|
|
||||||
;
|
|
||||||
path = systemPath + "/${userAtHost}";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
genAttrs userAtHosts parseUserAtHost;
|
|
||||||
in
|
|
||||||
foldl' (acc: system: acc // generateHomeConfigs system) { } systemArchs;
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib)
|
|
||||||
mapAttrs
|
|
||||||
mkOption
|
|
||||||
types
|
|
||||||
toUpper
|
|
||||||
substring
|
|
||||||
stringLength
|
|
||||||
mkDefault
|
|
||||||
mkForce
|
|
||||||
;
|
|
||||||
|
|
||||||
base64Lib = import ../base64 { inherit inputs; };
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
|
|
||||||
# Conditionally enable modules based on system
|
|
||||||
enableForSystem =
|
|
||||||
system: modules:
|
|
||||||
builtins.filter (
|
|
||||||
mod: mod.systems or [ ] == [ ] || builtins.elem system (mod.systems or [ ])
|
|
||||||
) modules;
|
|
||||||
|
|
||||||
# Create a module with common options
|
|
||||||
mkModule =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
description ? "",
|
|
||||||
options ? { },
|
|
||||||
config ? { },
|
|
||||||
}:
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
options.mjallen.${name} = lib.mkOption {
|
|
||||||
type = lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
enable = lib.mkEnableOption description;
|
|
||||||
}
|
|
||||||
// options;
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf config.mjallen.${name}.enable config;
|
|
||||||
};
|
|
||||||
|
|
||||||
mkContainer =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
localAddress ? "127.0.0.1",
|
|
||||||
ports ? [ "80" ],
|
|
||||||
bindMounts ? { },
|
|
||||||
config ? { },
|
|
||||||
}:
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
containers.${name} = {
|
|
||||||
inherit localAddress bindMounts;
|
|
||||||
|
|
||||||
config = config // {
|
|
||||||
networking = {
|
|
||||||
firewall = {
|
|
||||||
enable = true;
|
|
||||||
allowedTCPPorts = ports;
|
|
||||||
};
|
|
||||||
# Use systemd-resolved inside the container
|
|
||||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
|
||||||
useHostResolvConf = lib.mkForce false;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.resolved.enable = true;
|
|
||||||
system.stateVersion = "23.11";
|
|
||||||
};
|
|
||||||
autoStart = lib.mkDefault true;
|
|
||||||
privateNetwork = lib.mkDefault true;
|
|
||||||
hostAddress = lib.mkDefault "10.0.1.3";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
nat.forwardPorts = map (port: {
|
|
||||||
destination = lib.mkDefault "${localAddress}:${toString port}";
|
|
||||||
sourcePort = lib.mkDefault port;
|
|
||||||
}) ports;
|
|
||||||
firewall = {
|
|
||||||
allowedTCPPorts = ports;
|
|
||||||
allowedUDPPorts = ports;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Migrated mjallen utilities
|
|
||||||
# Option creation helpers
|
|
||||||
mkOpt =
|
|
||||||
type: default: description:
|
|
||||||
mkOption { inherit type default description; };
|
|
||||||
|
|
||||||
mkOpt' = type: default: mkOpt type default null;
|
|
||||||
|
|
||||||
mkBoolOpt = mkOpt types.bool;
|
|
||||||
|
|
||||||
mkBoolOpt' = mkOpt' types.bool;
|
|
||||||
|
|
||||||
mkReverseProxyOpt = {
|
|
||||||
enable = mkBoolOpt false "Enable reverse proxy support";
|
|
||||||
|
|
||||||
subdomain = mkOpt types.str "" "subdomain of the service";
|
|
||||||
|
|
||||||
middlewares = mkOpt (types.listOf types.str) [ ] "List of middlewares to use";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Standard enable/disable patterns
|
|
||||||
enabled = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
disabled = {
|
|
||||||
enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# String utilities
|
|
||||||
capitalize =
|
|
||||||
s:
|
|
||||||
let
|
|
||||||
len = stringLength s;
|
|
||||||
in
|
|
||||||
if len == 0 then "" else (toUpper (substring 0 1 s)) + (substring 1 len s);
|
|
||||||
|
|
||||||
# Boolean utilities
|
|
||||||
boolToNum = bool: if bool then 1 else 0;
|
|
||||||
|
|
||||||
# Attribute manipulation utilities
|
|
||||||
default-attrs = mapAttrs (_key: mkDefault);
|
|
||||||
|
|
||||||
force-attrs = mapAttrs (_key: mkForce);
|
|
||||||
|
|
||||||
nested-default-attrs = mapAttrs (_key: default-attrs);
|
|
||||||
|
|
||||||
nested-force-attrs = mapAttrs (_key: force-attrs);
|
|
||||||
}
|
|
||||||
// base64Lib
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib)
|
|
||||||
listToAttrs
|
|
||||||
nameValuePair
|
|
||||||
;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
# Create a service configuration for Traefik
|
|
||||||
mkService =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
loadBalancer ? { },
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit name url;
|
|
||||||
config = {
|
|
||||||
loadBalancer = {
|
|
||||||
servers = [ { inherit url; } ];
|
|
||||||
}
|
|
||||||
// loadBalancer;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create a router configuration for Traefik
|
|
||||||
mkRouter =
|
|
||||||
{
|
|
||||||
subdomain,
|
|
||||||
domain ? "mjallen.dev",
|
|
||||||
service,
|
|
||||||
entryPoints ? [ "websecure" ],
|
|
||||||
middlewares ? [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
],
|
|
||||||
priority ? null,
|
|
||||||
rule ? null,
|
|
||||||
tls ? {
|
|
||||||
certResolver = "letsencrypt";
|
|
||||||
},
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit
|
|
||||||
subdomain
|
|
||||||
service
|
|
||||||
entryPoints
|
|
||||||
middlewares
|
|
||||||
;
|
|
||||||
config = {
|
|
||||||
inherit
|
|
||||||
entryPoints
|
|
||||||
service
|
|
||||||
middlewares
|
|
||||||
tls
|
|
||||||
;
|
|
||||||
rule = if rule != null then rule else "Host(`${subdomain}.${domain}`)";
|
|
||||||
}
|
|
||||||
// (if priority != null then { inherit priority; } else { });
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create both service and router for a simple reverse proxy setup
|
|
||||||
mkReverseProxy =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
subdomain,
|
|
||||||
url,
|
|
||||||
domain ? "mjallen.dev",
|
|
||||||
entryPoints ? [ "websecure" ],
|
|
||||||
middlewares ? [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
],
|
|
||||||
priority ? null,
|
|
||||||
rule ? null,
|
|
||||||
tls ? {
|
|
||||||
certResolver = "letsencrypt";
|
|
||||||
},
|
|
||||||
loadBalancer ? { },
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
service = mkService {
|
|
||||||
inherit name url loadBalancer;
|
|
||||||
};
|
|
||||||
router = mkRouter {
|
|
||||||
inherit
|
|
||||||
subdomain
|
|
||||||
domain
|
|
||||||
entryPoints
|
|
||||||
middlewares
|
|
||||||
priority
|
|
||||||
rule
|
|
||||||
tls
|
|
||||||
;
|
|
||||||
service = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Convert a list of services to the format expected by Traefik module
|
|
||||||
servicesToConfig =
|
|
||||||
services: listToAttrs (map (service: nameValuePair service.name service.config) services);
|
|
||||||
|
|
||||||
# Convert a list of routers to the format expected by Traefik module
|
|
||||||
routersToConfig =
|
|
||||||
routers: listToAttrs (map (router: nameValuePair router.subdomain router.config) routers);
|
|
||||||
|
|
||||||
# Helper to create multiple reverse proxies at once
|
|
||||||
mkReverseProxies =
|
|
||||||
proxies:
|
|
||||||
let
|
|
||||||
results = map mkReverseProxy proxies;
|
|
||||||
services = map (result: result.service) results;
|
|
||||||
routers = map (result: result.router) results;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services = servicesToConfig services;
|
|
||||||
routers = routersToConfig routers;
|
|
||||||
extraServices = services;
|
|
||||||
extraRouters = map (router: {
|
|
||||||
inherit (router) subdomain entryPoints middlewares;
|
|
||||||
service = router.service;
|
|
||||||
}) routers;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Common middleware configurations
|
|
||||||
middlewares = {
|
|
||||||
# Authentication middleware
|
|
||||||
auth = [ "authentik" ];
|
|
||||||
|
|
||||||
# Basic security (default)
|
|
||||||
basic = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Internal only access
|
|
||||||
internal = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"internal-ipallowlist"
|
|
||||||
];
|
|
||||||
|
|
||||||
# WebSocket support
|
|
||||||
websocket = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"onlyoffice-websocket"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Authenticated with basic security
|
|
||||||
authBasic = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"authentik"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Common service URL builders
|
|
||||||
urls = {
|
|
||||||
# Local container service
|
|
||||||
container =
|
|
||||||
containerName: port: "http://\${config.containers.${containerName}.localAddress}:${toString port}";
|
|
||||||
|
|
||||||
# Local host service
|
|
||||||
localhost = port: "http://127.0.0.1:${toString port}";
|
|
||||||
|
|
||||||
# Network service
|
|
||||||
network = ip: port: "http://${ip}:${toString port}";
|
|
||||||
|
|
||||||
# Server IP service (using your server IP pattern)
|
|
||||||
server = port: "http://\${serverIp}:${toString port}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Pre-configured reverse proxy templates
|
|
||||||
templates = {
|
|
||||||
# Standard web application
|
|
||||||
webapp =
|
|
||||||
{ port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.localhost port;
|
|
||||||
middlewares = middlewares.basic;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
|
|
||||||
# Authenticated web application
|
|
||||||
authWebapp =
|
|
||||||
{ port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.localhost port;
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
|
|
||||||
# Container-based service
|
|
||||||
containerService =
|
|
||||||
{ containerName, port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.container containerName port;
|
|
||||||
middlewares = middlewares.basic;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
|
|
||||||
# Internal-only service
|
|
||||||
internalService =
|
|
||||||
{ port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.localhost port;
|
|
||||||
middlewares = middlewares.internal;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib) filterAttrs mapAttrs';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
mkExtendedLib =
|
|
||||||
flake: nixpkgs:
|
|
||||||
nixpkgs.lib.extend (
|
|
||||||
_final: _prev: {
|
|
||||||
mjallen = flake.mjallen-lib;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
mkNixpkgsConfig = flake: {
|
|
||||||
overlays = builtins.attrValues flake.overlays;
|
|
||||||
config = {
|
|
||||||
allowAliases = false;
|
|
||||||
allowUnfree = true;
|
|
||||||
permittedInsecurePackages = [
|
|
||||||
# Add any permitted insecure packages here
|
|
||||||
"mbedtls-2.28.10"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mkHomeConfigs =
|
|
||||||
{
|
|
||||||
flake,
|
|
||||||
system,
|
|
||||||
hostname,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (flake.mjallen-lib.file) scanHomes;
|
|
||||||
homesPath = ../../homes;
|
|
||||||
allHomes = scanHomes homesPath;
|
|
||||||
in
|
|
||||||
filterAttrs (
|
|
||||||
_name: homeConfig: homeConfig.system == system && homeConfig.hostname == hostname
|
|
||||||
) allHomes;
|
|
||||||
|
|
||||||
mkHomeManagerConfig =
|
|
||||||
{
|
|
||||||
extendedLib,
|
|
||||||
inputs,
|
|
||||||
system,
|
|
||||||
matchingHomes,
|
|
||||||
isNixOS ? true,
|
|
||||||
}:
|
|
||||||
if matchingHomes != { } then
|
|
||||||
{
|
|
||||||
home-manager = {
|
|
||||||
useGlobalPkgs = true;
|
|
||||||
useUserPackages = true;
|
|
||||||
extraSpecialArgs = {
|
|
||||||
inherit inputs system;
|
|
||||||
inherit (inputs) self;
|
|
||||||
lib = extendedLib;
|
|
||||||
};
|
|
||||||
sharedModules = [
|
|
||||||
{ _module.args.lib = extendedLib; }
|
|
||||||
]
|
|
||||||
++ (extendedLib.mjallen.file.importModulesRecursive ../../modules/home);
|
|
||||||
users = mapAttrs' (_name: homeConfig: {
|
|
||||||
name = homeConfig.username;
|
|
||||||
value = {
|
|
||||||
imports = [ homeConfig.path ];
|
|
||||||
home = {
|
|
||||||
inherit (homeConfig) username;
|
|
||||||
homeDirectory = inputs.nixpkgs.lib.mkDefault (
|
|
||||||
if isNixOS then "/home/${homeConfig.username}" else "/Users/${homeConfig.username}"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if isNixOS then
|
|
||||||
{
|
|
||||||
_module.args.username = homeConfig.username;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ }
|
|
||||||
);
|
|
||||||
}) matchingHomes;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ };
|
|
||||||
|
|
||||||
mkSpecialArgs =
|
|
||||||
{
|
|
||||||
inputs,
|
|
||||||
hostname,
|
|
||||||
username,
|
|
||||||
extendedLib,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit inputs hostname username;
|
|
||||||
inherit (inputs) self;
|
|
||||||
lib = extendedLib;
|
|
||||||
namespace = "mjallen";
|
|
||||||
format = "system";
|
|
||||||
host = hostname;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
{
|
|
||||||
# Common utilities used by system builders
|
|
||||||
common = import ./common.nix { inherit inputs; };
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
options,
|
|
||||||
namespace,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
options.${namespace}.home = with lib.types; {
|
|
||||||
configFile = lib.mkOption {
|
|
||||||
type = attrs;
|
|
||||||
default = { };
|
|
||||||
description = "A set of files to be managed by home-manager's <option>xdg.configFile</option>.";
|
|
||||||
};
|
|
||||||
extraOptions = lib.mkOption {
|
|
||||||
type = attrs;
|
|
||||||
default = { };
|
|
||||||
description = "Options to pass directly to home-manager.";
|
|
||||||
};
|
|
||||||
file = lib.mkOption {
|
|
||||||
type = attrs;
|
|
||||||
default = { };
|
|
||||||
description = "A set of files to be managed by home-manager's <option>home.file</option>.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
home-manager = {
|
|
||||||
# enables backing up existing files instead of erroring if conflicts exist
|
|
||||||
backupFileExtension = "backup";
|
|
||||||
|
|
||||||
useGlobalPkgs = true;
|
|
||||||
useUserPackages = true;
|
|
||||||
|
|
||||||
# Pass inputs so external modules can access them
|
|
||||||
extraSpecialArgs = {
|
|
||||||
inherit inputs namespace;
|
|
||||||
overlays = with inputs; [
|
|
||||||
nix-vscode-extensions.overlays.default
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Make ALL external HM modules available globally
|
|
||||||
sharedModules = with inputs; [
|
|
||||||
sops-nix.homeManagerModules.sops
|
|
||||||
nix-plist-manager.homeManagerModules.default
|
|
||||||
nix-index-database.homeModules.nix-index
|
|
||||||
stylix.homeModules.stylix
|
|
||||||
# Add any other external HM modules here
|
|
||||||
];
|
|
||||||
|
|
||||||
users."mattjallen" = lib.mkAliasDefinitions options.${namespace}.home.extraOptions;
|
|
||||||
|
|
||||||
verbose = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
config = {
|
|
||||||
programs.ssh.knownHosts = {
|
|
||||||
desktop = {
|
|
||||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTBMydhOc6SnOdB5WrEd7X07DrboAtagCUgXiOJjLov matt@matt-nixos";
|
|
||||||
};
|
|
||||||
nas = {
|
|
||||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIwoHWOLSTGVif9hAhaMLl0qDA4roIzCNuyR6kyIXDOj admin@jallen-nas";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
410
modules/home/desktop/hyprland/default.nix
Executable file
410
modules/home/desktop/hyprland/default.nix
Executable file
@@ -0,0 +1,410 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mjallen.desktop.hyprland;
|
||||||
|
drawer = "nwg-drawer -fm nautilus -term kitty -mb 10 -mt 10 -ml 10 -mr 10 -pbuseicontheme -i ${cfg.iconThemeName}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./options.nix
|
||||||
|
./packages.nix
|
||||||
|
./theme.nix
|
||||||
|
./variables.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
services = {
|
||||||
|
hyprpolkitagent.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
vscode.profiles.default.userSettings."window"."titleBarStyle" = "custom";
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
xwayland.enable = true;
|
||||||
|
systemd.enable = true;
|
||||||
|
|
||||||
|
plugins = with pkgs.hyprlandPlugins; [
|
||||||
|
hyprgrass
|
||||||
|
];
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
"$mod" = "SUPER";
|
||||||
|
|
||||||
|
# Mouse
|
||||||
|
# mouse_[up|down] - scroll wheel
|
||||||
|
# middle_mouse - 274
|
||||||
|
# thumb_up - 276
|
||||||
|
# thumb_down - 275
|
||||||
|
|
||||||
|
# l -> locked, will also work when an input inhibitor (e.g. a lockscreen) is active.
|
||||||
|
# r -> release, will trigger on release of a key.
|
||||||
|
# e -> repeat, will repeat when held.
|
||||||
|
# n -> non-consuming, key/mouse events will be passed to the active window in addition to triggering the dispatcher.
|
||||||
|
# m -> mouse, see below.
|
||||||
|
# t -> transparent, cannot be shadowed by other binds.
|
||||||
|
# i -> ignore mods, will ignore modifiers.
|
||||||
|
# s -> separate, will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos) above.
|
||||||
|
# d -> has description, will allow you to write a description for your bind.
|
||||||
|
# p -> bypasses the app's requests to inhibit keybinds.
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Binds/
|
||||||
|
# https://wiki.hyprland.org/Configuring/Binds/#mouse-buttons
|
||||||
|
|
||||||
|
bind = [
|
||||||
|
"$mod, Return, exec, ${cfg.defaultApps.terminal.pname}"
|
||||||
|
"$mod, SPACE, exec, wofi --show drun"
|
||||||
|
", xf86Search, exec, wofi --show drun"
|
||||||
|
"$mod, Q, killactive, "
|
||||||
|
"$mod, M, exec, wlogout --protocol layer-shell"
|
||||||
|
"$mod, E, exec, ${cfg.defaultApps.fileExplorer.pname}"
|
||||||
|
"$mod, V, togglefloating, "
|
||||||
|
"$mod, D, exec, ${drawer}"
|
||||||
|
"$mod, P, pseudo, " # dwindle
|
||||||
|
"$mod, S, togglesplit, " # dwindle
|
||||||
|
"$mod SHIFT, Q, exec, hyprlock"
|
||||||
|
"$mod SHIFT, 4, exec, hyprshot -m region --clipboard-only"
|
||||||
|
"$mod, F, fullscreen, 1"
|
||||||
|
"$mod SHIFT, F, fullscreen, 0"
|
||||||
|
"$mod SHIFT, E, exec, smile"
|
||||||
|
|
||||||
|
"$mod, mouse:276, movecurrentworkspacetomonitor, ${cfg.display1.input}"
|
||||||
|
"$mod, mouse:275, movecurrentworkspacetomonitor, ${cfg.display2.input}"
|
||||||
|
|
||||||
|
# alt-tab between workspaces on active monitor
|
||||||
|
"$mod, Tab, workspace, m+1"
|
||||||
|
"$mod SHIFT, Tab, workspace, m-1"
|
||||||
|
|
||||||
|
"$mod, h, movefocus, l"
|
||||||
|
"$mod, l, movefocus, r"
|
||||||
|
"$mod, k, movefocus, u"
|
||||||
|
"$mod, j, movefocus, d"
|
||||||
|
|
||||||
|
"$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, 0, workspace, 10"
|
||||||
|
|
||||||
|
"$mod ALT, 1, movetoworkspace, 1"
|
||||||
|
"$mod ALT, 2, movetoworkspace, 2"
|
||||||
|
"$mod ALT, 3, movetoworkspace, 3"
|
||||||
|
"$mod ALT, 4, movetoworkspace, 4"
|
||||||
|
"$mod ALT, 5, movetoworkspace, 5"
|
||||||
|
"$mod ALT, 6, movetoworkspace, 6"
|
||||||
|
"$mod ALT, 7, movetoworkspace, 7"
|
||||||
|
"$mod ALT, 8, movetoworkspace, 8"
|
||||||
|
"$mod ALT, 9, movetoworkspace, 9"
|
||||||
|
"$mod ALT, 0, movetoworkspace, discord"
|
||||||
|
|
||||||
|
"$mod CTRL, l, resizeactive, 10 0"
|
||||||
|
"$mod CTRL, h, resizeactive, -10 0"
|
||||||
|
"$mod CTRL, k, resizeactive, 0 -10"
|
||||||
|
"$mod CTRL, j, resizeactive, 0 10"
|
||||||
|
|
||||||
|
"$mod SHIFT, l, movewindow, r"
|
||||||
|
"$mod SHIFT, h, movewindow, l"
|
||||||
|
"$mod SHIFT, k, movewindow, u"
|
||||||
|
"$mod SHIFT, j, movewindow, d"
|
||||||
|
|
||||||
|
"$mod, b, exec, ${cfg.defaultApps.browser.pname}"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindm = [
|
||||||
|
# Move/resize windows with mod + LMB/RMB and dragging
|
||||||
|
"$mod, mouse:272, movewindow"
|
||||||
|
"$mod, mouse:273, resizewindow"
|
||||||
|
# middle mouse will grab a window, mod + middle mouse will close it
|
||||||
|
"$mod SHIFT, mouse:274, movewindow"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindel = [
|
||||||
|
", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
|
||||||
|
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindl = [
|
||||||
|
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
|
||||||
|
", XF86AudioPlay, exec, playerctl play-pause"
|
||||||
|
", XF86AudioPrev, exec, playerctl previous"
|
||||||
|
", XF86AudioNext, exec, playerctl next"
|
||||||
|
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
|
||||||
|
|
||||||
|
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
|
||||||
|
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
|
||||||
|
|
||||||
|
"$mod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight set +10%"
|
||||||
|
"$mod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight set 10%-"
|
||||||
|
];
|
||||||
|
|
||||||
|
monitor = cfg.monitor;
|
||||||
|
monitorv2 = cfg.monitorv2 or { };
|
||||||
|
|
||||||
|
render = {
|
||||||
|
cm_fs_passthrough = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
misc = {
|
||||||
|
vrr = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
general = {
|
||||||
|
gaps_in = 5;
|
||||||
|
gaps_out = 10;
|
||||||
|
border_size = 1;
|
||||||
|
"col.active_border" = "rgb(8aadf4) rgb(24273A) rgb(24273A) rgb(8aadf4) 45deg";
|
||||||
|
"col.inactive_border" = "rgb(24273A) rgb(24273A) rgb(24273A) rgb(24273A) 45deg";
|
||||||
|
layout = "dwindle";
|
||||||
|
allow_tearing = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
decoration = {
|
||||||
|
rounding = 10;
|
||||||
|
blur = {
|
||||||
|
enabled = true;
|
||||||
|
size = 2;
|
||||||
|
passes = 2;
|
||||||
|
new_optimizations = true;
|
||||||
|
xray = false;
|
||||||
|
};
|
||||||
|
# drop_shadow = "yes";
|
||||||
|
# shadow_range = 4;
|
||||||
|
# shadow_render_power = "3";
|
||||||
|
# "col.shadow" = "rgba(1a1a1aee)";
|
||||||
|
};
|
||||||
|
|
||||||
|
animations = {
|
||||||
|
enabled = "yes";
|
||||||
|
bezier = [
|
||||||
|
"overshot, 0.05, 0.9, 0.1, 1.05"
|
||||||
|
"smoothOut, 0.36, 0, 0.66, -0.56"
|
||||||
|
"smoothIn, 0.25, 1, 0.5, 1"
|
||||||
|
];
|
||||||
|
animation = [
|
||||||
|
"windows, 1, 5, overshot, slide"
|
||||||
|
"windowsOut, 1, 4, smoothOut, slide"
|
||||||
|
"windowsMove, 1, 4, default"
|
||||||
|
"border, 1, 10, default"
|
||||||
|
"fade, 1, 10, smoothIn"
|
||||||
|
"fadeDim, 1, 10, smoothIn"
|
||||||
|
"workspaces, 1, 6, default"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
dwindle = {
|
||||||
|
pseudotile = "yes";
|
||||||
|
preserve_split = "yes";
|
||||||
|
};
|
||||||
|
|
||||||
|
misc = {
|
||||||
|
force_default_wallpaper = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
workspace = cfg.workspace;
|
||||||
|
|
||||||
|
windowrule = [
|
||||||
|
"float, title:(file_progress)"
|
||||||
|
"float, title:(.*[Cc]onfirm.*)"
|
||||||
|
"float, title:(.*[Dd]ialog.*)"
|
||||||
|
"float, title:(.*[Dd]ownload.*)"
|
||||||
|
"float, title:(.*[Nn]otification.*)"
|
||||||
|
"float, title:(.*[Ee]rror.*)"
|
||||||
|
"float, title:(.*[Ss]plash.*)"
|
||||||
|
"float, title:(.*[Cc]onfirmreset.*)"
|
||||||
|
"float, title:(.*[Ss]ign [Ii]n - .*)"
|
||||||
|
"float, title:(.*[Oo]pen [Ff]ile.*)"
|
||||||
|
"float, title:(.*branchdialog.*)"
|
||||||
|
"float, class:(.*pavucontrol.*)"
|
||||||
|
"move onscreen cursor 0% 0%, class:(.*pavucontrol.*)"
|
||||||
|
"float, class:(.*[Oo]verskride.*)"
|
||||||
|
"float, class:(.*FileRoller.*)"
|
||||||
|
"float, class:(.*wlogout.*)"
|
||||||
|
"idleinhibit stayfocused, title:(.*mpv.*)"
|
||||||
|
|
||||||
|
"float, class:(.*nm-connection-editor.*)"
|
||||||
|
"move onscreen cursor 0% 0%, class:(.*nm-connection-editor.*)"
|
||||||
|
|
||||||
|
"float, title:(Media viewer)"
|
||||||
|
"float, class:(it.mijorus.smile),title:(Smile)"
|
||||||
|
"float, class:(.blueman-manager-wrapped)$,title:(Bluetooth Devices)"
|
||||||
|
# Picture in picture windows
|
||||||
|
"float, title:(.*Picture-in-Picture.*)"
|
||||||
|
"pin, title::(.*Picture-in-Picture.*)"
|
||||||
|
|
||||||
|
# discord/vesktop
|
||||||
|
"workspace: name:discord, class:(.*vesktop)"
|
||||||
|
"float, class:(.*vesktop),title:(.*Discord Popout.*)"
|
||||||
|
"pin, class:(.*vesktop),title:(.*Discord Popout.*)"
|
||||||
|
|
||||||
|
# Music
|
||||||
|
"workspace: name:discord, class:(Apple Music.*)"
|
||||||
|
|
||||||
|
# Steam
|
||||||
|
"float, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
||||||
|
"workspace name:steam silent, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
||||||
|
"tile, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
||||||
|
"float, class:(.*steam),title:(.*Friends List.*)"
|
||||||
|
|
||||||
|
# Code
|
||||||
|
"pin, class:(.*codium.*),title:(Save As)"
|
||||||
|
"float, class:(.*codium.*),title:(Save As)"
|
||||||
|
"float, class:(xdg-desktop-portal-gtk),title:(Open Workspace from File)"
|
||||||
|
|
||||||
|
# Game Tearing??? https://wiki.hyprland.org/Configuring/Tearing/
|
||||||
|
"immediate, class:(.*gamescope)"
|
||||||
|
|
||||||
|
# vmware
|
||||||
|
# this tag will set the below options to the vdi window
|
||||||
|
# this will have it auto open as a 2160x7680 window
|
||||||
|
# and makes multi-monitor work
|
||||||
|
"tag +horizonrdp, class:(.*[Hh]orizon-client),title:(USPS Next VDI)"
|
||||||
|
|
||||||
|
"noanim, tag:horizonrdp"
|
||||||
|
"noblur, tag:horizonrdp"
|
||||||
|
"norounding, tag:horizonrdp"
|
||||||
|
"noshadow, tag:horizonrdp"
|
||||||
|
"immediate, tag:horizonrdp"
|
||||||
|
"allowsinput, tag:horizonrdp"
|
||||||
|
"noborder, tag:horizonrdp"
|
||||||
|
"nodim, tag:horizonrdp"
|
||||||
|
"nomaxsize, tag:horizonrdp"
|
||||||
|
"renderunfocused, tag:horizonrdp"
|
||||||
|
"idleinhibit, tag:horizonrdp"
|
||||||
|
"float, tag:horizonrdp"
|
||||||
|
# "size 2160 7680, tag:horizonrdp"
|
||||||
|
# "move onscreen 0 0, tag:horizonrdp"
|
||||||
|
# float the vmware window cause its annoying to use in fullscreen
|
||||||
|
"float, class:(.*[Hh]orizon-client),title:([Oo]mnissa [Hh]orizon [Cc]lient)"
|
||||||
|
|
||||||
|
"tag +waydroid, class:([Ww]aydroid.*)"
|
||||||
|
"float, tag:waydroid"
|
||||||
|
"pin, tag:waydroid"
|
||||||
|
]
|
||||||
|
++ cfg.windowRule;
|
||||||
|
|
||||||
|
plugin = {
|
||||||
|
touch_gestures = {
|
||||||
|
# The default sensitivity is probably too low on tablet screens,
|
||||||
|
# I recommend turning it up to 4.0
|
||||||
|
sensitivity = "4.0";
|
||||||
|
|
||||||
|
# must be >= 3
|
||||||
|
workspace_swipe_fingers = "3";
|
||||||
|
|
||||||
|
# switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers
|
||||||
|
# and can be used at the same time
|
||||||
|
# possible values: l, r, u, or d
|
||||||
|
# to disable it set it to anything else
|
||||||
|
workspace_swipe_edge = "d";
|
||||||
|
|
||||||
|
# in milliseconds
|
||||||
|
long_press_delay = "400";
|
||||||
|
|
||||||
|
# resize windows by long-pressing on window borders and gaps.
|
||||||
|
# If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating
|
||||||
|
# windows
|
||||||
|
resize_on_border_long_press = true;
|
||||||
|
|
||||||
|
# in pixels, the distance from the edge that is considered an edge
|
||||||
|
edge_margin = "10";
|
||||||
|
|
||||||
|
# emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe.
|
||||||
|
# ONLY triggers when finger count is equal to workspace_swipe_fingers
|
||||||
|
#
|
||||||
|
# might be removed in the future in favor of event hooks
|
||||||
|
emulate_touchpad_swipe = false;
|
||||||
|
|
||||||
|
experimental = {
|
||||||
|
# send proper cancel events to windows instead of hacky touch_up events,
|
||||||
|
# NOT recommended as it crashed a few times, once it's stabilized I'll make it the default
|
||||||
|
send_cancel = "0";
|
||||||
|
};
|
||||||
|
|
||||||
|
hyprgrass-bind = [
|
||||||
|
# swipe left from right edge
|
||||||
|
", edge:r:l, workspace, +1"
|
||||||
|
|
||||||
|
# swipe up from bottom edge
|
||||||
|
", edge:d:u, exec, ${cfg.defaultApps.browser.pname}"
|
||||||
|
|
||||||
|
# swipe down from left edge
|
||||||
|
", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%"
|
||||||
|
|
||||||
|
# swipe down with 4 fingers
|
||||||
|
", swipe:4:d, killactive"
|
||||||
|
|
||||||
|
# swipe diagonally left and down with 3 fingers
|
||||||
|
# l (or r) must come before d and u
|
||||||
|
", swipe:3:ld, exec, foot"
|
||||||
|
|
||||||
|
# tap with 3 fingers
|
||||||
|
", tap:3, exec, foot"
|
||||||
|
|
||||||
|
# longpress can trigger mouse binds:
|
||||||
|
", longpress:2, movewindow"
|
||||||
|
", longpress:3, resizewindow"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gestures = {
|
||||||
|
workspace_swipe = true;
|
||||||
|
workspace_swipe_cancel_ratio = "0.15";
|
||||||
|
};
|
||||||
|
|
||||||
|
input = {
|
||||||
|
kb_layout = "us";
|
||||||
|
|
||||||
|
kb_variant = "";
|
||||||
|
kb_model = "";
|
||||||
|
kb_options = "";
|
||||||
|
kb_rules = "";
|
||||||
|
|
||||||
|
numlock_by_default = true;
|
||||||
|
|
||||||
|
follow_mouse = 1;
|
||||||
|
|
||||||
|
touchpad = {
|
||||||
|
clickfinger_behavior = 1;
|
||||||
|
natural_scroll = "yes";
|
||||||
|
};
|
||||||
|
|
||||||
|
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
|
||||||
|
};
|
||||||
|
|
||||||
|
experimental = {
|
||||||
|
xx_color_management_v4 = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
debug = {
|
||||||
|
full_cm_proto = true;
|
||||||
|
disable_logs = true;
|
||||||
|
disable_scale_checks = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
exec-once = dbus-update-activation-environment --systemd --all
|
||||||
|
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||||
|
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
||||||
|
exec-once = xhost +SI:localuser:root
|
||||||
|
exec-once = nwg-look -a
|
||||||
|
exec-once = nwg-dock-hyprland -d
|
||||||
|
''
|
||||||
|
+ cfg.extraConfig or '''';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
147
modules/home/desktop/hyprland/options.nix
Normal file
147
modules/home/desktop/hyprland/options.nix
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
{ lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.mjallen.desktop.hyprland = {
|
||||||
|
enable = mkEnableOption "enable hyprland desktop";
|
||||||
|
|
||||||
|
primaryDisplay = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "DP-1";
|
||||||
|
};
|
||||||
|
|
||||||
|
display1 = {
|
||||||
|
input = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "DP-1";
|
||||||
|
};
|
||||||
|
|
||||||
|
resolution = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "3840x2160";
|
||||||
|
};
|
||||||
|
|
||||||
|
refreshRate = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "240.00000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
display2 = {
|
||||||
|
input = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "DP-1";
|
||||||
|
};
|
||||||
|
|
||||||
|
resolution = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "3840x2160";
|
||||||
|
};
|
||||||
|
|
||||||
|
refreshRate = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "240.00000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
wallpaper = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of hyprland wallpaper configs";
|
||||||
|
};
|
||||||
|
|
||||||
|
monitor = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of hyprland monitor configs";
|
||||||
|
};
|
||||||
|
|
||||||
|
monitorv2 = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of hyprland monitorv2 configs";
|
||||||
|
};
|
||||||
|
|
||||||
|
workspace = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of hyprland workspace definitions";
|
||||||
|
};
|
||||||
|
|
||||||
|
windowRule = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of hyprland window rules";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; str;
|
||||||
|
default = '''';
|
||||||
|
description = "any extra options";
|
||||||
|
};
|
||||||
|
|
||||||
|
iconThemeName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Colloid-Dark";
|
||||||
|
};
|
||||||
|
|
||||||
|
gtkThemeName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Colloid-Dark";
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultApps = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = {
|
||||||
|
browser = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.firefox;
|
||||||
|
};
|
||||||
|
editor = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.micro;
|
||||||
|
};
|
||||||
|
fileExplorer = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.nemo;
|
||||||
|
};
|
||||||
|
visual = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.vscodium;
|
||||||
|
};
|
||||||
|
terminal = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.kitty;
|
||||||
|
};
|
||||||
|
office = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.onlyoffice-bin_latest;
|
||||||
|
};
|
||||||
|
video = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.vlc;
|
||||||
|
};
|
||||||
|
imageViewer = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.nomacs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = "Default applications used across the system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
hyprIdle = {
|
||||||
|
lockScreenTimer = mkOption {
|
||||||
|
type = with types; int;
|
||||||
|
default = 300;
|
||||||
|
};
|
||||||
|
screenOffTimer = mkOption {
|
||||||
|
type = with types; int;
|
||||||
|
default = 900;
|
||||||
|
};
|
||||||
|
suspendTimer = mkOption {
|
||||||
|
type = with types; int;
|
||||||
|
default = 1800;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
74
modules/home/desktop/hyprland/packages.nix
Normal file
74
modules/home/desktop/hyprland/packages.nix
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mjallen.desktop.hyprland;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
box64
|
||||||
|
brightnessctl
|
||||||
|
ddcutil
|
||||||
|
dunst
|
||||||
|
egl-wayland
|
||||||
|
file-roller
|
||||||
|
glib
|
||||||
|
gnome-calculator
|
||||||
|
gnome-calendar
|
||||||
|
gnome-disk-utility
|
||||||
|
gnome-firmware
|
||||||
|
gnome-firmware-updater
|
||||||
|
gnome-font-viewer
|
||||||
|
gnome-logs
|
||||||
|
gnome-photos
|
||||||
|
gnome-tweaks
|
||||||
|
gnome-weather
|
||||||
|
gsettings-desktop-schemas
|
||||||
|
hyprcursor
|
||||||
|
hyprland
|
||||||
|
hyprpaper
|
||||||
|
hyprshot
|
||||||
|
hyprsysteminfo
|
||||||
|
kdePackages.qtmultimedia
|
||||||
|
libnotify
|
||||||
|
libz
|
||||||
|
mako
|
||||||
|
meson
|
||||||
|
nautilus
|
||||||
|
networkmanagerapplet
|
||||||
|
nm-tray
|
||||||
|
nomacs
|
||||||
|
nwg-look
|
||||||
|
overskride
|
||||||
|
pamixer
|
||||||
|
pavucontrol
|
||||||
|
playerctl
|
||||||
|
polkit
|
||||||
|
polkit_gnome
|
||||||
|
qt5.qtwayland
|
||||||
|
qt6.qtwayland
|
||||||
|
rofi-wayland
|
||||||
|
waybar
|
||||||
|
wayland-protocols
|
||||||
|
wayland-utils
|
||||||
|
waypaper
|
||||||
|
wev
|
||||||
|
wl-clipboard
|
||||||
|
wlogout
|
||||||
|
wlroots
|
||||||
|
xdg-desktop-portal-hyprland
|
||||||
|
xdg-desktop-portal-gtk
|
||||||
|
xdg-desktop-portal-wlr
|
||||||
|
xorg.xhost
|
||||||
|
xsettingsd
|
||||||
|
xwayland
|
||||||
|
|
||||||
|
pkgs.mjallen.pipewire-python
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
46
modules/home/desktop/hyprland/services/hypridle/default.nix
Normal file
46
modules/home/desktop/hyprland/services/hypridle/default.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.desktop.hyprland;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ../../options.nix ];
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.hypridle = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
general = {
|
||||||
|
before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
|
||||||
|
after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
|
||||||
|
ignore_dbus_inhibit = false;
|
||||||
|
lock_cmd = "pidof hyprlock || hyprlock"; # avoid starting multiple hyprlock instances.
|
||||||
|
};
|
||||||
|
listener = [
|
||||||
|
# {
|
||||||
|
# timeout = 300; # 5min
|
||||||
|
# on-timeout = "brightnessctl -s set 10"; # set monitor backlight to minimum, avoid 0 on OLED monitor.
|
||||||
|
# on-resume = "brightnessctl -r"; # monitor backlight restore.
|
||||||
|
# }
|
||||||
|
{
|
||||||
|
timeout = cfg.hyprIdle.lockScreenTimer;
|
||||||
|
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = cfg.hyprIdle.screenOffTimer;
|
||||||
|
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
|
||||||
|
on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired.
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = cfg.hyprIdle.suspendTimer;
|
||||||
|
on-timeout = "systemctl suspend"; # suspend pc
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
52
modules/home/desktop/hyprland/services/hyprlock/default.nix
Normal file
52
modules/home/desktop/hyprland/services/hyprlock/default.nix
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.desktop.hyprland;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ../../options.nix ];
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.hyprlock = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
background = [
|
||||||
|
{
|
||||||
|
monitor = "";
|
||||||
|
path = cfg.wallpaper; # supports png, jpg, webp (no animations, though)
|
||||||
|
color = "rgba(25, 20, 20, 1.0)";
|
||||||
|
|
||||||
|
# all these options are taken from hyprland, see https://wiki.hyprland.org/Configuring/Variables/#blur for explanations
|
||||||
|
blur_passes = "3"; # 0 disables blurring
|
||||||
|
blur_size = "7";
|
||||||
|
noise = "0.0117";
|
||||||
|
contrast = "0.8916";
|
||||||
|
brightness = "0.8172";
|
||||||
|
vibrancy = "0.1696";
|
||||||
|
vibrancy_darkness = "0.0";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
input-field = [
|
||||||
|
{
|
||||||
|
size = "200, 50";
|
||||||
|
position = "0, -80";
|
||||||
|
monitor = cfg.primaryDisplay;
|
||||||
|
dots_center = true;
|
||||||
|
fade_on_empty = true;
|
||||||
|
font_color = "rgb(202, 211, 245)";
|
||||||
|
inner_color = "rgb(91, 96, 120)";
|
||||||
|
outer_color = "rgb(24, 25, 38)";
|
||||||
|
bothlock_color = -1;
|
||||||
|
outline_thickness = 5;
|
||||||
|
placeholder_text = ''<span foreground="##cad3f5">Password...</span>'';
|
||||||
|
shadow_passes = 2;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
23
modules/home/desktop/hyprland/services/hyprpaper/default.nix
Normal file
23
modules/home/desktop/hyprland/services/hyprpaper/default.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.desktop.hyprland;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ../../options.nix ];
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.hyprpaper = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
preload = [ "/run/wallpaper.jpg" ];
|
||||||
|
wallpaper = ",/run/wallpaper.jpg";
|
||||||
|
splash = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
103
modules/home/desktop/hyprland/theme.nix
Normal file
103
modules/home/desktop/hyprland/theme.nix
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mjallen.desktop.hyprland;
|
||||||
|
|
||||||
|
themeSize = "compact"; # [ "standard" "compact" ]
|
||||||
|
themeAccent = "all"; # [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ]
|
||||||
|
themeVariant = "nord"; # [ "nord" "dracula" "gruvbox" "everforest" "catppuccin" "all" "black" "rimless" "normal" "float" ]
|
||||||
|
themeColor = "dark"; # [ "standard" "light" "dark" ]
|
||||||
|
iconThemeVariant = "all"; # [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ]
|
||||||
|
iconScheme = "nord"; # [ "default" "nord" "dracula" "gruvbox" "everforest" "catppuccin" "all" ]
|
||||||
|
|
||||||
|
# Cursor
|
||||||
|
cursorTheme = "macOS";
|
||||||
|
cursorThemePkg = pkgs.apple-cursor;
|
||||||
|
cursorSize = 24;
|
||||||
|
|
||||||
|
# GTK
|
||||||
|
# gtkThemeSize = themeSize;
|
||||||
|
# gtkThemeAccent = themeAccent;
|
||||||
|
# gtkThemeVariant = themeVariant;
|
||||||
|
# gtkThemeColor = themeColor;
|
||||||
|
gtkTheme = "Colloid-Dark-Compact-Nord";
|
||||||
|
gtkThemePkg = pkgs.colloid-gtk-theme.override {
|
||||||
|
sizeVariants = [ themeSize ];
|
||||||
|
colorVariants = [ themeColor ];
|
||||||
|
themeVariants = [ themeAccent ];
|
||||||
|
tweaks = [ themeVariant ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Icons
|
||||||
|
# iconThemeScheme = iconScheme;
|
||||||
|
iconTheme = "Colloid-Nord-Dark";
|
||||||
|
iconThemePkg = pkgs.colloid-icon-theme.override {
|
||||||
|
schemeVariants = [ iconScheme ];
|
||||||
|
colorVariants = [ iconThemeVariant ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Fonts
|
||||||
|
fontName = "JetBrainsMono NFM";
|
||||||
|
fontPackage = pkgs.nerd-fonts.jetbrains-mono;
|
||||||
|
fontSize = 12;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home = {
|
||||||
|
pointerCursor = {
|
||||||
|
gtk.enable = true;
|
||||||
|
package = cursorThemePkg;
|
||||||
|
name = cursorTheme;
|
||||||
|
size = cursorSize;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
dconf = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
"org/gnome/desktop/interface".color-scheme = "prefer-dark";
|
||||||
|
"org/gnome/desktop/interface".cursor-theme = cursorTheme;
|
||||||
|
"org/gnome/desktop/interface".gtk-theme = gtkTheme;
|
||||||
|
"org/gnome/desktop/interface".icon-theme = iconTheme;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
cursorTheme = {
|
||||||
|
name = cursorTheme;
|
||||||
|
package = cursorThemePkg;
|
||||||
|
};
|
||||||
|
|
||||||
|
theme = {
|
||||||
|
name = gtkTheme;
|
||||||
|
package = gtkThemePkg;
|
||||||
|
};
|
||||||
|
|
||||||
|
iconTheme = {
|
||||||
|
name = iconTheme;
|
||||||
|
package = iconThemePkg;
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk3.extraConfig = {
|
||||||
|
gtk-application-prefer-dark-theme = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk4.extraConfig = {
|
||||||
|
gtk-application-prefer-dark-theme = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
font = {
|
||||||
|
name = fontName;
|
||||||
|
package = fontPackage;
|
||||||
|
size = fontSize;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
39
modules/home/desktop/hyprland/variables.nix
Normal file
39
modules/home/desktop/hyprland/variables.nix
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mjallen.desktop.hyprland;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.sessionVariables = {
|
||||||
|
BROWSER = "${cfg.defaultApps.browser.pname}";
|
||||||
|
CLUTTER_BACKEND = "wayland";
|
||||||
|
EDITOR = "${cfg.defaultApps.editor.pname}";
|
||||||
|
VISUAL = "${cfg.defaultApps.visual.pname}";
|
||||||
|
ICON_THEME = cfg.iconThemeName;
|
||||||
|
GTK_CSD = "0";
|
||||||
|
GTK_THEME = cfg.gtkThemeName;
|
||||||
|
GTK_USE_PORTAL = "1";
|
||||||
|
HYPRCURSOR_THEME = config.home.pointerCursor.name;
|
||||||
|
HYPRCURSOR_SIZE = config.home.pointerCursor.size;
|
||||||
|
MOZ_ENABLE_WAYLAND = "1";
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
NIXOS_XDG_OPEN_USE_PORTAL = "1";
|
||||||
|
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
|
||||||
|
QT_QPA_PLATFORM = "wayland-egl";
|
||||||
|
QT_QPA_PLATFORMTHEME = "gtk3";
|
||||||
|
QT_SCALE_FACTOR = "1";
|
||||||
|
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
||||||
|
SDL_VIDEODRIVER = "wayland";
|
||||||
|
TERMINAL = "${cfg.defaultApps.terminal.pname}";
|
||||||
|
XCURSOR_THEME = config.home.pointerCursor.name;
|
||||||
|
XCURSOR_SIZE = config.home.pointerCursor.size;
|
||||||
|
XDG_CACHE_HOME = "\${HOME}/.cache";
|
||||||
|
XDG_CONFIG_HOME = "\${HOME}/.config";
|
||||||
|
XDG_CURRENT_DESKTOP = "Hyprland";
|
||||||
|
XDG_DATA_HOME = "\${HOME}/.local/share";
|
||||||
|
XDG_SESSION_DESKTOP = "Hyprland";
|
||||||
|
XDG_SESSION_TYPE = "wayland";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
62
modules/home/desktop/theme/nord.nix
Normal file
62
modules/home/desktop/theme/nord.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
# Nord colors
|
||||||
|
# Opacity Hex alpha
|
||||||
|
# 100% FF
|
||||||
|
# 75% BF
|
||||||
|
# 50% 80
|
||||||
|
# 25% 40
|
||||||
|
# 10% 1A
|
||||||
|
# 0% 00
|
||||||
|
polarNight = {
|
||||||
|
nord0 = "#2e3440";
|
||||||
|
nord1 = "#3b4252";
|
||||||
|
nord2 = "#434c5e";
|
||||||
|
nord3 = "#4c566a";
|
||||||
|
};
|
||||||
|
snowStorm = {
|
||||||
|
nord4 = "#d8dee9";
|
||||||
|
nord5 = "#e5e9f0";
|
||||||
|
nord6 = "#eceff4";
|
||||||
|
};
|
||||||
|
frost = {
|
||||||
|
nord7 = "#8fbcbb";
|
||||||
|
nord8 = "#88c0d0";
|
||||||
|
nord9 = "#81a1c1";
|
||||||
|
nord10 = "#5e81ac";
|
||||||
|
};
|
||||||
|
aurora = {
|
||||||
|
nord11 = "#bf616a";
|
||||||
|
nord12 = "#d08770";
|
||||||
|
nord13 = "#ebcb8b";
|
||||||
|
nord14 = "#a3be8c";
|
||||||
|
nord15 = "#b48ead";
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultOpacity = "opacity: 0.85;";
|
||||||
|
defaultBorderRadius = "border-radius: 1rem;";
|
||||||
|
defaultCenterOptions = ''
|
||||||
|
padding-top: 0.2rem;
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
margin: 3px 0;
|
||||||
|
'';
|
||||||
|
borderRight = ''
|
||||||
|
padding-top: 0.2rem;
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
margin: 3px 0;
|
||||||
|
border-radius: 0rem 1rem 1rem 0rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
'';
|
||||||
|
borderLeft = ''
|
||||||
|
padding-top: 0.2rem;
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
margin: 3px 0;
|
||||||
|
border-radius: 1rem 0rem 0rem 1rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
programs = {
|
|
||||||
gpg = {
|
|
||||||
enable = true;
|
|
||||||
scdaemonSettings = {
|
|
||||||
disable-ccid = true;
|
|
||||||
pcsc-shared = true;
|
|
||||||
};
|
|
||||||
publicKeys = [
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
||||||
|
|
||||||
mQINBGipyhUBEADCal3wKbTCJHZ7qBTxe2zrJPGV9vu6V4+x/MBQq07jd33RrdgI
|
|
||||||
5R/YSviZLyTjY84xk+XTpxWe6PNxcrNlPrJgqR48UNYiG7rH2VWg073KQZaAEeX4
|
|
||||||
DRmfANtds9m9N9CadMv1XcHvVkEz+UlD3yYGNwrd1ZnWVBpUobIyZvFrVjpGBtOg
|
|
||||||
jgW3NepPn9SfguF+PV4t3Tn2iAFsDa/U3RpkMvYtfxgtxJPvbaVNc3Zq7UDWaXta
|
|
||||||
zZ7y/o5figLUn3q/2JrbzeXmNpShkTixXJHJwSjoD/27I6fVFz4EfwkBfyo8B9yX
|
|
||||||
goekY00wym0oIT2Jb5ZLFh8b60mX/ezUJcMhDkqTG77caRDRxw76yVxc0Jp+r+xZ
|
|
||||||
3ckcrdm+/UtnnD3VO0ktvhb4pU93Pj0PJhrm7qVZS/SEJ67vUx8Aem3aMWgSRsl5
|
|
||||||
51h08US7yfPaMNqKX9d2KaLSTGnQ2BSoXJEmbIqvlvazUTqVk85TDWZEYXgc2S2K
|
|
||||||
phyDfJiVmmUWekgrYE/Fyx0QJkCA6z8cNQWwpRe7oJG1VrnRjhIcuL+EpJb9Ytd9
|
|
||||||
NT39/6/rBot2iGmn64vdyqirji2shuLwrp34A9KWY3XUC5zv0GlHCFsF8lraFzKz
|
|
||||||
AsYv2cLRRja4kyuzoSwoHgXYu1MsifZHgF2+Y0sFW+odRqlo0A9ziXkB9QARAQAB
|
|
||||||
tCNNYXR0aGV3IEphbGxlbiA8amFsbGUwMDhAcHJvdG9uLm1lPokCVwQTAQgAQRYh
|
|
||||||
BMvLmximuJMLC2q/0cy4y+swYzaEBQJoqcoVAhsDBQkSzAMABQsJCAcCAiICBhUK
|
|
||||||
CQgLAgQWAgMBAh4HAheAAAoJEMy4y+swYzaEsrkP/3c/kW0QNv79dEgEHhpJy7nP
|
|
||||||
XyB8fTGr804Gq0ffaPgmn0G8iNzg9pgjgrA8oHpoP0ZbmKaO7JkpHsS0+fpMNuFE
|
|
||||||
dhthWgsYLAnC6rZb4Ib/b+wbUH19CJJIt6Rj9uqH3vDCxeG5TfiJnVA+x3O6VaM1
|
|
||||||
K2oyrXaXDrUKxFlLlnMOsdfRZwXoyYPuJm8Lip5GawIakHGV17FdwdZOcfy0JtdH
|
|
||||||
CwI0K5D390lQ2WNjIJx0vI8E3QYubciOjDzS+KNB12q4sSY6O3fKTXsi80JZ/y4C
|
|
||||||
z1dwsRxMlndBbK1SBJFmczRy4dZC0WbNaxEF2qnM7RENDpB+73HQ1/mSsFaTu609
|
|
||||||
9clDDjwCAUu4UrbL5veWLB+b+xUNy6Sgkbal1Q+pgGSTF9H8plGN0ymijC9xNmvX
|
|
||||||
JeeSTvfnzAThiJubIpZYLkoMmlyEiGrc4CQDdfbsVR9xFGZcau5akcW3e45kiOZC
|
|
||||||
is1H55HsXlBpezanvJCnX7ZEQlRP8vdquHADvgERf3D/qlVAgD/lGE8bzBKJxt1P
|
|
||||||
kxXvGZFxF0BCN/GCoYib1w3WJeTyxGlf9wHkwa/COjasEBGzsnkLToET637WdmHr
|
|
||||||
hgnTVm6CQQW4EUw6gOznDNQvd1EipAwJB7iEm2PneEAwauWeQN38+hc7QVIEqXRk
|
|
||||||
wdfxlU/9WD+rh6FfQ7d3uQINBGipyhUBEADUGJQW/FUWo3R6X7+Quv3TqZfVXJB/
|
|
||||||
bjX9Uv8SKOomUBAjQK9TklaZJvNiaD4qYV93kPfpclGhxdGahXVBC7SdGenaFig4
|
|
||||||
4WwUe5vrKIGbbfcC+dBW/8eAqueKjCWe6wFqXbKat1/4Y1atsFZX5Lf/GEi1VNXu
|
|
||||||
0NkSPKAqTdXyXrTuC7D5wARGdavbxO3BcF1NqpIPHiROQoOyP10jx8xcMYGoVIIr
|
|
||||||
uscckoqhdbyEua9m9zFesYyqiCfJeSCK8O4w7BU3dgHUz53hfeuNuGBPb/dQ9Ent
|
|
||||||
qKwrMxsPWJC9qN19Wvvsgy89QLn0CWmcUsmc/f4mWnKoSH9AZCuVCSgoSjknXGj0
|
|
||||||
MPBI6jY1gaqZAuyMH24ekUAdUtNK5IuPPPxrlE1ljAWSxvFGG7Dj4p78ELJizlT7
|
|
||||||
XXOtAPggwCFfXauQD+v43ILg5Zxz6fjTd0TZ8iSypqiZIQgQoiUUGcDZmjHhRHNj
|
|
||||||
GHlqmRECyef6mZVhb3zlyzAcQycnZvHtXFMmyrvfFs21pX9WEF3lQFDapnMAwODE
|
|
||||||
2BLQWrh2ed++/An3DJOh/Iwv9WBatDagMObJi3lsUszJ0l5iwteJOfXMR72zV+m7
|
|
||||||
7QzaEdGFDlNRSMmtjni7FLWbDA/CkihRsUtqgrXgj91oqLga0GmjlNnIZGwhcDUx
|
|
||||||
Yuo+kIRRM4DSDwARAQABiQI8BBgBCAAmFiEEy8ubGKa4kwsLar/RzLjL6zBjNoQF
|
|
||||||
AmipyhUCGwwFCRLMAwAACgkQzLjL6zBjNoS5/Q//SPmdM26wUq50A8QTuQ3r8xpc
|
|
||||||
3oGCdBAP7QJk6+W1kJcGVP4r2bFylbWUGyHWuhKTs47r6fh3Sd9MtmGQgtEEbGFW
|
|
||||||
a4pxaYBRPYGHvJuVwb4IvOzDuVj8yabk0c688jz2Wv1DW3+z4623TI2JeOfEoOqg
|
|
||||||
u4DGySVZkXA/F01HShP0QsGEGRkklEvysD101GbJrQuQ6ssHiFVF1m+/w+I8fYzP
|
|
||||||
F9BC61DOEabm62YjELf/xvKQ6aT8rB0F2p9udOmIlw9lkAJMsEz4mB5f4Bq/1vGt
|
|
||||||
aZ7K0tytT3aeTFFgLwtBPcjWvHavEp4/CDXUL58v/X5R+E6Z03zsWwspsACacblq
|
|
||||||
RW15f3aKI2j7u/w6oJ/iJbEXtZq/Hv1XACyZ/kD9WcYIPsNikCS6vSsnj9Hk/o88
|
|
||||||
yG0rQ6v9L7s9gqWm1IajnDQD6g7n3H4pXGJsE4sBGg6FfE0OJDcd4VqZGJGMz9rr
|
|
||||||
+V+3zUxs/RIVWTCdoVPTLBWrtsKbwObgE7SdkaUt4/1uhtdkR++brhr2uz3il0Kt
|
|
||||||
2QZAXJDcK2xzcOEz41lhclgMxUzjYTggQvpD8lu70xlGqgm94NJCBctPx6xJAN9f
|
|
||||||
H6dELHDuLAwB+vKB9YJIvMVaPNKRam8wGnZ0EKHUFvmIqqSOE8GR1LmgslYRNidv
|
|
||||||
ywgEIPcOpJGzt3TQprM=
|
|
||||||
=i8do
|
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
|
||||||
'';
|
|
||||||
trust = "ultimate";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
gpg-agent = {
|
|
||||||
enable = true;
|
|
||||||
enableZshIntegration = true;
|
|
||||||
enableSshSupport = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -2,68 +2,53 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
namespace,
|
|
||||||
hasDestopEnvironment ? true,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) enabled disabled;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home = {
|
home = {
|
||||||
enableNixpkgsReleaseCheck = lib.mkDefault false;
|
enableNixpkgsReleaseCheck = lib.mkDefault false;
|
||||||
homeDirectory = lib.mkDefault "/home/${config.home.username}";
|
homeDirectory = lib.mkDefault "/home/${config.home.username}";
|
||||||
packages =
|
packages = with pkgs; [
|
||||||
with pkgs;
|
age
|
||||||
[
|
chromium
|
||||||
age
|
clinfo
|
||||||
clinfo
|
cpufetch
|
||||||
cpufetch
|
deadnix
|
||||||
deadnix
|
firefox
|
||||||
lm_sensors
|
gamescope
|
||||||
nano
|
gamescope-wsi
|
||||||
nixfmt-rfc-style
|
goverlay
|
||||||
pciutils
|
gparted
|
||||||
protonup-ng
|
lm_sensors
|
||||||
rsync
|
mission-center
|
||||||
smartmontools
|
nano
|
||||||
sops
|
nixfmt-rfc-style
|
||||||
tailscale
|
pciutils
|
||||||
tree
|
protonup
|
||||||
usbutils
|
rsync
|
||||||
vim
|
smartmontools
|
||||||
vulkan-tools
|
sops
|
||||||
wget
|
tailscale
|
||||||
]
|
tree
|
||||||
++ (
|
usbutils
|
||||||
if hasDestopEnvironment then
|
vesktop
|
||||||
[
|
vim
|
||||||
chromium
|
vulkan-tools
|
||||||
firefox
|
wget
|
||||||
gamescope
|
];
|
||||||
gamescope-wsi
|
|
||||||
gparted
|
|
||||||
goverlay
|
|
||||||
mission-center
|
|
||||||
vesktop
|
|
||||||
]
|
|
||||||
else
|
|
||||||
[ ]
|
|
||||||
);
|
|
||||||
|
|
||||||
stateVersion = lib.mkDefault "23.11";
|
stateVersion = lib.mkDefault "23.11";
|
||||||
};
|
};
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
nix-index-database.comma = enabled;
|
btop.enable = lib.mkDefault true;
|
||||||
btop = lib.mkDefault enabled;
|
fastfetch.enable = lib.mkDefault true;
|
||||||
fastfetch = lib.mkDefault enabled;
|
home-manager.enable = lib.mkDefault true;
|
||||||
home-manager = lib.mkDefault enabled;
|
|
||||||
java = {
|
java = {
|
||||||
enable = lib.mkDefault true;
|
enable = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
mangohud.enable = lib.mkDefault hasDestopEnvironment;
|
mangohud.enable = lib.mkDefault true;
|
||||||
password-store = enabled;
|
password-store.enable = true;
|
||||||
nh = {
|
nh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
flake = "/etc/nixos";
|
flake = "/etc/nixos";
|
||||||
@@ -125,10 +110,10 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
nextcloud-client.enable = lib.mkDefault hasDestopEnvironment;
|
nextcloud-client.enable = lib.mkDefault true;
|
||||||
pass-secret-service = lib.mkDefault enabled;
|
pass-secret-service.enable = lib.mkDefault true;
|
||||||
kdeconnect = {
|
kdeconnect = {
|
||||||
enable = lib.mkDefault hasDestopEnvironment;
|
enable = lib.mkDefault true;
|
||||||
indicator = lib.mkDefault true;
|
indicator = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.btop;
|
cfg = config.mjallen.programs.btop;
|
||||||
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -9,6 +10,8 @@ in
|
|||||||
programs.btop = {
|
programs.btop = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
|
color_theme = "nord"; # todo
|
||||||
|
theme_background = true;
|
||||||
truecolor = true;
|
truecolor = true;
|
||||||
force_tty = false;
|
force_tty = false;
|
||||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty";
|
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty";
|
||||||
@@ -72,6 +75,52 @@ in
|
|||||||
selected_battery = "Auto";
|
selected_battery = "Auto";
|
||||||
log_level = "WARNING";
|
log_level = "WARNING";
|
||||||
};
|
};
|
||||||
|
themes = {
|
||||||
|
nord = ''
|
||||||
|
theme[main_bg]="${nord.polarNight.nord0}"
|
||||||
|
theme[main_fg]="${nord.snowStorm.nord6}"
|
||||||
|
theme[title]="${nord.snowStorm.nord6}"
|
||||||
|
theme[hi_fg]="${nord.frost.nord7}"
|
||||||
|
theme[selected_bg]="${nord.polarNight.nord1}"
|
||||||
|
theme[selected_fg]="${nord.frost.nord7}"
|
||||||
|
theme[inactive_fg]="${nord.polarNight.nord2}"
|
||||||
|
theme[graph_text]="${nord.snowStorm.nord6}"
|
||||||
|
theme[meter_bg]="${nord.polarNight.nord1}"
|
||||||
|
theme[proc_misc]="${nord.snowStorm.nord6}"
|
||||||
|
theme[cpu_box]="${nord.aurora.nord15}"
|
||||||
|
theme[mem_box]="${nord.aurora.nord14}"
|
||||||
|
theme[net_box]="${nord.aurora.nord12}"
|
||||||
|
theme[proc_box]="${nord.aurora.nord11}"
|
||||||
|
theme[div_line]="${nord.polarNight.nord1}"
|
||||||
|
theme[temp_start]="${nord.aurora.nord14}"
|
||||||
|
theme[temp_mid]="${nord.aurora.nord13}"
|
||||||
|
theme[temp_end]="${nord.aurora.nord11}"
|
||||||
|
theme[cpu_start]="${nord.aurora.nord15}"
|
||||||
|
theme[cpu_mid]="${nord.aurora.nord12}"
|
||||||
|
theme[cpu_end]="${nord.aurora.nord11}"
|
||||||
|
theme[free_start]="${nord.aurora.nord14}"
|
||||||
|
theme[free_mid]="${nord.aurora.nord13}"
|
||||||
|
theme[free_end]="${nord.aurora.nord12}"
|
||||||
|
theme[cached_start]="${nord.aurora.nord14}"
|
||||||
|
theme[cached_mid]="${nord.aurora.nord13}"
|
||||||
|
theme[cached_end]="${nord.aurora.nord12}"
|
||||||
|
theme[available_start]="${nord.snowStorm.nord6}"
|
||||||
|
theme[available_mid]="${nord.aurora.nord11}"
|
||||||
|
theme[available_end]="${nord.aurora.nord11}"
|
||||||
|
theme[used_start]="${nord.aurora.nord14}"
|
||||||
|
theme[used_mid]="${nord.aurora.nord13}"
|
||||||
|
theme[used_end]="${nord.aurora.nord11}"
|
||||||
|
theme[download_start]="${nord.frost.nord8}"
|
||||||
|
theme[download_mid]="${nord.frost.nord8}"
|
||||||
|
theme[download_end]="${nord.aurora.nord12}"
|
||||||
|
theme[upload_start]="${nord.frost.nord7}"
|
||||||
|
theme[upload_mid]="${nord.frost.nord7}"
|
||||||
|
theme[upload_end]="${nord.aurora.nord12}"
|
||||||
|
theme[process_start]="${nord.aurora.nord15}"
|
||||||
|
theme[process_mid]="${nord.aurora.nord12}"
|
||||||
|
theme[process_end]="${nord.aurora.nord11}"
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,26 +3,19 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
system,
|
system,
|
||||||
namespace,
|
namespace,
|
||||||
hasDestopEnvironment ? true,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
isArm = ("aarch64-linux" == system) || ("aarch64-darwin" == system);
|
isArm = "aarch64-linux" == system;
|
||||||
|
|
||||||
x86_only = with pkgs; [
|
x86_only = with pkgs; [
|
||||||
vscode-extensions.redhat.vscode-xml
|
vscode-extensions.redhat.vscode-xml
|
||||||
];
|
];
|
||||||
open-remote-ssh = pkgs.${namespace}.open-remote-ssh;
|
open-remote-ssh = pkgs.${namespace}.open-remote-ssh;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
|
||||||
nodePackages.nodejs
|
|
||||||
uv
|
|
||||||
];
|
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
vscode = {
|
vscode = {
|
||||||
enable = hasDestopEnvironment;
|
enable = true;
|
||||||
package = pkgs.vscodium;
|
package = pkgs.vscodium;
|
||||||
mutableExtensionsDir = false;
|
mutableExtensionsDir = false;
|
||||||
profiles = {
|
profiles = {
|
||||||
@@ -36,7 +29,7 @@ in
|
|||||||
vscode-extensions.bbenoist.nix
|
vscode-extensions.bbenoist.nix
|
||||||
vscode-extensions.brettm12345.nixfmt-vscode
|
vscode-extensions.brettm12345.nixfmt-vscode
|
||||||
vscode-extensions.cweijan.vscode-database-client2
|
vscode-extensions.cweijan.vscode-database-client2
|
||||||
# vscode-extensions.dendron.dendron-markdown-preview-enhanced
|
vscode-extensions.dendron.dendron-markdown-preview-enhanced
|
||||||
vscode-extensions.jnoortheen.nix-ide
|
vscode-extensions.jnoortheen.nix-ide
|
||||||
vscode-extensions.mkhl.direnv
|
vscode-extensions.mkhl.direnv
|
||||||
vscode-extensions.ms-python.debugpy
|
vscode-extensions.ms-python.debugpy
|
||||||
@@ -154,8 +147,8 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
direnv = {
|
direnv = {
|
||||||
enable = false;
|
enable = true;
|
||||||
nix-direnv.enable = false;
|
nix-direnv.enable = true;
|
||||||
enableZshIntegration = true;
|
enableZshIntegration = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,12 +14,8 @@ in
|
|||||||
{
|
{
|
||||||
programs.git = {
|
programs.git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
userName = "mjallen18";
|
||||||
user = {
|
userEmail = "matt.l.jallen@gmail.com";
|
||||||
name = "mjallen18";
|
aliases = gitAliases;
|
||||||
email = "matt.l.jallen@gmail.com";
|
|
||||||
};
|
|
||||||
alias = gitAliases;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,724 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.mjallen.programs.hyprland;
|
|
||||||
drawer = "nwg-drawer -fm nautilus -term kitty -mb 10 -mt 10 -ml 10 -mr 10 -pbuseicontheme -i ${config.stylix.icons.dark}";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./options.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# Home packages
|
|
||||||
home.packages =
|
|
||||||
with pkgs;
|
|
||||||
(
|
|
||||||
[
|
|
||||||
box64
|
|
||||||
brightnessctl
|
|
||||||
ddcutil
|
|
||||||
egl-wayland
|
|
||||||
file-roller
|
|
||||||
glib
|
|
||||||
gnome-calculator
|
|
||||||
gnome-calendar
|
|
||||||
gnome-disk-utility
|
|
||||||
gnome-firmware
|
|
||||||
gnome-font-viewer
|
|
||||||
gnome-logs
|
|
||||||
gnome-photos
|
|
||||||
gnome-tweaks
|
|
||||||
gnome-weather
|
|
||||||
gsettings-desktop-schemas
|
|
||||||
hyprcursor
|
|
||||||
hyprland
|
|
||||||
hyprpaper
|
|
||||||
hyprshot
|
|
||||||
hyprsysteminfo
|
|
||||||
kdePackages.qtmultimedia
|
|
||||||
libnotify
|
|
||||||
libz
|
|
||||||
meson
|
|
||||||
nautilus
|
|
||||||
nomacs
|
|
||||||
nwg-look
|
|
||||||
overskride
|
|
||||||
pamixer
|
|
||||||
pavucontrol
|
|
||||||
playerctl
|
|
||||||
qt5.qtwayland
|
|
||||||
qt6.qtwayland
|
|
||||||
waybar
|
|
||||||
wayland-protocols
|
|
||||||
wayland-utils
|
|
||||||
waypaper
|
|
||||||
wev
|
|
||||||
wl-clipboard
|
|
||||||
wlogout
|
|
||||||
wlroots
|
|
||||||
xorg.xhost
|
|
||||||
xsettingsd
|
|
||||||
xwayland
|
|
||||||
|
|
||||||
pkgs.mjallen.pipewire-python
|
|
||||||
]
|
|
||||||
++ (if cfg.notificationDaemon == "mako" then [ mako ] else [ dunst ])
|
|
||||||
++ (if cfg.launcher == "wofi" then [ wofi ] else [ rofi ])
|
|
||||||
);
|
|
||||||
|
|
||||||
# Session variables
|
|
||||||
home.sessionVariables = {
|
|
||||||
BROWSER = "${cfg.defaultApps.browser.pname}";
|
|
||||||
CLUTTER_BACKEND = "wayland";
|
|
||||||
EDITOR = "${cfg.defaultApps.editor.pname}";
|
|
||||||
VISUAL = "${cfg.defaultApps.visual.pname}";
|
|
||||||
ICON_THEME = config.gtk.iconTheme.name;
|
|
||||||
GTK_CSD = "0";
|
|
||||||
GTK_THEME = config.gtk.theme.name;
|
|
||||||
GTK_USE_PORTAL = "1";
|
|
||||||
HYPRCURSOR_THEME = config.stylix.cursor.name;
|
|
||||||
HYPRCURSOR_SIZE = config.stylix.cursor.size;
|
|
||||||
MOZ_ENABLE_WAYLAND = "1";
|
|
||||||
NIXOS_OZONE_WL = "1";
|
|
||||||
NIXOS_XDG_OPEN_USE_PORTAL = "1";
|
|
||||||
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
|
|
||||||
QT_QPA_PLATFORM = "wayland-egl";
|
|
||||||
QT_QPA_PLATFORMTHEME = "gtk3";
|
|
||||||
QT_SCALE_FACTOR = "1";
|
|
||||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
|
||||||
SDL_VIDEODRIVER = "wayland";
|
|
||||||
TERMINAL = "${cfg.defaultApps.terminal.pname}";
|
|
||||||
XCURSOR_THEME = config.stylix.cursor.name;
|
|
||||||
XCURSOR_SIZE = config.stylix.cursor.size;
|
|
||||||
XDG_CACHE_HOME = "\${HOME}/.cache";
|
|
||||||
XDG_CONFIG_HOME = "\${HOME}/.config";
|
|
||||||
XDG_CURRENT_DESKTOP = "Hyprland";
|
|
||||||
XDG_DATA_HOME = "\${HOME}/.local/share";
|
|
||||||
XDG_SESSION_DESKTOP = "Hyprland";
|
|
||||||
XDG_SESSION_TYPE = "wayland";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Services
|
|
||||||
services = {
|
|
||||||
hyprpolkitagent.enable = true;
|
|
||||||
hyprpaper = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
preload = [ cfg.hyprpaper.wallpaperPath ];
|
|
||||||
wallpaper =
|
|
||||||
let
|
|
||||||
useMonitorV2 = (lib.versionAtLeast pkgs.hyprland.version "0.40.0") && (cfg.monitorv2 != [ ]);
|
|
||||||
names =
|
|
||||||
if useMonitorV2 then
|
|
||||||
map (m: m.name) cfg.monitorv2
|
|
||||||
else
|
|
||||||
[
|
|
||||||
cfg.display1.input
|
|
||||||
cfg.display2.input
|
|
||||||
];
|
|
||||||
in
|
|
||||||
if cfg.hyprpaper.usePerMonitor then
|
|
||||||
map (n: "${n}, ${cfg.hyprpaper.wallpaperPath}") names
|
|
||||||
else
|
|
||||||
[ ", ${cfg.hyprpaper.wallpaperPath}" ];
|
|
||||||
splash = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
hypridle = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
general = {
|
|
||||||
before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
|
|
||||||
after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
|
|
||||||
ignore_dbus_inhibit = false;
|
|
||||||
lock_cmd = "pidof hyprlock || hyprlock"; # avoid starting multiple hyprlock instances.
|
|
||||||
};
|
|
||||||
listener = [
|
|
||||||
# {
|
|
||||||
# timeout = 300; # 5min
|
|
||||||
# on-timeout = "brightnessctl -s set 10"; # set monitor backlight to minimum, avoid 0 on OLED monitor.
|
|
||||||
# on-resume = "brightnessctl -r"; # monitor backlight restore.
|
|
||||||
# }
|
|
||||||
{
|
|
||||||
timeout = cfg.hyprIdle.lockScreenTimer;
|
|
||||||
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
|
|
||||||
}
|
|
||||||
{
|
|
||||||
timeout = cfg.hyprIdle.screenOffTimer;
|
|
||||||
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
|
|
||||||
on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired.
|
|
||||||
}
|
|
||||||
{
|
|
||||||
timeout = cfg.hyprIdle.suspendTimer;
|
|
||||||
on-timeout = "systemctl suspend"; # suspend pc
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Programs
|
|
||||||
programs = {
|
|
||||||
vscode.profiles.default.userSettings."window"."titleBarStyle" = "custom";
|
|
||||||
|
|
||||||
hyprlock = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
background = [
|
|
||||||
{
|
|
||||||
monitor = "";
|
|
||||||
path = "/run/wallpaper.jpg"; # supports png, jpg, webp (no animations, though)
|
|
||||||
color = mkForce "rgba(25, 20, 20, 1.0)";
|
|
||||||
|
|
||||||
# all these options are taken from hyprland, see https://wiki.hyprland.org/Configuring/Variables/#blur for explanations
|
|
||||||
blur_passes = mkForce "3"; # 0 disables blurring
|
|
||||||
blur_size = mkForce "7";
|
|
||||||
noise = "0.0117";
|
|
||||||
contrast = "0.8916";
|
|
||||||
brightness = mkForce "0.8172";
|
|
||||||
vibrancy = "0.1696";
|
|
||||||
vibrancy_darkness = "0.0";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
label = [
|
|
||||||
# Date display
|
|
||||||
{
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
text = "cmd[update:1000] echo -e \"$(LC_TIME=en_US.UTF-8 date +\"%A, %B %d\")\"";
|
|
||||||
color = config.lib.stylix.colors.base06;
|
|
||||||
font_size = "25";
|
|
||||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
|
||||||
position = "0, 350";
|
|
||||||
halign = "center";
|
|
||||||
valign = "center";
|
|
||||||
}
|
|
||||||
# Time display
|
|
||||||
{
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
text = "cmd[update:1000] echo \"<span>$(date +\"%I:%M\")</span>\"";
|
|
||||||
color = config.lib.stylix.colors.base06;
|
|
||||||
font_size = "120";
|
|
||||||
font_family = lib.mkDefault "${config.stylix.fonts.monospace.name} Bold";
|
|
||||||
position = "0, 230";
|
|
||||||
halign = "center";
|
|
||||||
valign = "center";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
text = "$USER";
|
|
||||||
color = config.lib.stylix.colors.base06;
|
|
||||||
outline_thickness = 2;
|
|
||||||
dots_size = 0.2;
|
|
||||||
dots_spacing = 0.2;
|
|
||||||
dots_center = true;
|
|
||||||
font_size = 18;
|
|
||||||
font_family = lib.mkDefault "${config.stylix.fonts.monospace.name} Bold";
|
|
||||||
position = "0, 0";
|
|
||||||
halign = "center";
|
|
||||||
valign = "center";
|
|
||||||
}
|
|
||||||
# weather
|
|
||||||
{
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
text = "cmd[update:30000] waybar-weather --hyprlock";
|
|
||||||
color = config.lib.stylix.colors.base06;
|
|
||||||
font_size = "25";
|
|
||||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
|
||||||
position = "-100, 100";
|
|
||||||
halign = "right";
|
|
||||||
valign = "bottom";
|
|
||||||
}
|
|
||||||
# media
|
|
||||||
{
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
text = "cmd[update:1000] waybar-media";
|
|
||||||
color = config.lib.stylix.colors.base06;
|
|
||||||
font_size = "15";
|
|
||||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
|
||||||
position = "100, 100";
|
|
||||||
halign = "left";
|
|
||||||
valign = "bottom";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
# user box
|
|
||||||
shape = [
|
|
||||||
{
|
|
||||||
monitor = "";
|
|
||||||
size = "200, 50";
|
|
||||||
color = "rgba(46, 52, 64, .25)";
|
|
||||||
rounding = -1;
|
|
||||||
border_size = "0";
|
|
||||||
position = "0, 0";
|
|
||||||
halign = "center";
|
|
||||||
valign = "center";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
input-field = [
|
|
||||||
{
|
|
||||||
size = "200, 50";
|
|
||||||
position = "0, -80";
|
|
||||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
dots_center = true;
|
|
||||||
fade_on_empty = true;
|
|
||||||
font_color = config.lib.stylix.colors.base06;
|
|
||||||
inner_color = config.lib.stylix.colors.base03;
|
|
||||||
outer_color = config.lib.stylix.colors.base00;
|
|
||||||
bothlock_color = -1;
|
|
||||||
outline_thickness = 5;
|
|
||||||
placeholder_text = ''<span foreground="#${config.lib.stylix.colors.base00}">Password...</span>'';
|
|
||||||
shadow_passes = 2;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
image = [
|
|
||||||
{
|
|
||||||
monitor = cfg.primaryDisplay;
|
|
||||||
# path = "/tmp/hyprlock-art";
|
|
||||||
reload_cmd = "waybar-media-art";
|
|
||||||
reload_time = 3;
|
|
||||||
size = 150;
|
|
||||||
rounding = 0;
|
|
||||||
position = "100, 150";
|
|
||||||
halign = "left";
|
|
||||||
valign = "bottom";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Wayland configuration
|
|
||||||
wayland.windowManager.hyprland = {
|
|
||||||
enable = true;
|
|
||||||
xwayland.enable = true;
|
|
||||||
systemd = {
|
|
||||||
enable = true;
|
|
||||||
enableXdgAutostart = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
plugins = with pkgs.hyprlandPlugins; [
|
|
||||||
# hyprgrass
|
|
||||||
];
|
|
||||||
|
|
||||||
settings =
|
|
||||||
let
|
|
||||||
useMonitorV2 = (lib.versionAtLeast pkgs.hyprland.version "0.40.0") && (cfg.monitorv2 != [ ]);
|
|
||||||
names =
|
|
||||||
if useMonitorV2 then
|
|
||||||
map (m: m.name) cfg.monitorv2
|
|
||||||
else
|
|
||||||
[
|
|
||||||
cfg.display1.input
|
|
||||||
cfg.display2.input
|
|
||||||
];
|
|
||||||
firstMonitor = builtins.elemAt names 0;
|
|
||||||
secondMonitor = if builtins.length names > 1 then builtins.elemAt names 1 else firstMonitor;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
"$mod" = cfg.modKey;
|
|
||||||
|
|
||||||
# Mouse
|
|
||||||
# mouse_[up|down] - scroll wheel
|
|
||||||
# middle_mouse - 274
|
|
||||||
# thumb_up - 276
|
|
||||||
# thumb_down - 275
|
|
||||||
|
|
||||||
# l -> locked, will also work when an input inhibitor (e.g. a lockscreen) is active.
|
|
||||||
# r -> release, will trigger on release of a key.
|
|
||||||
# e -> repeat, will repeat when held.
|
|
||||||
# n -> non-consuming, key/mouse events will be passed to the active window in addition to triggering the dispatcher.
|
|
||||||
# m -> mouse, see below.
|
|
||||||
# t -> transparent, cannot be shadowed by other binds.
|
|
||||||
# i -> ignore mods, will ignore modifiers.
|
|
||||||
# s -> separate, will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos) above.
|
|
||||||
# d -> has description, will allow you to write a description for your bind.
|
|
||||||
# p -> bypasses the app's requests to inhibit keybinds.
|
|
||||||
|
|
||||||
# https://wiki.hyprland.org/Configuring/Binds/
|
|
||||||
# https://wiki.hyprland.org/Configuring/Binds/#mouse-buttons
|
|
||||||
|
|
||||||
bind = [
|
|
||||||
"$mod, Return, exec, ${cfg.defaultApps.terminal.pname}"
|
|
||||||
"$mod, SPACE, exec, ${if cfg.launcher == "wofi" then "wofi --show drun" else "rofi -show drun"}"
|
|
||||||
", xf86Search, exec, ${if cfg.launcher == "wofi" then "wofi --show drun" else "rofi -show drun"}"
|
|
||||||
"$mod, Q, killactive, "
|
|
||||||
"$mod, M, exec, wlogout --protocol layer-shell"
|
|
||||||
"$mod, E, exec, ${cfg.defaultApps.fileExplorer.pname}"
|
|
||||||
"$mod, V, togglefloating, "
|
|
||||||
"$mod, D, exec, ${drawer}"
|
|
||||||
"$mod, P, pseudo, " # dwindle
|
|
||||||
"$mod, S, togglesplit, " # dwindle
|
|
||||||
"$mod SHIFT, Q, exec, hyprlock"
|
|
||||||
"$mod SHIFT, 4, exec, hyprshot -m region --clipboard-only"
|
|
||||||
"$mod, F, fullscreen, 1"
|
|
||||||
"$mod SHIFT, F, fullscreen, 0"
|
|
||||||
"$mod SHIFT, E, exec, smile"
|
|
||||||
|
|
||||||
"$mod, mouse:276, movecurrentworkspacetomonitor, ${firstMonitor}"
|
|
||||||
"$mod, mouse:275, movecurrentworkspacetomonitor, ${secondMonitor}"
|
|
||||||
|
|
||||||
# alt-tab between workspaces on active monitor
|
|
||||||
"$mod, Tab, workspace, m+1"
|
|
||||||
"$mod SHIFT, Tab, workspace, m-1"
|
|
||||||
|
|
||||||
"$mod, h, movefocus, l"
|
|
||||||
"$mod, l, movefocus, r"
|
|
||||||
"$mod, k, movefocus, u"
|
|
||||||
"$mod, j, movefocus, d"
|
|
||||||
|
|
||||||
"$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, 0, workspace, 10"
|
|
||||||
|
|
||||||
"$mod ALT, 1, movetoworkspace, 1"
|
|
||||||
"$mod ALT, 2, movetoworkspace, 2"
|
|
||||||
"$mod ALT, 3, movetoworkspace, 3"
|
|
||||||
"$mod ALT, 4, movetoworkspace, 4"
|
|
||||||
"$mod ALT, 5, movetoworkspace, 5"
|
|
||||||
"$mod ALT, 6, movetoworkspace, 6"
|
|
||||||
"$mod ALT, 7, movetoworkspace, 7"
|
|
||||||
"$mod ALT, 8, movetoworkspace, 8"
|
|
||||||
"$mod ALT, 9, movetoworkspace, 9"
|
|
||||||
"$mod ALT, 0, movetoworkspace, discord"
|
|
||||||
|
|
||||||
"$mod CTRL, l, resizeactive, 10 0"
|
|
||||||
"$mod CTRL, h, resizeactive, -10 0"
|
|
||||||
"$mod CTRL, k, resizeactive, 0 -10"
|
|
||||||
"$mod CTRL, j, resizeactive, 0 10"
|
|
||||||
|
|
||||||
"$mod SHIFT, l, movewindow, r"
|
|
||||||
"$mod SHIFT, h, movewindow, l"
|
|
||||||
"$mod SHIFT, k, movewindow, u"
|
|
||||||
"$mod SHIFT, j, movewindow, d"
|
|
||||||
|
|
||||||
"$mod, b, exec, ${cfg.defaultApps.browser.pname}"
|
|
||||||
]
|
|
||||||
++ cfg.keybinds.bind;
|
|
||||||
|
|
||||||
bindm = [
|
|
||||||
# Move/resize windows with mod + LMB/RMB and dragging
|
|
||||||
"$mod, mouse:272, movewindow"
|
|
||||||
"$mod, mouse:273, resizewindow"
|
|
||||||
# middle mouse will grab a window, mod + middle mouse will close it
|
|
||||||
"$mod SHIFT, mouse:274, movewindow"
|
|
||||||
]
|
|
||||||
++ cfg.keybinds.bindm;
|
|
||||||
|
|
||||||
bindel = [
|
|
||||||
", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
|
|
||||||
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
|
|
||||||
]
|
|
||||||
++ cfg.keybinds.bindel;
|
|
||||||
|
|
||||||
bindl = [
|
|
||||||
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
|
|
||||||
", XF86AudioPlay, exec, playerctl play-pause"
|
|
||||||
", XF86AudioPrev, exec, playerctl previous"
|
|
||||||
", XF86AudioNext, exec, playerctl next"
|
|
||||||
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
|
|
||||||
|
|
||||||
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
|
|
||||||
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
|
|
||||||
|
|
||||||
"$mod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight set +10%"
|
|
||||||
"$mod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight set 10%-"
|
|
||||||
]
|
|
||||||
++ cfg.keybinds.bindl;
|
|
||||||
|
|
||||||
monitor =
|
|
||||||
cfg.monitor
|
|
||||||
++ map (
|
|
||||||
m:
|
|
||||||
if m.disabled then
|
|
||||||
"${m.name}, disable"
|
|
||||||
else if m.mirrorOf != null then
|
|
||||||
"${m.name}, mirror, ${m.mirrorOf}"
|
|
||||||
else
|
|
||||||
let
|
|
||||||
mode = if m.mode == null then "preferred" else m.mode;
|
|
||||||
position = if m.position == null then "0x0" else m.position;
|
|
||||||
scale = if m.scale == null then "1" else (toString m.scale);
|
|
||||||
parts = [
|
|
||||||
m.name
|
|
||||||
mode
|
|
||||||
position
|
|
||||||
scale
|
|
||||||
];
|
|
||||||
# Append transform only when set, as "transform, <value>"
|
|
||||||
transformTokens =
|
|
||||||
if m.transform == null then
|
|
||||||
[ ]
|
|
||||||
else
|
|
||||||
[
|
|
||||||
"transform"
|
|
||||||
m.transform
|
|
||||||
];
|
|
||||||
tokens = parts ++ transformTokens ++ m.extra;
|
|
||||||
in
|
|
||||||
builtins.concatStringsSep ", " tokens
|
|
||||||
) cfg.monitorv2;
|
|
||||||
|
|
||||||
render = {
|
|
||||||
cm_fs_passthrough = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
misc = {
|
|
||||||
vrr = if cfg.enableVRR then 1 else 0;
|
|
||||||
force_default_wallpaper = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
general = {
|
|
||||||
gaps_in = 5;
|
|
||||||
gaps_out = 10;
|
|
||||||
border_size = 1;
|
|
||||||
# "col.active_border" = "rgb(8aadf4) rgb(24273A) rgb(24273A) rgb(8aadf4) 45deg";
|
|
||||||
# "col.inactive_border" = "rgb(24273A) rgb(24273A) rgb(24273A) rgb(24273A) 45deg";
|
|
||||||
layout = "dwindle";
|
|
||||||
allow_tearing = cfg.allowTearing;
|
|
||||||
};
|
|
||||||
|
|
||||||
decoration = {
|
|
||||||
rounding = 10;
|
|
||||||
blur = {
|
|
||||||
enabled = true;
|
|
||||||
size = 2;
|
|
||||||
passes = 2;
|
|
||||||
new_optimizations = true;
|
|
||||||
xray = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
animations = {
|
|
||||||
enabled = "yes";
|
|
||||||
bezier = [
|
|
||||||
"overshot, 0.05, 0.9, 0.1, 1.05"
|
|
||||||
"smoothOut, 0.36, 0, 0.66, -0.56"
|
|
||||||
"smoothIn, 0.25, 1, 0.5, 1"
|
|
||||||
];
|
|
||||||
animation = [
|
|
||||||
"windows, 1, 5, overshot, slide"
|
|
||||||
"windowsOut, 1, 4, smoothOut, slide"
|
|
||||||
"windowsMove, 1, 4, default"
|
|
||||||
"border, 1, 10, default"
|
|
||||||
"fade, 1, 10, smoothIn"
|
|
||||||
"fadeDim, 1, 10, smoothIn"
|
|
||||||
"workspaces, 1, 6, default"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
dwindle = {
|
|
||||||
pseudotile = "yes";
|
|
||||||
preserve_split = "yes";
|
|
||||||
};
|
|
||||||
|
|
||||||
workspace = cfg.workspace;
|
|
||||||
|
|
||||||
windowrule = [
|
|
||||||
"float, title:(file_progress)"
|
|
||||||
"float, title:(.*[Cc]onfirm.*)"
|
|
||||||
"float, title:(.*[Dd]ialog.*)"
|
|
||||||
"float, title:(.*[Dd]ownload.*)"
|
|
||||||
"float, title:(.*[Nn]otification.*)"
|
|
||||||
"float, title:(.*[Ee]rror.*)"
|
|
||||||
"float, title:(.*[Ss]plash.*)"
|
|
||||||
"float, title:(.*[Cc]onfirmreset.*)"
|
|
||||||
"float, title:(.*[Ss]ign [Ii]n - .*)"
|
|
||||||
"float, title:(.*[Oo]pen [Ff]ile.*)"
|
|
||||||
"float, title:(.*branchdialog.*)"
|
|
||||||
"float, class:(.*pavucontrol.*)"
|
|
||||||
"move onscreen cursor 0% 0%, class:(.*pavucontrol.*)"
|
|
||||||
"float, class:(.*[Oo]verskride.*)"
|
|
||||||
"float, class:(.*FileRoller.*)"
|
|
||||||
"float, class:(.*wlogout.*)"
|
|
||||||
"idleinhibit stayfocused, title:(.*mpv.*)"
|
|
||||||
|
|
||||||
"float, class:(.*nm-connection-editor.*)"
|
|
||||||
"move onscreen cursor 0% 0%, class:(.*nm-connection-editor.*)"
|
|
||||||
|
|
||||||
"float, title:(Media viewer)"
|
|
||||||
"float, class:(it.mijorus.smile),title:(Smile)"
|
|
||||||
"float, class:(.blueman-manager-wrapped)$,title:(Bluetooth Devices)"
|
|
||||||
# Picture in picture windows
|
|
||||||
"float, title:(.*Picture-in-Picture.*)"
|
|
||||||
"pin, title::(.*Picture-in-Picture.*)"
|
|
||||||
|
|
||||||
# discord/vesktop
|
|
||||||
# "workspace: name:discord, class:(.*vesktop)"
|
|
||||||
# "float, class:(.*vesktop),title:(.*Discord Popout.*)"
|
|
||||||
# "pin, class:(.*vesktop),title:(.*Discord Popout.*)"
|
|
||||||
|
|
||||||
# Music
|
|
||||||
# "workspace: name:discord, class:(Apple Music.*)"
|
|
||||||
|
|
||||||
# Steam
|
|
||||||
"float, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
|
||||||
"workspace name:steam silent, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
|
||||||
"tile, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
|
||||||
"float, class:(.*steam),title:(.*Friends List.*)"
|
|
||||||
|
|
||||||
# Code
|
|
||||||
"pin, class:(.*codium.*),title:(Save As)"
|
|
||||||
"float, class:(.*codium.*),title:(Save As)"
|
|
||||||
"float, class:(xdg-desktop-portal-gtk),title:(Open Workspace from File)"
|
|
||||||
|
|
||||||
# Game Tearing??? https://wiki.hypr.land/Configuring/Tearing/
|
|
||||||
"immediate, class:(.*gamescope)"
|
|
||||||
|
|
||||||
# vmware
|
|
||||||
# this tag will set the below options to the vdi window
|
|
||||||
# this will have it auto open as a 2160x7680 window
|
|
||||||
# and makes multi-monitor work
|
|
||||||
"tag +horizonrdp, class:(.*[Hh]orizon-client),title:(USPS Next VDI)"
|
|
||||||
|
|
||||||
"noanim, tag:horizonrdp"
|
|
||||||
"noblur, tag:horizonrdp"
|
|
||||||
"norounding, tag:horizonrdp"
|
|
||||||
"noshadow, tag:horizonrdp"
|
|
||||||
"immediate, tag:horizonrdp"
|
|
||||||
"allowsinput, tag:horizonrdp"
|
|
||||||
"noborder, tag:horizonrdp"
|
|
||||||
"nodim, tag:horizonrdp"
|
|
||||||
"nomaxsize, tag:horizonrdp"
|
|
||||||
"renderunfocused, tag:horizonrdp"
|
|
||||||
"idleinhibit, tag:horizonrdp"
|
|
||||||
"float, tag:horizonrdp"
|
|
||||||
# float the vmware window cause its annoying to use in fullscreen
|
|
||||||
"float, class:(.*[Hh]orizon-client),title:([Oo]mnissa [Hh]orizon [Cc]lient)"
|
|
||||||
|
|
||||||
"tag +waydroid, class:([Ww]aydroid.*)"
|
|
||||||
"float, tag:waydroid"
|
|
||||||
"pin, tag:waydroid"
|
|
||||||
]
|
|
||||||
++ cfg.windowRule;
|
|
||||||
|
|
||||||
plugin = {
|
|
||||||
# touch_gestures = {
|
|
||||||
# # The default sensitivity is probably too low on tablet screens,
|
|
||||||
# # I recommend turning it up to 4.0
|
|
||||||
# sensitivity = "4.0";
|
|
||||||
|
|
||||||
# # must be >= 3
|
|
||||||
# workspace_swipe_fingers = "3";
|
|
||||||
|
|
||||||
# # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers
|
|
||||||
# # and can be used at the same time
|
|
||||||
# # possible values: l, r, u, or d
|
|
||||||
# # to disable it set it to anything else
|
|
||||||
# workspace_swipe_edge = "d";
|
|
||||||
|
|
||||||
# # in milliseconds
|
|
||||||
# long_press_delay = "400";
|
|
||||||
|
|
||||||
# # resize windows by long-pressing on window borders and gaps.
|
|
||||||
# # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating
|
|
||||||
# # windows
|
|
||||||
# resize_on_border_long_press = true;
|
|
||||||
|
|
||||||
# # in pixels, the distance from the edge that is considered an edge
|
|
||||||
# edge_margin = "10";
|
|
||||||
|
|
||||||
# # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe.
|
|
||||||
# # ONLY triggers when finger count is equal to workspace_swipe_fingers
|
|
||||||
# #
|
|
||||||
# # might be removed in the future in favor of event hooks
|
|
||||||
# emulate_touchpad_swipe = false;
|
|
||||||
|
|
||||||
# experimental = {
|
|
||||||
# # send proper cancel events to windows instead of hacky touch_up events,
|
|
||||||
# # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default
|
|
||||||
# send_cancel = "0";
|
|
||||||
# };
|
|
||||||
|
|
||||||
# hyprgrass-bind = [
|
|
||||||
# # swipe left from right edge
|
|
||||||
# ", edge:r:l, workspace, +1"
|
|
||||||
|
|
||||||
# # swipe up from bottom edge
|
|
||||||
# ", edge:d:u, exec, ${cfg.defaultApps.browser.pname}"
|
|
||||||
|
|
||||||
# # swipe down from left edge
|
|
||||||
# ", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%"
|
|
||||||
|
|
||||||
# # swipe down with 4 fingers
|
|
||||||
# ", swipe:4:d, killactive"
|
|
||||||
|
|
||||||
# # swipe diagonally left and down with 3 fingers
|
|
||||||
# # l (or r) must come before d and u
|
|
||||||
# ", swipe:3:ld, exec, foot"
|
|
||||||
|
|
||||||
# # tap with 3 fingers
|
|
||||||
# ", tap:3, exec, foot"
|
|
||||||
|
|
||||||
# # longpress can trigger mouse binds:
|
|
||||||
# ", longpress:2, movewindow"
|
|
||||||
# ", longpress:3, resizewindow"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
|
|
||||||
gesture = [
|
|
||||||
"3, horizontal, scale: 0.75, workspace" # swipe 3 fingers to change workspace
|
|
||||||
"3, pinch, mod: SUPER, resize"
|
|
||||||
"4, pinch, fullscreen"
|
|
||||||
];
|
|
||||||
|
|
||||||
input = {
|
|
||||||
kb_layout = "us";
|
|
||||||
|
|
||||||
kb_variant = "";
|
|
||||||
kb_model = "";
|
|
||||||
kb_options = "";
|
|
||||||
kb_rules = "";
|
|
||||||
|
|
||||||
numlock_by_default = true;
|
|
||||||
|
|
||||||
follow_mouse = 1;
|
|
||||||
|
|
||||||
touchpad = {
|
|
||||||
clickfinger_behavior = 1;
|
|
||||||
natural_scroll = "yes";
|
|
||||||
};
|
|
||||||
|
|
||||||
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
|
|
||||||
};
|
|
||||||
|
|
||||||
experimental = {
|
|
||||||
xx_color_management_v4 = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
debug = {
|
|
||||||
full_cm_proto = cfg.debug.fullCmProto;
|
|
||||||
disable_logs = cfg.debug.disableLogs;
|
|
||||||
disable_scale_checks = cfg.debug.disableScaleChecks;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig =
|
|
||||||
let
|
|
||||||
autostarts = builtins.concatStringsSep "\n" (map (cmd: "exec-once = ${cmd}") cfg.autostartCommands);
|
|
||||||
in
|
|
||||||
''
|
|
||||||
exec-once = dbus-update-activation-environment --systemd --all
|
|
||||||
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
|
||||||
exec-once = xhost +SI:localuser:root
|
|
||||||
''
|
|
||||||
+ autostarts
|
|
||||||
+ "\n"
|
|
||||||
+ (cfg.extraConfig or "");
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,325 +0,0 @@
|
|||||||
{ lib, pkgs, ... }:
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
options.mjallen.programs.hyprland = {
|
|
||||||
enable = mkEnableOption "enable hyprland";
|
|
||||||
|
|
||||||
primaryDisplay = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "DP-1";
|
|
||||||
description = "Primary display identifier";
|
|
||||||
};
|
|
||||||
|
|
||||||
display1 = {
|
|
||||||
input = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "DP-1";
|
|
||||||
description = "First display identifier (Deprecated: prefer monitorv2)";
|
|
||||||
};
|
|
||||||
|
|
||||||
resolution = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "3840x2160";
|
|
||||||
description = "First display resolution (Deprecated: prefer monitorv2)";
|
|
||||||
};
|
|
||||||
|
|
||||||
refreshRate = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "240.00000";
|
|
||||||
description = "First display refresh rate (Deprecated: prefer monitorv2)";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
display2 = {
|
|
||||||
input = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "DP-1";
|
|
||||||
description = "Second display identifier (Deprecated: prefer monitorv2)";
|
|
||||||
};
|
|
||||||
|
|
||||||
resolution = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "3840x2160";
|
|
||||||
description = "Second display resolution (Deprecated: prefer monitorv2)";
|
|
||||||
};
|
|
||||||
|
|
||||||
refreshRate = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "240.00000";
|
|
||||||
description = "Second display refresh rate (Deprecated: prefer monitorv2)";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Deprecated: prefer hyprpaper.* options
|
|
||||||
wallpaper = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Deprecated: no longer used; prefer hyprpaper.wallpaperPath and hyprpaper.usePerMonitor.";
|
|
||||||
};
|
|
||||||
|
|
||||||
hyprpaper = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
options = {
|
|
||||||
wallpaperPath = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/run/wallpaper.jpg";
|
|
||||||
description = "Path to the wallpaper used by hyprpaper.";
|
|
||||||
};
|
|
||||||
usePerMonitor = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "If true, generate one wallpaper entry per monitor (monitorv2 preferred, falls back to display1/display2).";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Hyprpaper configuration.";
|
|
||||||
};
|
|
||||||
|
|
||||||
monitor = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "List of Hyprland monitor configs (legacy). Example: [ \"eDP-1, 1920x1080@60, 0x0, 1\" ]";
|
|
||||||
};
|
|
||||||
|
|
||||||
monitorv2 = mkOption {
|
|
||||||
type =
|
|
||||||
with types;
|
|
||||||
listOf (
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Monitor name (e.g., DP-1, eDP-1).";
|
|
||||||
};
|
|
||||||
mode = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Resolution@Hz or keyword (e.g., \"3840x2160@144\" or \"preferred\").";
|
|
||||||
};
|
|
||||||
position = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Position like \"0x0\" or \"auto\".";
|
|
||||||
};
|
|
||||||
scale = mkOption {
|
|
||||||
type = types.nullOr types.float;
|
|
||||||
default = null;
|
|
||||||
description = "Scale factor (e.g., 1.0).";
|
|
||||||
};
|
|
||||||
transform = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Rotation/transform (e.g., \"normal\", \"90\", \"180\", \"270\", \"flipped\").";
|
|
||||||
};
|
|
||||||
disabled = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Disable this monitor.";
|
|
||||||
};
|
|
||||||
mirrorOf = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Mirror another monitor by name.";
|
|
||||||
};
|
|
||||||
extra = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Additional monitorv2 flags appended as-is.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
default = [ ];
|
|
||||||
description = "Hyprland monitorv2 entries as structured options; rendered to lines like \"name, mode, position, scale, transform, ...\".";
|
|
||||||
};
|
|
||||||
|
|
||||||
workspace = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "List of hyprland workspace definitions";
|
|
||||||
};
|
|
||||||
|
|
||||||
windowRule = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "List of hyprland window rules";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = with types; str;
|
|
||||||
default = '''';
|
|
||||||
description = "Any extra configuration options";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultApps = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
options = {
|
|
||||||
browser = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.firefox;
|
|
||||||
description = "Default browser";
|
|
||||||
};
|
|
||||||
editor = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.micro;
|
|
||||||
description = "Default text editor";
|
|
||||||
};
|
|
||||||
fileExplorer = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.nautilus;
|
|
||||||
description = "Default file explorer";
|
|
||||||
};
|
|
||||||
visual = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.vscodium;
|
|
||||||
description = "Default visual editor";
|
|
||||||
};
|
|
||||||
terminal = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.kitty;
|
|
||||||
description = "Default terminal";
|
|
||||||
};
|
|
||||||
office = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.onlyoffice-desktopeditors;
|
|
||||||
description = "Default office suite";
|
|
||||||
};
|
|
||||||
video = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.vlc;
|
|
||||||
description = "Default video player";
|
|
||||||
};
|
|
||||||
imageViewer = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.nomacs;
|
|
||||||
description = "Default image viewer";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
description = "Default applications used across the system";
|
|
||||||
};
|
|
||||||
|
|
||||||
autostartCommands = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [
|
|
||||||
"nwg-look -a"
|
|
||||||
"nwg-dock-hyprland -d"
|
|
||||||
];
|
|
||||||
description = "Commands to run via Hyprland exec-once";
|
|
||||||
};
|
|
||||||
|
|
||||||
launcher = mkOption {
|
|
||||||
type = types.enum [
|
|
||||||
"wofi"
|
|
||||||
"rofi"
|
|
||||||
];
|
|
||||||
default = "wofi";
|
|
||||||
description = "Application launcher to use in keybinds and packages.";
|
|
||||||
};
|
|
||||||
|
|
||||||
notificationDaemon = mkOption {
|
|
||||||
type = types.enum [
|
|
||||||
"mako"
|
|
||||||
"dunst"
|
|
||||||
];
|
|
||||||
default = "mako";
|
|
||||||
description = "Notification daemon to install.";
|
|
||||||
};
|
|
||||||
|
|
||||||
modKey = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "SUPER";
|
|
||||||
description = "Modifier key used for Hyprland binds (e.g., SUPER, ALT).";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableVRR = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Enable variable refresh rate (maps to Hyprland misc.vrr).";
|
|
||||||
};
|
|
||||||
|
|
||||||
allowTearing = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Allow tearing (maps to Hyprland general.allow_tearing).";
|
|
||||||
};
|
|
||||||
|
|
||||||
debug = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
options = {
|
|
||||||
disableLogs = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Set Hyprland debug.disable_logs.";
|
|
||||||
};
|
|
||||||
fullCmProto = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Set Hyprland debug.full_cm_proto.";
|
|
||||||
};
|
|
||||||
disableScaleChecks = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Set Hyprland debug.disable_scale_checks.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Hyprland debug flags.";
|
|
||||||
};
|
|
||||||
|
|
||||||
keybinds = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
options = {
|
|
||||||
bind = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Hyprland bind entries.";
|
|
||||||
};
|
|
||||||
bindm = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Hyprland bindm entries.";
|
|
||||||
};
|
|
||||||
bindel = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Hyprland bindel entries.";
|
|
||||||
};
|
|
||||||
bindl = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Hyprland bindl entries.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Keybinding lists for Hyprland; useful for host-level overrides.";
|
|
||||||
};
|
|
||||||
|
|
||||||
gestures = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Hyprland gesture entries.";
|
|
||||||
};
|
|
||||||
|
|
||||||
hyprIdle = {
|
|
||||||
lockScreenTimer = mkOption {
|
|
||||||
type = with types; int;
|
|
||||||
default = 300;
|
|
||||||
description = "Time in seconds before locking the screen";
|
|
||||||
};
|
|
||||||
screenOffTimer = mkOption {
|
|
||||||
type = with types; int;
|
|
||||||
default = 900;
|
|
||||||
description = "Time in seconds before turning off the screen";
|
|
||||||
};
|
|
||||||
suspendTimer = mkOption {
|
|
||||||
type = with types; int;
|
|
||||||
default = 1800;
|
|
||||||
description = "Time in seconds before suspending";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.kitty;
|
cfg = config.mjallen.programs.kitty;
|
||||||
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -11,14 +12,94 @@ in
|
|||||||
enable = true;
|
enable = true;
|
||||||
shellIntegration.enableZshIntegration = true;
|
shellIntegration.enableZshIntegration = true;
|
||||||
|
|
||||||
|
font = {
|
||||||
|
name = cfg.font.name;
|
||||||
|
package = cfg.font.package;
|
||||||
|
size = cfg.font.size;
|
||||||
|
};
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
bold_font = "auto";
|
bold_font = "auto";
|
||||||
italic_font = "auto";
|
italic_font = "auto";
|
||||||
bold_italic_font = "auto";
|
bold_italic_font = "auto";
|
||||||
mouse_hide_wait = "2.0";
|
mouse_hide_wait = "2.0";
|
||||||
cursor_shape = "block";
|
cursor_shape = "block";
|
||||||
url_style = "dotted";
|
url_style = "dotted";
|
||||||
confirm_os_window_close = "0";
|
confirm_os_window_close = "0";
|
||||||
|
background_opacity = "0.85";
|
||||||
|
|
||||||
|
# The basic colors
|
||||||
|
foreground = nord.snowStorm.nord6;
|
||||||
|
background = nord.polarNight.nord0;
|
||||||
|
selection_foreground = nord.polarNight.nord0;
|
||||||
|
selection_background = nord.aurora.nord15;
|
||||||
|
|
||||||
|
# Cursor colors
|
||||||
|
cursor = nord.aurora.nord15;
|
||||||
|
cursor_text_color = nord.polarNight.nord0;
|
||||||
|
|
||||||
|
# URL underline color when hovering with mouse
|
||||||
|
url_color = nord.aurora.nord15;
|
||||||
|
|
||||||
|
# Kitty window border colors
|
||||||
|
active_border_color = nord.frost.nord10;
|
||||||
|
inactive_border_color = nord.polarNight.nord1;
|
||||||
|
bell_border_color = nord.aurora.nord13;
|
||||||
|
|
||||||
|
# OS Window titlebar colors
|
||||||
|
wayland_titlebar_color = nord.polarNight.nord0;
|
||||||
|
macos_titlebar_color = nord.polarNight.nord0;
|
||||||
|
|
||||||
|
# Tab bar colors
|
||||||
|
active_tab_foreground = nord.polarNight.nord3;
|
||||||
|
active_tab_background = nord.aurora.nord15;
|
||||||
|
inactive_tab_foreground = nord.snowStorm.nord6;
|
||||||
|
inactive_tab_background = nord.polarNight.nord1;
|
||||||
|
tab_bar_background = nord.polarNight.nord3;
|
||||||
|
|
||||||
|
# Colors for marks (marked text in the terminal)
|
||||||
|
mark1_foreground = nord.polarNight.nord0;
|
||||||
|
mark1_background = nord.frost.nord10;
|
||||||
|
mark2_foreground = nord.polarNight.nord0;
|
||||||
|
mark2_background = nord.aurora.nord15;
|
||||||
|
mark3_foreground = nord.polarNight.nord0;
|
||||||
|
mark3_background = nord.frost.nord8;
|
||||||
|
|
||||||
|
# The 16 terminal colors
|
||||||
|
|
||||||
|
# black
|
||||||
|
color0 = nord.polarNight.nord0;
|
||||||
|
|
||||||
|
# Autosuggestion
|
||||||
|
color8 = nord.frost.nord10;
|
||||||
|
|
||||||
|
# red
|
||||||
|
color1 = nord.aurora.nord11;
|
||||||
|
color9 = nord.aurora.nord11;
|
||||||
|
|
||||||
|
# green
|
||||||
|
color2 = nord.aurora.nord14;
|
||||||
|
color10 = nord.aurora.nord14;
|
||||||
|
|
||||||
|
# yellow
|
||||||
|
color3 = nord.aurora.nord13;
|
||||||
|
color11 = nord.aurora.nord13;
|
||||||
|
|
||||||
|
# blue
|
||||||
|
color4 = nord.frost.nord10;
|
||||||
|
color12 = nord.frost.nord10;
|
||||||
|
|
||||||
|
# magenta
|
||||||
|
color5 = nord.aurora.nord15;
|
||||||
|
color13 = nord.aurora.nord15;
|
||||||
|
|
||||||
|
# cyan
|
||||||
|
color6 = nord.frost.nord8;
|
||||||
|
color14 = nord.frost.nord8;
|
||||||
|
|
||||||
|
# white
|
||||||
|
color7 = nord.snowStorm.nord5;
|
||||||
|
color15 = nord.snowStorm.nord4;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,27 @@
|
|||||||
{ lib, namespace, ... }:
|
{ lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) mkOpt;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
options.mjallen.programs.kitty = {
|
options.mjallen.programs.kitty = {
|
||||||
enable = mkEnableOption "enable kitty terminal";
|
enable = mkEnableOption "enable kitty terminal";
|
||||||
|
|
||||||
|
font = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "DejaVu Sans";
|
||||||
|
};
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.dejavu_fonts;
|
||||||
|
};
|
||||||
|
size = mkOption {
|
||||||
|
type = with types; int;
|
||||||
|
default = 12;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
theme = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.mako;
|
cfg = config.mjallen.programs.mako;
|
||||||
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -9,7 +10,7 @@ in
|
|||||||
services.mako = {
|
services.mako = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
font = mkDefault cfg.fontName;
|
font = cfg.fontName;
|
||||||
icons = true;
|
icons = true;
|
||||||
ignore-timeout = true;
|
ignore-timeout = true;
|
||||||
sort = "-time";
|
sort = "-time";
|
||||||
@@ -21,10 +22,10 @@ in
|
|||||||
max-icon-size = 64;
|
max-icon-size = 64;
|
||||||
default-timeout = 5000;
|
default-timeout = 5000;
|
||||||
|
|
||||||
# background-color = mkDefault config.lib.stylix.colors.base00;
|
background-color = nord.polarNight.nord0;
|
||||||
# text-color = mkDefault config.lib.stylix.colors.base06;
|
text-color = nord.snowStorm.nord6;
|
||||||
# border-color = mkDefault config.lib.stylix.colors.base0F;
|
border-color = nord.frost.nord10;
|
||||||
# progress-color = mkDefault "over ${config.lib.stylix.colors.base0C}";
|
progress-color = "over ${nord.frost.nord8}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.nwg-dock;
|
cfg = config.mjallen.programs.nwg-dock;
|
||||||
palette = import cfg.theme.file;
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -18,11 +18,11 @@ in
|
|||||||
home.file = {
|
home.file = {
|
||||||
".config/nwg-dock-hyprland/drawer.css".text = ''
|
".config/nwg-dock-hyprland/drawer.css".text = ''
|
||||||
window {
|
window {
|
||||||
background: ${config.lib.stylix.colors.base00};
|
background: ${nord.polarNight.nord0};
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: ${config.lib.stylix.colors.base0E}b0
|
border-color: ${nord.aurora.nord15}b0
|
||||||
}
|
}
|
||||||
|
|
||||||
#box {
|
#box {
|
||||||
@@ -33,14 +33,14 @@ in
|
|||||||
active {
|
active {
|
||||||
/* This is to underline the button representing the currently active window */
|
/* This is to underline the button representing the currently active window */
|
||||||
border-bottom: solid 1px;
|
border-bottom: solid 1px;
|
||||||
border-color: ${config.lib.stylix.colors.base0B}1a
|
border-color: ${nord.aurora.nord14}1a
|
||||||
}
|
}
|
||||||
|
|
||||||
button, image {
|
button, image {
|
||||||
background: none;
|
background: none;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
color: ${config.lib.stylix.colors.base0F}
|
color: ${nord.frost.nord10}
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@@ -52,7 +52,7 @@ in
|
|||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
background-color: ${config.lib.stylix.colors.base00}1a;
|
background-color: ${nord.polarNight.nord0}1a;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.nwg-drawer;
|
cfg = config.mjallen.programs.nwg-drawer;
|
||||||
palette = import cfg.theme.file;
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -18,13 +18,13 @@ in
|
|||||||
home.file = {
|
home.file = {
|
||||||
".config/nwg-drawer/drawer.css".text = ''
|
".config/nwg-drawer/drawer.css".text = ''
|
||||||
window {
|
window {
|
||||||
background-color: ${config.lib.stylix.colors.base00}bf;
|
background-color: ${nord.polarNight.nord0}bf;
|
||||||
color: ${config.lib.stylix.colors.base05}00
|
color: ${nord.snowStorm.nord5}00
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search entry */
|
/* search entry */
|
||||||
entry {
|
entry {
|
||||||
background-color: ${config.lib.stylix.colors.base01}0f
|
background-color: ${nord.polarNight.nord1}0f
|
||||||
}
|
}
|
||||||
|
|
||||||
button, image {
|
button, image {
|
||||||
@@ -33,7 +33,7 @@ in
|
|||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
background-color: ${config.lib.stylix.colors.base0F}1a
|
background-color: ${nord.frost.nord10}1a
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in case you wanted to give category buttons a different look */
|
/* in case you wanted to give category buttons a different look */
|
||||||
@@ -43,12 +43,12 @@ in
|
|||||||
|
|
||||||
#pinned-box {
|
#pinned-box {
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
border-bottom: 1px dotted ${config.lib.stylix.colors.base03}
|
border-bottom: 1px dotted ${nord.polarNight.nord3}
|
||||||
}
|
}
|
||||||
|
|
||||||
#files-box {
|
#files-box {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border: 1px dotted ${config.lib.stylix.colors.base03};
|
border: 1px dotted ${nord.polarNight.nord3};
|
||||||
border-radius: 15px
|
border-radius: 15px
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ with lib;
|
|||||||
};
|
};
|
||||||
fileExplorer = mkOption {
|
fileExplorer = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.nautilus;
|
default = pkgs.nemo;
|
||||||
};
|
};
|
||||||
visual = mkOption {
|
visual = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
@@ -29,7 +29,7 @@ with lib;
|
|||||||
};
|
};
|
||||||
office = mkOption {
|
office = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.onlyoffice-desktopeditors;
|
default = pkgs.onlyoffice-bin_latest;
|
||||||
};
|
};
|
||||||
video = mkOption {
|
video = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
{
|
{ lib, system, ... }:
|
||||||
lib,
|
|
||||||
system,
|
|
||||||
hasDestopEnvironment ? true,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
isArm = builtins.match "aarch64*" system != null;
|
isArm = builtins.match "aarch64*" system != null;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
programs.onlyoffice = {
|
programs.onlyoffice = {
|
||||||
enable = lib.mkDefault (!isArm && hasDestopEnvironment);
|
enable = lib.mkDefault (!isArm);
|
||||||
settings = {
|
settings = {
|
||||||
UITheme = "theme-contrast-dark";
|
UITheme = "theme-contrast-dark";
|
||||||
forcedRtl = false;
|
forcedRtl = false;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,333 +1,69 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
|
||||||
inherit (types)
|
|
||||||
str
|
|
||||||
int
|
|
||||||
bool
|
|
||||||
listOf
|
|
||||||
attrs
|
|
||||||
path
|
|
||||||
nullOr
|
|
||||||
submodule
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
options.mjallen.programs.waybar = {
|
options.mjallen.programs.waybar = {
|
||||||
enable = mkEnableOption "Waybar status bar";
|
enable = mkEnableOption "enable waybar";
|
||||||
|
|
||||||
# Legacy/compat options (kept for backwards compatibility)
|
|
||||||
layer = mkOption {
|
layer = mkOption {
|
||||||
type = str;
|
type = types.str;
|
||||||
default = "top";
|
default = "top";
|
||||||
description = "Waybar layer (compat). Prefer layout + feature flags.";
|
};
|
||||||
|
|
||||||
|
modules-right = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networkInterface = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "wlan0";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraModules = mkOption {
|
extraModules = mkOption {
|
||||||
type = attrs;
|
type = types.attrs;
|
||||||
default = { };
|
default = { };
|
||||||
description = "Extra settings bars at top-level (compat with older module).";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extraModulesStyle = mkOption {
|
extraModulesStyle = mkOption {
|
||||||
type = str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
description = "Extra CSS appended (compat). Prefer extra.style.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
windowOffset = mkOption {
|
windowOffset = mkOption {
|
||||||
type = int;
|
type = types.int;
|
||||||
default = 4;
|
default = 4;
|
||||||
description = "Right margin offset for the hyprland/window module (in rem).";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Layout
|
# Waybar modules config
|
||||||
layout = mkOption {
|
# modules = mkOption {
|
||||||
type = submodule {
|
# type = types.submodule {
|
||||||
options = {
|
# options = {
|
||||||
left = mkOption {
|
# # Modules
|
||||||
type = listOf str;
|
# window = mkOption {
|
||||||
default = [ "hyprland/workspaces" ];
|
# type = types.submodule {
|
||||||
description = "Modules shown on the left.";
|
# options = {
|
||||||
};
|
# # Waybar Module CSS
|
||||||
center = mkOption {
|
# margin-right = mkOption {
|
||||||
type = listOf str;
|
# type = types.str;
|
||||||
default = [ "hyprland/window" ];
|
# default = "4";
|
||||||
description = "Modules shown in the center.";
|
# };
|
||||||
};
|
# };
|
||||||
right = mkOption {
|
# };
|
||||||
type = listOf str;
|
# };
|
||||||
default = [
|
# temperature = mkOption {
|
||||||
"tray"
|
# type = types.submodule {
|
||||||
"custom/left-end"
|
# options = {
|
||||||
"temperature"
|
# # Waybar Module CSS
|
||||||
"temperature#gpu"
|
# margin-right = mkOption {
|
||||||
"keyboard-state#capslock"
|
# type = types.str;
|
||||||
"keyboard-state#numlock"
|
# default = "4";
|
||||||
"wireplumber#sink"
|
# };
|
||||||
"bluetooth"
|
# };
|
||||||
"network"
|
# };
|
||||||
"idle_inhibitor"
|
# };
|
||||||
"custom/right-end"
|
# };
|
||||||
"custom/left-end"
|
# };
|
||||||
"clock"
|
# default = { };
|
||||||
"battery"
|
# };
|
||||||
"custom/notifications"
|
|
||||||
"custom/weather"
|
|
||||||
"custom/power"
|
|
||||||
"custom/right-end"
|
|
||||||
];
|
|
||||||
description = "Modules shown on the right.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Waybar module layout.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Network
|
|
||||||
network = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
interface = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "wlan0";
|
|
||||||
description = "Primary network interface name.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Network configuration.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Temperatures
|
|
||||||
temperature = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
cpu = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
description = "Enable CPU temperature module.";
|
|
||||||
};
|
|
||||||
hwmonPath = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "/sys/devices/pci0000:00/0000:00:18.3/hwmon";
|
|
||||||
description = "CPU temperature hwmon path.";
|
|
||||||
};
|
|
||||||
hwmonFile = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "temp1_input";
|
|
||||||
description = "CPU temperature hwmon file.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
gpu = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
description = "Enable GPU temperature module.";
|
|
||||||
};
|
|
||||||
hwmonPath = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "/sys/devices/pci0000:00/0000:00:01.1/0000:01:00.0/0000:02:00.0/0000:03:00.0/hwmon";
|
|
||||||
description = "GPU temperature hwmon path.";
|
|
||||||
};
|
|
||||||
hwmonFile = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "temp1_input";
|
|
||||||
description = "GPU temperature hwmon file.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Temperature module configuration.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Features
|
|
||||||
features = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
tray = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
bluetooth = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
idleInhibitor = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
keyboardIndicators = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
audio = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
sink = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
source = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
weather = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
hass = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
clock = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
battery = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Toggle optional Waybar features.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Styling
|
|
||||||
style = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
file = mkOption {
|
|
||||||
type = nullOr path;
|
|
||||||
default = null;
|
|
||||||
description = "Optional external CSS file to use instead of the inline style.";
|
|
||||||
};
|
|
||||||
fragmentsDir = mkOption {
|
|
||||||
type = nullOr path;
|
|
||||||
default = null;
|
|
||||||
description = "Optional directory of CSS fragments to append.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Styling configuration.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Extra overrides
|
|
||||||
extra = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
settings = mkOption {
|
|
||||||
type = attrs;
|
|
||||||
default = { };
|
|
||||||
description = "Extra settings merged into settings.mainBar.";
|
|
||||||
};
|
|
||||||
style = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "";
|
|
||||||
description = "Extra CSS appended to the computed style.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Extra settings/style hooks.";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.${namespace}.programs.waybar;
|
|
||||||
|
|
||||||
waybar-audio = pkgs.writeScriptBin "waybar-audio" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Extract sink entries: "ID Description"
|
|
||||||
choices=$(pw-dump | jq -r '
|
|
||||||
.. | objects
|
|
||||||
| select(.["media.class"] == "Audio/Sink")
|
|
||||||
| "\(.["object.id"]) \(.["node.description"])"
|
|
||||||
'
|
|
||||||
)
|
|
||||||
|
|
||||||
# Show wofi menu
|
|
||||||
selected=$(printf "%s\n" "$choices" | wofi --dmenu --prompt "Audio Output")
|
|
||||||
|
|
||||||
# Extract ID
|
|
||||||
id=$(echo "$selected" | awk '{print $1}')
|
|
||||||
|
|
||||||
# Switch to the selected device
|
|
||||||
if [ -n "$id" ]; then
|
|
||||||
wpctl set-default "$id"
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ ../options.nix ];
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [ waybar-audio ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.${namespace}.programs.waybar;
|
|
||||||
|
|
||||||
waybar-media = pkgs.writeScriptBin "waybar-media" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Get current playing song from playerctl
|
|
||||||
if command -v playerctl &> /dev/null; then
|
|
||||||
# Check if any player is running
|
|
||||||
if playerctl status &> /dev/null; then
|
|
||||||
artist=$(playerctl metadata xesam:artist 2>/dev/null)
|
|
||||||
title=$(playerctl metadata xesam:title 2>/dev/null)
|
|
||||||
|
|
||||||
if [[ -n "$artist" && -n "$title" ]]; then
|
|
||||||
echo "♪ $artist - $title"
|
|
||||||
elif [[ -n "$title" ]]; then
|
|
||||||
echo "♪ ''\${title//&/&}"
|
|
||||||
else
|
|
||||||
echo "♪ Music Playing"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
waybar-media-art = pkgs.writeScriptBin "waybar-media-art" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Get current playing song from playerctl
|
|
||||||
if command -v playerctl &> /dev/null; then
|
|
||||||
# Check if any player is running
|
|
||||||
if playerctl status &> /dev/null; then
|
|
||||||
art=$(playerctl metadata mpris:artUrl 2>/dev/null)
|
|
||||||
|
|
||||||
if [[ -n "$art" ]]; then
|
|
||||||
echo ''\${art#file://}
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ ../options.nix ];
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [
|
|
||||||
waybar-media
|
|
||||||
waybar-media-art
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.${namespace}.programs.waybar;
|
|
||||||
|
|
||||||
waybar-notifications = pkgs.writeScriptBin "waybar-notifications" ''
|
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import json
|
|
||||||
import codecs
|
|
||||||
import re
|
|
||||||
|
|
||||||
def check_notifications(args = "history"):
|
|
||||||
notifications = []
|
|
||||||
number = None
|
|
||||||
content = None
|
|
||||||
appname = None
|
|
||||||
urgency = None
|
|
||||||
cmd = "makoctl"
|
|
||||||
temp = subprocess.Popen([cmd, args], stdout = subprocess.PIPE)
|
|
||||||
output = str(temp.communicate()).replace("(b\'", "").replace("\', None)", "")
|
|
||||||
lines = output.split("\\n")
|
|
||||||
for line in lines:
|
|
||||||
if "Notification" in line:
|
|
||||||
number = line.split(":")[0].replace("Notification ", "")
|
|
||||||
content = re.sub(r"[\u2066\u2067\u2068\u2069, \u00e2\u0081\u00a8]", "", codecs.decode(line.split(": ")[-1].encode("latin1").decode("utf-8"), "unicode_escape"))
|
|
||||||
content = re.sub(r"[\u00a9]", " ", content)
|
|
||||||
|
|
||||||
if "App name" in line:
|
|
||||||
appname = line.split(": ")[-1]
|
|
||||||
if "Urgency" in line:
|
|
||||||
urgency = line.split(": ")[-1]
|
|
||||||
|
|
||||||
if number is not None and content is not None and appname is not None and urgency is not None:
|
|
||||||
notifications.append((number, content, appname, urgency))
|
|
||||||
number = None
|
|
||||||
content = None
|
|
||||||
appname = None
|
|
||||||
urgency = None
|
|
||||||
|
|
||||||
return notifications
|
|
||||||
|
|
||||||
def get_icon(notifications):
|
|
||||||
status = ""
|
|
||||||
icon = ""
|
|
||||||
|
|
||||||
for number, content, appname, urgency in notifications:
|
|
||||||
status = "notify"
|
|
||||||
if urgency != "normal":
|
|
||||||
status = "alert"
|
|
||||||
break
|
|
||||||
|
|
||||||
if status == "notify":
|
|
||||||
icon = ""
|
|
||||||
if status == "alert":
|
|
||||||
icon = ""
|
|
||||||
|
|
||||||
return icon, status
|
|
||||||
|
|
||||||
def build_tooltip(notifications):
|
|
||||||
tooltip = ""
|
|
||||||
for number, content, appname, urgency in notifications:
|
|
||||||
tooltip += "{0}: {1}\n".format(appname, content)
|
|
||||||
|
|
||||||
return tooltip
|
|
||||||
|
|
||||||
def main():
|
|
||||||
notifications = check_notifications()
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
icon, status = get_icon(notifications)
|
|
||||||
|
|
||||||
data["text"] = icon
|
|
||||||
data["tooltip"] = build_tooltip(notifications)
|
|
||||||
data["class"] = status
|
|
||||||
|
|
||||||
print(json.dumps(data, ensure_ascii=False))
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ ../options.nix ];
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [ waybar-notifications ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -16,18 +16,9 @@ let
|
|||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import argparse
|
|
||||||
import math
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(prog='waybar-weather')
|
|
||||||
parser.add_argument('--waybar', action='store_true')
|
|
||||||
parser.add_argument('--hyprlock', action='store_true')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# --- MAPPINGS ---
|
|
||||||
|
|
||||||
WWO_CODE = {
|
WWO_CODE = {
|
||||||
"113": "Sunny",
|
"113": "Sunny",
|
||||||
"116": "PartlyCloudy",
|
"116": "PartlyCloudy",
|
||||||
@@ -79,38 +70,6 @@ let
|
|||||||
"395": "HeavySnowShowers",
|
"395": "HeavySnowShowers",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Maps WMO codes (OpenMeteo) to WWO codes (wttr.in)
|
|
||||||
WMO_TO_WWO = {
|
|
||||||
0: "113", # Clear sky -> Sunny
|
|
||||||
1: "113", # Mainly clear -> Sunny
|
|
||||||
2: "116", # Partly cloudy
|
|
||||||
3: "122", # Overcast -> VeryCloudy
|
|
||||||
45: "143", # Fog
|
|
||||||
48: "248", # Depositing rime fog
|
|
||||||
51: "266", # Drizzle: Light
|
|
||||||
53: "266", # Drizzle: Moderate (mapped to LightRain)
|
|
||||||
55: "296", # Drizzle: Dense intensity (LightRain usually suits better than heavy)
|
|
||||||
56: "281", # Freezing Drizzle: Light
|
|
||||||
57: "284", # Freezing Drizzle: Dense
|
|
||||||
61: "296", # Rain: Slight
|
|
||||||
63: "302", # Rain: Moderate
|
|
||||||
65: "308", # Rain: Heavy
|
|
||||||
66: "311", # Freezing Rain: Light
|
|
||||||
67: "314", # Freezing Rain: Heavy
|
|
||||||
71: "326", # Snow fall: Slight
|
|
||||||
73: "332", # Snow fall: Moderate
|
|
||||||
75: "338", # Snow fall: Heavy
|
|
||||||
77: "350", # Snow grains
|
|
||||||
80: "353", # Rain showers: Slight
|
|
||||||
81: "356", # Rain showers: Moderate
|
|
||||||
82: "359", # Rain showers: Violent
|
|
||||||
85: "368", # Snow showers: Slight
|
|
||||||
86: "371", # Snow showers: Heavy
|
|
||||||
95: "386", # Thunderstorm: Slight or moderate
|
|
||||||
96: "389", # Thunderstorm with slight hail
|
|
||||||
99: "395", # Thunderstorm with heavy hail
|
|
||||||
}
|
|
||||||
|
|
||||||
WEATHER_SYMBOL = {
|
WEATHER_SYMBOL = {
|
||||||
"Unknown": "",
|
"Unknown": "",
|
||||||
"Cloudy": "",
|
"Cloudy": "",
|
||||||
@@ -150,6 +109,10 @@ let
|
|||||||
"SSE": "↘",
|
"SSE": "↘",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOON_PHASES = (
|
||||||
|
"", "", "", "", "", "", "", ""
|
||||||
|
)
|
||||||
|
|
||||||
WEATHER_SYMBOL_WI_DAY = {
|
WEATHER_SYMBOL_WI_DAY = {
|
||||||
"Unknown": "",
|
"Unknown": "",
|
||||||
"Cloudy": "",
|
"Cloudy": "",
|
||||||
@@ -226,117 +189,117 @@ let
|
|||||||
' '],
|
' '],
|
||||||
"VeryCloudy": [
|
"VeryCloudy": [
|
||||||
' ',
|
' ',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> .--. </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> .--. </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> .-( ). </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> .-( ). </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> (___.__)__) </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> (___.__)__) </span>',
|
||||||
' '],
|
' '],
|
||||||
"LightShowers": [
|
"LightShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>',
|
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>'],
|
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>'],
|
||||||
"HeavyShowers": [
|
"HeavyShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\" font-weight="bold">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\"; font-weight: bold;">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\" font-weight="bold">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\"; font-weight: bold;">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\" font-weight="bold">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\"; font-weight: bold;">(___(__) </span>',
|
||||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚‘‚‘‚‘‚‘ </span>',
|
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚‘‚‘‚‘‚‘ </span>',
|
||||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚’‚’‚’‚’ </span>'],
|
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚’‚’‚’‚’ </span>'],
|
||||||
"LightSnowShowers": [
|
"LightSnowShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||||
'<span foreground=\"#eeeeee\"> * * * </span>',
|
'<span foreground=\"#eeeeee\";"> * * * </span>',
|
||||||
'<span foreground=\"#eeeeee\"> * * * </span>'],
|
'<span foreground=\"#eeeeee\";"> * * * </span>'],
|
||||||
"HeavySnowShowers": [
|
"HeavySnowShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\" font-weight="bold">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\"; font-weight: bold;">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\" font-weight="bold">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\"; font-weight: bold;">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\" font-weight="bold">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\"; font-weight: bold;">(___(__) </span>',
|
||||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>',
|
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>',
|
||||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>'],
|
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>'],
|
||||||
"LightSleetShowers": [
|
"LightSleetShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">* </span>',
|
'<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">* </span>',
|
||||||
'<span foreground=\"#eeeeee\"> *</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>'],
|
'<span foreground=\"#eeeeee\";"> *</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>'],
|
||||||
"ThunderyShowers": [
|
"ThunderyShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||||
'<span foreground=\"#ffff87\"> ⚡\\</span>"<span foreground=\"#87afff\">‘ ‘</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#87afff\">‘ ‘ </span>',
|
'<span foreground=\"#ffff87\";"> ⚡\\</span>"<span foreground=\"#87afff\";">‘ ‘</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#87afff\";">‘ ‘ </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>'],
|
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>'],
|
||||||
"ThunderyHeavyRain": [
|
"ThunderyHeavyRain": [
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> .-. </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> .-. </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> ( ). </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> ( ). </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> (___(__) </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> (___(__) </span>',
|
||||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚‘</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#0000ff\">‘‚</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#0000ff\">‚‘ </span>',
|
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚‘</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">‘‚</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">‚‘ </span>',
|
||||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚’‚’</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#0000ff\">’‚’ </span>'],
|
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚’‚’</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">’‚’ </span>'],
|
||||||
"ThunderySnowShowers": [
|
"ThunderySnowShowers": [
|
||||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||||
'<span foreground=\"#eeeeee\"> *</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#eeeeee\">* </span>',
|
'<span foreground=\"#eeeeee\";"> *</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#eeeeee\";">* </span>',
|
||||||
'<span foreground=\"#eeeeee\"> * * * </span>'],
|
'<span foreground=\"#eeeeee\";"> * * * </span>'],
|
||||||
"LightRain": [
|
"LightRain": [
|
||||||
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
||||||
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
||||||
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>',
|
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>'],
|
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>'],
|
||||||
"HeavyRain": [
|
"HeavyRain": [
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> .-. </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> .-. </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> ( ). </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> ( ). </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> (___(__) </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> (___(__) </span>',
|
||||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚‘‚‘‚‘‚‘ </span>',
|
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚‘‚‘‚‘‚‘ </span>',
|
||||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚’‚’‚’‚’ </span>'],
|
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚’‚’‚’‚’ </span>'],
|
||||||
"LightSnow": [
|
"LightSnow": [
|
||||||
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
||||||
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
||||||
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
||||||
'<span foreground=\"#eeeeee\"> * * * </span>',
|
'<span foreground=\"#eeeeee\";"> * * * </span>',
|
||||||
'<span foreground=\"#eeeeee\"> * * * </span>'],
|
'<span foreground=\"#eeeeee\";"> * * * </span>'],
|
||||||
"HeavySnow": [
|
"HeavySnow": [
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> .-. </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> .-. </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> ( ). </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> ( ). </span>',
|
||||||
'<span foreground=\"#585858\" font-weight="bold"> (___(__) </span>',
|
'<span foreground=\"#585858\"; font-weight: bold;"> (___(__) </span>',
|
||||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>',
|
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>',
|
||||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>'],
|
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>'],
|
||||||
"LightSleet": [
|
"LightSleet": [
|
||||||
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
||||||
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
||||||
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
||||||
'<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">* </span>',
|
'<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">* </span>',
|
||||||
'<span foreground=\"#eeeeee\"> *</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>'],
|
'<span foreground=\"#eeeeee\";"> *</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>'],
|
||||||
"Fog": [
|
"Fog": [
|
||||||
' ',
|
' ',
|
||||||
'<span foreground=\"#c0c0c0\"> _ - _ - _ - </span>',
|
'<span foreground=\"#c0c0c0\";"> _ - _ - _ - </span>',
|
||||||
'<span foreground=\"#c0c0c0\"> _ - _ - _ </span>',
|
'<span foreground=\"#c0c0c0\";"> _ - _ - _ </span>',
|
||||||
'<span foreground=\"#c0c0c0\"> _ - _ - _ - </span>',
|
'<span foreground=\"#c0c0c0\";"> _ - _ - _ - </span>',
|
||||||
' '],
|
' '],
|
||||||
}
|
}
|
||||||
|
|
||||||
WEATHER_CODES_WEGO = {key: WEATHER_SYMBOL_WEGO[value] for key, value in WWO_CODE.items()}
|
WEATHER_CODES_WEGO = {key: WEATHER_SYMBOL_WEGO[value] for key, value in WWO_CODE.items()}
|
||||||
|
|
||||||
CACHE_DIR = os.path.join(os.environ.get("XDG_CACHE_HOME", os.path.expanduser("~/.cache")), "waybar-weather")
|
|
||||||
CACHE_FILE = os.path.join(CACHE_DIR, "wttr.json")
|
|
||||||
CACHE_MOON_FILE = os.path.join(CACHE_DIR, "moon.json")
|
|
||||||
CACHE_MOON_ICON_FILE = os.path.join(CACHE_DIR, "moon-icon")
|
|
||||||
CACHE_TTL = timedelta(minutes=10)
|
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
data["text"] = ""
|
|
||||||
|
|
||||||
def format_time(time):
|
def format_time(time):
|
||||||
|
"""get the time formatted"""
|
||||||
return datetime.strptime(format_24_time(time), "%H").strftime("%I %p")
|
return datetime.strptime(format_24_time(time), "%H").strftime("%I %p")
|
||||||
|
|
||||||
def format_24_time(time):
|
def format_24_time(time):
|
||||||
|
"""get the time formatted"""
|
||||||
return time.replace("00", "").zfill(2)
|
return time.replace("00", "").zfill(2)
|
||||||
|
|
||||||
|
|
||||||
def format_temp(temp):
|
def format_temp(temp):
|
||||||
return (str(temp) + "°").ljust(3)
|
"""get the temp formatted"""
|
||||||
|
return (temp + "°").ljust(3)
|
||||||
|
|
||||||
|
|
||||||
def format_chances(hour):
|
def format_chances(hour):
|
||||||
|
"""get the chances formatted"""
|
||||||
chances = {
|
chances = {
|
||||||
"chanceoffog": "Fog",
|
"chanceoffog": "Fog",
|
||||||
"chanceoffrost": "Frost",
|
"chanceoffrost": "Frost",
|
||||||
@@ -347,67 +310,62 @@ let
|
|||||||
"chanceofthunder": "Thunder",
|
"chanceofthunder": "Thunder",
|
||||||
"chanceofwindy": "Wind",
|
"chanceofwindy": "Wind",
|
||||||
}
|
}
|
||||||
|
|
||||||
conditions = []
|
conditions = []
|
||||||
for chance, event in chances.items():
|
for chance, event in chances.items():
|
||||||
if int(hour.get(chance, 0)) > 0:
|
if int(hour[chance]) > 0:
|
||||||
conditions.append(event + " " + str(hour[chance]) + "%")
|
conditions.append(event + " " + hour[chance] + "%")
|
||||||
return ", ".join(conditions)
|
return ", ".join(conditions)
|
||||||
|
|
||||||
def deg_to_compass(num):
|
|
||||||
val = int((num / 22.5) + 0.5)
|
|
||||||
arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"]
|
|
||||||
return arr[(val % 16)]
|
|
||||||
|
|
||||||
def build_text(current_condition):
|
def build_text(current_condition):
|
||||||
|
"""build the text string"""
|
||||||
feels_like_f = current_condition["FeelsLikeF"]
|
feels_like_f = current_condition["FeelsLikeF"]
|
||||||
weather_code = current_condition["weatherCode"]
|
weather_code = current_condition["weatherCode"]
|
||||||
# Check if we have a mapped format; if not, fallback to Unknown
|
|
||||||
if weather_code not in WEATHER_CODES:
|
|
||||||
weather_code = "113" # Fallback to sunny/default to prevent crash
|
|
||||||
|
|
||||||
tempint = int(float(feels_like_f)) # float cast just in case
|
tempint = int(feels_like_f)
|
||||||
extrachar = ""
|
extrachar = ""
|
||||||
if 0 < tempint < 10:
|
if 0 < tempint < 10:
|
||||||
extrachar = "+"
|
extrachar = "+"
|
||||||
|
|
||||||
current_weather = f"{WEATHER_CODES[weather_code]} {extrachar} {int(feels_like_f)}°F"
|
current_weather = f"{WEATHER_CODES[weather_code]} {extrachar} {feels_like_f}°F"
|
||||||
|
|
||||||
return current_weather
|
return current_weather
|
||||||
|
|
||||||
def build_tooltip(current_condition, astronomy, moon_icon):
|
def build_tooltip(current_condition, astronomy, moon_icon):
|
||||||
|
"""build the tooltip text"""
|
||||||
weather_description = current_condition['weatherDesc'][0]['value']
|
weather_description = current_condition['weatherDesc'][0]['value']
|
||||||
feels_like_f = current_condition["FeelsLikeF"]
|
feels_like_f = current_condition["FeelsLikeF"]
|
||||||
temp_f = current_condition['temp_F']
|
temp_f = current_condition['temp_F']
|
||||||
humidity = current_condition['humidity']
|
humidity = current_condition['humidity']
|
||||||
wind_speed = current_condition['windspeedMiles']
|
wind_speed = current_condition['windspeedMiles']
|
||||||
wind_dir = current_condition['winddir16Point']
|
wind_dir = current_condition['winddir16Point']
|
||||||
moon_phase = astronomy.get('moon_phase', 'Unknown')
|
moon_phase = astronomy['moon_phase']
|
||||||
|
wego = WEATHER_CODES_WEGO[current_condition['weatherCode']]
|
||||||
weather_code = current_condition['weatherCode']
|
|
||||||
if weather_code not in WEATHER_CODES_WEGO:
|
|
||||||
weather_code = "113"
|
|
||||||
|
|
||||||
wego = WEATHER_CODES_WEGO[weather_code]
|
|
||||||
|
|
||||||
current = f"{wego[0]}{weather_description} {temp_f}°\n"
|
current = f"{wego[0]}{weather_description} {temp_f}°\n"
|
||||||
feels = f"{wego[1]}Feels like: {feels_like_f}°\n"
|
feels = f"{wego[1]}Feels like: {feels_like_f}°\n"
|
||||||
wind = f"{wego[2]}Wind: {wind_speed}mph {WIND_DIRECTION.get(wind_dir, ''\'')}\n" # Safe get for direction
|
wind = f"{wego[2]}Wind: {wind_speed}mph {WIND_DIRECTION[wind_dir]}\n"
|
||||||
humidityl = f"{wego[3]}Humidity: {humidity}%\n"
|
humidityl = f"{wego[3]}Humidity: {humidity}%\n"
|
||||||
moon = f"{wego[4]}Moon phase: {moon_phase} " + moon_icon + "\n"
|
moon = f"{wego[4]}Moon phase: {moon_phase} " + moon_icon + "\n"
|
||||||
|
|
||||||
tooltip = current + feels + wind + humidityl + moon
|
tooltip = current + feels + wind + humidityl + moon
|
||||||
|
|
||||||
return tooltip
|
return tooltip
|
||||||
|
|
||||||
def build_forecast(weather):
|
def build_forecast(weather):
|
||||||
|
"""build a 3 day forecast"""
|
||||||
tooltip = "\n"
|
tooltip = "\n"
|
||||||
|
|
||||||
for i, day in enumerate(weather):
|
for i, day in enumerate(weather):
|
||||||
|
# determine day
|
||||||
if i == 0:
|
if i == 0:
|
||||||
tooltip += "Today, "
|
tooltip += "Today, "
|
||||||
if i == 1:
|
if i == 1:
|
||||||
tooltip += "Tomorrow, "
|
tooltip += "Tomorrow, "
|
||||||
|
# format the date
|
||||||
date = datetime.strptime(day['date'], "%Y-%m-%d").strftime("%a %b %d %Y")
|
date = datetime.strptime(day['date'], "%Y-%m-%d").strftime("%a %b %d %Y")
|
||||||
tooltip += f"<b>{date}</b>\n"
|
tooltip += f"<b>{date}</b>\n"
|
||||||
|
# set the high and low
|
||||||
max_temp = day['maxtempF']
|
max_temp = day['maxtempF']
|
||||||
min_temp = day['mintempF']
|
min_temp = day['mintempF']
|
||||||
tooltip += f" {max_temp}°F {min_temp}°F"
|
tooltip += f" {max_temp}°F {min_temp}°F"
|
||||||
@@ -419,34 +377,29 @@ let
|
|||||||
tooltip += build_hourly_forecast(i, day['hourly'], sunrise, sunset)
|
tooltip += build_hourly_forecast(i, day['hourly'], sunrise, sunset)
|
||||||
return tooltip
|
return tooltip
|
||||||
|
|
||||||
def build_hourly_forecast(day_num, hourly, sunrise, sunset):
|
|
||||||
try:
|
|
||||||
sunrise_hour = datetime.strptime(sunrise, "%I:%M %p").hour
|
|
||||||
sunset_hour = datetime.strptime(sunset, "%I:%M %p").hour
|
|
||||||
except ValueError:
|
|
||||||
# Fallback if time format is different (OpenMeteo might send 24h)
|
|
||||||
sunrise_hour = int(sunrise.split(':')[0])
|
|
||||||
sunset_hour = int(sunset.split(':')[0])
|
|
||||||
|
|
||||||
|
def build_hourly_forecast(day_num, hourly, sunrise, sunset):
|
||||||
|
"""build an hourly forecast"""
|
||||||
|
sunrise_hour = datetime.strptime(sunrise, "%I:%M %p").hour
|
||||||
|
sunset_hour = datetime.strptime(sunset, "%I:%M %p").hour
|
||||||
current_hour = datetime.now().hour
|
current_hour = datetime.now().hour
|
||||||
tooltip = ""
|
tooltip = ""
|
||||||
|
|
||||||
for hour in hourly:
|
for hour in hourly:
|
||||||
time_24_hr = int(format_24_time(hour["time"]))
|
time_24_hr = int(format_24_time(hour["time"]))
|
||||||
|
|
||||||
if day_num == 0:
|
if day_num == 0:
|
||||||
if time_24_hr < current_hour - 2:
|
if time_24_hr < current_hour - 2:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# determine which code to use
|
||||||
if is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
|
if is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
|
||||||
codes = WEATHER_CODES_WI_NIGHT
|
codes = WEATHER_CODES_WI_NIGHT
|
||||||
else:
|
else:
|
||||||
codes = WEATHER_CODES_WI_DAY
|
codes = WEATHER_CODES_WI_DAY
|
||||||
|
|
||||||
current_time = format_time(hour['time'])
|
current_time = format_time(hour['time'])
|
||||||
wcode = hour['weatherCode']
|
current_weather_code = codes[hour['weatherCode']]
|
||||||
if wcode not in codes: wcode = "113" # Fallback
|
|
||||||
|
|
||||||
current_weather_code = codes[wcode]
|
|
||||||
feels_like = format_temp(hour['FeelsLikeF'])
|
feels_like = format_temp(hour['FeelsLikeF'])
|
||||||
weather_desc = hour['weatherDesc'][0]['value']
|
weather_desc = hour['weatherDesc'][0]['value']
|
||||||
current_chances = format_chances(hour)
|
current_chances = format_chances(hour)
|
||||||
@@ -457,188 +410,38 @@ let
|
|||||||
return tooltip
|
return tooltip
|
||||||
|
|
||||||
def is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
|
def is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
|
||||||
|
"""returns true if the hour is night"""
|
||||||
before_sunrise = time_24_hr < sunrise_hour
|
before_sunrise = time_24_hr < sunrise_hour
|
||||||
after_sunset = time_24_hr > sunset_hour
|
after_sunset = time_24_hr > sunset_hour
|
||||||
return after_sunset or before_sunrise
|
return after_sunset or before_sunrise
|
||||||
|
|
||||||
def load_cache(path, ttl):
|
def get_wttr_json():
|
||||||
try:
|
"""get the weather json"""
|
||||||
if not os.path.exists(path):
|
weather = requests.get("https://wttr.in/?u&format=j1", timeout=30).json()
|
||||||
return None
|
moon = requests.get("https://wttr.in/?format=%m", timeout=30)
|
||||||
mtime = datetime.fromtimestamp(os.path.getmtime(path))
|
moon_icon = moon.text
|
||||||
if datetime.now() - mtime > ttl:
|
|
||||||
return None
|
|
||||||
with open(path, "r") as f:
|
|
||||||
if path.endswith(".json"):
|
|
||||||
return json.load(f)
|
|
||||||
return f.read().strip()
|
|
||||||
except Exception:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def save_cache(path, data):
|
current_condition = weather["current_condition"][0]
|
||||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
astronomy = weather["weather"][0]['astronomy'][0]
|
||||||
tmp = path + ".tmp"
|
|
||||||
try:
|
|
||||||
with open(tmp, "w") as f:
|
|
||||||
if isinstance(data, dict):
|
|
||||||
json.dump(data, f)
|
|
||||||
else:
|
|
||||||
f.write(str(data))
|
|
||||||
shutil.move(tmp, path)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# --- OPEN-METEO INTEGRATION HELPER FUNCTIONS ---
|
text = build_text(current_condition)
|
||||||
|
|
||||||
def get_lat_lon():
|
tooltip = build_tooltip(current_condition, astronomy, moon_icon) + build_forecast(weather["weather"])
|
||||||
"""Attempt to get location via IP if using OpenMeteo"""
|
|
||||||
try:
|
|
||||||
resp = requests.get("http://ip-api.com/json/", timeout=5).json()
|
|
||||||
return resp.get('lat'), resp.get('lon')
|
|
||||||
except:
|
|
||||||
# Default to a generic location if IP fetch fails (NYC)
|
|
||||||
return 40.71, -74.00
|
|
||||||
|
|
||||||
def fetch_open_meteo():
|
data["text"] = text
|
||||||
"""Fetch and Transform OpenMeteo data to match Wttr.in JSON structure"""
|
data["tooltip"] = tooltip
|
||||||
lat, lon = get_lat_lon()
|
|
||||||
url = "https://api.open-meteo.com/v1/forecast"
|
|
||||||
params = {
|
|
||||||
"latitude": lat,
|
|
||||||
"longitude": lon,
|
|
||||||
"current": "temperature_2m,apparent_temperature,precipitation,weather_code,wind_speed_10m,wind_direction_10m,relative_humidity_2m",
|
|
||||||
"daily": "weather_code,temperature_2m_max,temperature_2m_min,sunrise,sunset,precipitation_probability_max",
|
|
||||||
"hourly": "temperature_2m,apparent_temperature,precipitation_probability,weather_code",
|
|
||||||
"temperature_unit": "fahrenheit",
|
|
||||||
"wind_speed_unit": "mph",
|
|
||||||
"precipitation_unit": "inch",
|
|
||||||
"timezone": "auto"
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(url, params=params, timeout=10)
|
|
||||||
om_data = response.json()
|
|
||||||
|
|
||||||
# Transform Current Condition
|
|
||||||
current = om_data["current"]
|
|
||||||
wmo_code = current["weather_code"]
|
|
||||||
wwo_code = WMO_TO_WWO.get(wmo_code, "113")
|
|
||||||
|
|
||||||
wttr_current = {
|
|
||||||
"temp_F": str(int(current["temperature_2m"])),
|
|
||||||
"FeelsLikeF": str(int(current["apparent_temperature"])),
|
|
||||||
"weatherCode": wwo_code,
|
|
||||||
"weatherDesc": [{"value": WWO_CODE.get(wwo_code, "Unknown")}],
|
|
||||||
"humidity": str(current["relative_humidity_2m"]),
|
|
||||||
"windspeedMiles": str(int(current["wind_speed_10m"])),
|
|
||||||
"winddir16Point": deg_to_compass(current["wind_direction_10m"]),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Transform Daily Forecast (OpenMeteo gives 7 days, we need 3)
|
|
||||||
wttr_weather = []
|
|
||||||
daily = om_data["daily"]
|
|
||||||
hourly = om_data["hourly"]
|
|
||||||
|
|
||||||
for i in range(3):
|
|
||||||
date_str = daily["time"][i]
|
|
||||||
|
|
||||||
# Build Hourly for this day (wttr uses 3-hour intervals: 0, 300, 600...)
|
|
||||||
# OpenMeteo gives 0, 1, 2...
|
|
||||||
wttr_hourly = []
|
|
||||||
for h in range(0, 24, 3): # Step by 3 hours to mimic wttr
|
|
||||||
idx = (i * 24) + h
|
|
||||||
h_code = hourly["weather_code"][idx]
|
|
||||||
h_wwo = WMO_TO_WWO.get(h_code, "113")
|
|
||||||
|
|
||||||
wttr_hourly.append({
|
|
||||||
"time": str(h * 100), # 0, 300, 600
|
|
||||||
"weatherCode": h_wwo,
|
|
||||||
"weatherDesc": [{"value": WWO_CODE.get(h_wwo, "Unknown")}],
|
|
||||||
"FeelsLikeF": str(int(hourly["apparent_temperature"][idx])),
|
|
||||||
"chanceofrain": str(hourly["precipitation_probability"][idx]),
|
|
||||||
# Fill other chances with 0 as API doesn't provide them easily
|
|
||||||
"chanceoffog": "0", "chanceofsnow": "0", "chanceofthunder": "0",
|
|
||||||
"chanceofwindy": "0", "chanceofsunshine": "0"
|
|
||||||
})
|
|
||||||
|
|
||||||
# Astronomy
|
return json.dumps(data)
|
||||||
sunrise = datetime.fromisoformat(daily["sunrise"][i]).strftime("%I:%M %p")
|
|
||||||
sunset = datetime.fromisoformat(daily["sunset"][i]).strftime("%I:%M %p")
|
|
||||||
|
|
||||||
wttr_weather.append({
|
|
||||||
"date": date_str,
|
|
||||||
"maxtempF": str(int(daily["temperature_2m_max"][i])),
|
|
||||||
"mintempF": str(int(daily["temperature_2m_min"][i])),
|
|
||||||
"astronomy": [{"sunrise": sunrise, "sunset": sunset, "moon_phase": "Unknown"}],
|
|
||||||
"hourly": wttr_hourly
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
"current_condition": [wttr_current],
|
|
||||||
"weather": wttr_weather
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_wttr_json(hyprlock=False):
|
|
||||||
# Try loading cached JSON
|
|
||||||
cached = load_cache(CACHE_FILE, CACHE_TTL)
|
|
||||||
cached_moon = load_cache(CACHE_MOON_FILE, CACHE_TTL)
|
|
||||||
cached_moon_icon = load_cache(CACHE_MOON_ICON_FILE, CACHE_TTL)
|
|
||||||
|
|
||||||
if cached and cached_moon and cached_moon_icon:
|
|
||||||
weather = cached
|
|
||||||
current_condition = weather["current_condition"][0]
|
|
||||||
astronomy = cached_moon
|
|
||||||
moon_icon = cached_moon_icon
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
# Primary Source: wttr.in
|
|
||||||
weather = requests.get("https://wttr.in/?u&format=j1", timeout=5).json()
|
|
||||||
moon = requests.get("https://wttr.in/?format=%m", timeout=5)
|
|
||||||
moon_icon = moon.text
|
|
||||||
|
|
||||||
current_condition = weather["current_condition"][0]
|
|
||||||
astronomy = weather["weather"][0]['astronomy'][0]
|
|
||||||
except Exception:
|
|
||||||
# Fallback Source: Open-Meteo
|
|
||||||
try:
|
|
||||||
print("open_mateo fallback")
|
|
||||||
weather = fetch_open_meteo()
|
|
||||||
current_condition = weather["current_condition"][0]
|
|
||||||
astronomy = weather["weather"][0]['astronomy'][0]
|
|
||||||
moon_icon = "" # Generic moon icon for fallback
|
|
||||||
except Exception as e:
|
|
||||||
# If both fail
|
|
||||||
raise e
|
|
||||||
|
|
||||||
# Save cache (works for both sources since we transformed OM data)
|
|
||||||
save_cache(CACHE_FILE, weather)
|
|
||||||
save_cache(CACHE_MOON_FILE, astronomy)
|
|
||||||
save_cache(CACHE_MOON_ICON_FILE, moon_icon)
|
|
||||||
|
|
||||||
if hyprlock:
|
|
||||||
return build_tooltip(current_condition, astronomy, moon_icon)
|
|
||||||
else:
|
|
||||||
text = build_text(current_condition)
|
|
||||||
tooltip = build_tooltip(current_condition, astronomy, moon_icon) + build_forecast(weather["weather"])
|
|
||||||
data["text"] = text
|
|
||||||
data["tooltip"] = tooltip
|
|
||||||
return json.dumps(data)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if args.hyprlock:
|
"""main"""
|
||||||
try:
|
try:
|
||||||
print(get_wttr_json(hyprlock=True))
|
print(get_wttr_json())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("error")
|
print("error")
|
||||||
# print(e) # Uncomment for debug
|
print(e)
|
||||||
else:
|
|
||||||
try:
|
|
||||||
print(get_wttr_json())
|
|
||||||
except Exception as e:
|
|
||||||
print(json.dumps({"text": "Err", "tooltip": str(e)}))
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
||||||
|
main()
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.wlogout;
|
cfg = config.mjallen.programs.wlogout;
|
||||||
palette = import cfg.theme.file;
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -53,13 +53,13 @@ in
|
|||||||
}
|
}
|
||||||
|
|
||||||
window {
|
window {
|
||||||
background-color: ${config.lib.stylix.colors.base00}f0
|
background-color: ${nord.polarNight.nord0}f0
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
color: ${config.lib.stylix.colors.base0C};
|
color: ${nord.frost.nord7};
|
||||||
background-color: ${config.lib.stylix.colors.base01};
|
background-color: ${nord.polarNight.nord1};
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
@@ -70,8 +70,8 @@ in
|
|||||||
button:active,
|
button:active,
|
||||||
button:focus,
|
button:focus,
|
||||||
button:hover {
|
button:hover {
|
||||||
color: ${config.lib.stylix.colors.base0C};
|
color: ${nord.frost.nord8};
|
||||||
background-color: ${config.lib.stylix.colors.base02Alt};
|
background-color: ${nord.polarNight.nord2};
|
||||||
outline-style: none;
|
outline-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,10 @@ with lib;
|
|||||||
{
|
{
|
||||||
options.mjallen.programs.wlogout = {
|
options.mjallen.programs.wlogout = {
|
||||||
enable = mkEnableOption "enable wlogout";
|
enable = mkEnableOption "enable wlogout";
|
||||||
|
|
||||||
|
fontName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Deja Vu Sans";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.programs.wofi;
|
cfg = config.mjallen.programs.wofi;
|
||||||
palette = import cfg.theme.file;
|
nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -20,9 +20,9 @@ in
|
|||||||
window {
|
window {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 0.16em solid ${config.lib.stylix.colors.base0E};
|
border: 0.16em solid ${nord.aurora.nord15};
|
||||||
border-radius: 0.1em;
|
border-radius: 0.1em;
|
||||||
background-color: ${config.lib.stylix.colors.base00};
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inner Box */
|
/* Inner Box */
|
||||||
@@ -30,7 +30,7 @@ in
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: ${config.lib.stylix.colors.base00};
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Outer Box */
|
/* Outer Box */
|
||||||
@@ -38,7 +38,7 @@ in
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: ${config.lib.stylix.colors.base00};
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scroll */
|
/* Scroll */
|
||||||
@@ -46,7 +46,7 @@ in
|
|||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: ${config.lib.stylix.colors.base00};
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input */
|
/* Input */
|
||||||
@@ -55,46 +55,46 @@ in
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0.1em;
|
border-radius: 0.1em;
|
||||||
color: ${config.lib.stylix.colors.base06};
|
color: ${nord.snowStorm.nord6};
|
||||||
background-color: ${config.lib.stylix.colors.base00};
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
}
|
||||||
|
|
||||||
#input image {
|
#input image {
|
||||||
border: none;
|
border: none;
|
||||||
color: ${config.lib.stylix.colors.base08};
|
color: ${nord.aurora.nord11};
|
||||||
}
|
}
|
||||||
|
|
||||||
#input * {
|
#input * {
|
||||||
outline: 4px solid ${config.lib.stylix.colors.base08}!important;
|
outline: 4px solid ${nord.aurora.nord11}!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text */
|
/* Text */
|
||||||
#text {
|
#text {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border: none;
|
border: none;
|
||||||
color: ${config.lib.stylix.colors.base06};
|
color: ${nord.snowStorm.nord6};
|
||||||
}
|
}
|
||||||
|
|
||||||
#entry {
|
#entry {
|
||||||
background-color: ${config.lib.stylix.colors.base00};
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
}
|
||||||
|
|
||||||
#entry arrow {
|
#entry arrow {
|
||||||
border: none;
|
border: none;
|
||||||
color: ${config.lib.stylix.colors.base0E};
|
color: ${nord.aurora.nord15};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Selected Entry */
|
/* Selected Entry */
|
||||||
#entry:selected {
|
#entry:selected {
|
||||||
border: 0.11em solid ${config.lib.stylix.colors.base0E};
|
border: 0.11em solid ${nord.aurora.nord15};
|
||||||
}
|
}
|
||||||
|
|
||||||
#entry:selected #text {
|
#entry:selected #text {
|
||||||
color: ${config.lib.stylix.colors.base0C};
|
color: ${nord.frost.nord7};
|
||||||
}
|
}
|
||||||
|
|
||||||
#entry:drop(active) {
|
#entry:drop(active) {
|
||||||
background-color: ${config.lib.stylix.colors.base0E}!important;
|
background-color: ${nord.aurora.nord15}!important;
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
#services.gnome-keyring.enable = false;
|
|
||||||
#home.packages = [ pkgs.gcr ];
|
|
||||||
|
|
||||||
services.pass-secret-service = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,29 +1,32 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.mjallen.sops;
|
cfg = config.mjallen.sops;
|
||||||
|
|
||||||
|
user = config.${namespace}.user.name;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# sops = {
|
sops = {
|
||||||
# age.keyFile = "/home/${user}/.config/sops/age/keys.txt";
|
age.keyFile = "/home/${user}/.config/sops/age/keys.txt";
|
||||||
# defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||||
# validateSopsFiles = false;
|
validateSopsFiles = false;
|
||||||
# secrets = {
|
secrets = {
|
||||||
# "ssh-keys-public/desktop-nixos" = {
|
"ssh-keys-public/desktop-nixos" = {
|
||||||
# path = "/home/${user}/.ssh/id_ed25519.pub";
|
path = "/home/${user}/.ssh/id_ed25519.pub";
|
||||||
# mode = "0644";
|
mode = "0644";
|
||||||
# };
|
};
|
||||||
# "ssh-keys-private/desktop-nixos" = {
|
"ssh-keys-private/desktop-nixos" = {
|
||||||
# path = "/home/${user}/.ssh/id_ed25519";
|
path = "/home/${user}/.ssh/id_ed25519";
|
||||||
# mode = "0600";
|
mode = "0600";
|
||||||
# };
|
};
|
||||||
# };
|
};
|
||||||
# };
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
# # Pull from global theme options
|
|
||||||
# themeSize = "standard"; # "standard" | "compact"
|
|
||||||
# themeAccent = "default"; # "default" | ... | "all"
|
|
||||||
# themeTweak = "normal"; # "normal" | "rimless" | "float" | "black"
|
|
||||||
# themeColor = "dark"; # "light" | "dark"
|
|
||||||
# iconThemeVariant = "default"; # "default" | ... | "all"
|
|
||||||
# iconScheme = "nord"; # "default" | "nord" | "dracula" | ...
|
|
||||||
|
|
||||||
# # GTK
|
|
||||||
# gtkTheme = "Colloid-dark-standard";
|
|
||||||
# gtkThemePkg = pkgs.colloid-gtk-theme.override {
|
|
||||||
# sizeVariants = [ themeSize ];
|
|
||||||
# colorVariants = [ themeColor ];
|
|
||||||
# themeVariants = [ themeAccent ];
|
|
||||||
# tweaks = [ themeTweak ];
|
|
||||||
# };
|
|
||||||
|
|
||||||
# # Icons
|
|
||||||
# iconTheme = "Colloid-nord-dark";
|
|
||||||
# iconThemePkg = pkgs.colloid-icon-theme.override {
|
|
||||||
# schemeVariants = [ iconScheme ];
|
|
||||||
# colorVariants = [ iconThemeVariant ];
|
|
||||||
# };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
stylix = {
|
|
||||||
enable = true;
|
|
||||||
enableReleaseChecks = false;
|
|
||||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/nord.yaml";
|
|
||||||
|
|
||||||
cursor = {
|
|
||||||
name = "macOS";
|
|
||||||
size = 24;
|
|
||||||
package = pkgs.apple-cursor;
|
|
||||||
};
|
|
||||||
|
|
||||||
fonts = {
|
|
||||||
serif = {
|
|
||||||
package = pkgs.dejavu_fonts;
|
|
||||||
name = "DejaVu Serif";
|
|
||||||
};
|
|
||||||
|
|
||||||
sansSerif = {
|
|
||||||
package = pkgs.dejavu_fonts;
|
|
||||||
name = "DejaVu Sans";
|
|
||||||
};
|
|
||||||
|
|
||||||
monospace = {
|
|
||||||
package = pkgs.nerd-fonts.jetbrains-mono;
|
|
||||||
name = "JetBrainsMono NFM";
|
|
||||||
};
|
|
||||||
|
|
||||||
emoji = {
|
|
||||||
package = pkgs.noto-fonts-color-emoji;
|
|
||||||
name = "Noto Color Emoji";
|
|
||||||
};
|
|
||||||
|
|
||||||
sizes = {
|
|
||||||
applications = 12;
|
|
||||||
desktop = 14;
|
|
||||||
popups = config.stylix.fonts.sizes.desktop;
|
|
||||||
terminal = config.stylix.fonts.sizes.applications;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
icons = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.colloid-icon-theme;
|
|
||||||
dark = "Colloid-nord-dark";
|
|
||||||
light = "Colloid-nord-light";
|
|
||||||
};
|
|
||||||
|
|
||||||
opacity = {
|
|
||||||
terminal = 0.85;
|
|
||||||
};
|
|
||||||
|
|
||||||
targets = {
|
|
||||||
hyprlock.enable = false;
|
|
||||||
gnome.enable = false;
|
|
||||||
# gtk.enable = false;
|
|
||||||
qt.enable = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
131
modules/nixos/actual/default.nix
Normal file
131
modules/nixos/actual/default.nix
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.services.actual;
|
||||||
|
dataDir = "/data";
|
||||||
|
hostAddress = "10.0.1.3";
|
||||||
|
actualUserId = config.users.users.nix-apps.uid;
|
||||||
|
actualGroupId = config.users.groups.jallen-nas.gid;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ./options.nix ];
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
containers.actual = {
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = true;
|
||||||
|
hostAddress = hostAddress;
|
||||||
|
localAddress = cfg.localAddress;
|
||||||
|
|
||||||
|
bindMounts = {
|
||||||
|
${dataDir} = {
|
||||||
|
hostPath = cfg.dataDir;
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
services.actual = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
settings = {
|
||||||
|
trustedProxies = [ hostAddress ];
|
||||||
|
port = cfg.port;
|
||||||
|
dataDir = dataDir;
|
||||||
|
serverFiles = "${dataDir}/server-files";
|
||||||
|
userFiles = "${dataDir}/user-files";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.actual = {
|
||||||
|
isSystemUser = true;
|
||||||
|
uid = lib.mkForce actualUserId;
|
||||||
|
group = "actual";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups = {
|
||||||
|
actual = {
|
||||||
|
gid = lib.mkForce actualGroupId;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# System packages
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
sqlite
|
||||||
|
];
|
||||||
|
|
||||||
|
# Create and set permissions for required directories
|
||||||
|
system.activationScripts.actual-dirs = ''
|
||||||
|
mkdir -p ${dataDir}
|
||||||
|
chown -R actual:actual ${dataDir}
|
||||||
|
chmod -R 0700 ${dataDir}
|
||||||
|
'';
|
||||||
|
|
||||||
|
systemd.services = {
|
||||||
|
actual = {
|
||||||
|
environment.ACTUAL_CONFIG_PATH = lib.mkForce "${dataDir}/config.json";
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = lib.mkForce "${pkgs.actual-server}/bin/actual-server --config ${dataDir}/config.json";
|
||||||
|
WorkingDirectory = lib.mkForce dataDir;
|
||||||
|
StateDirectory = lib.mkForce dataDir;
|
||||||
|
StateDirectoryMode = lib.mkForce 700;
|
||||||
|
DynamicUser = lib.mkForce false;
|
||||||
|
ProtectSystem = lib.mkForce null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowedTCPPorts = [ cfg.port ];
|
||||||
|
};
|
||||||
|
# Use systemd-resolved inside the container
|
||||||
|
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||||
|
useHostResolvConf = lib.mkForce false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.resolved.enable = true;
|
||||||
|
system.stateVersion = "23.11";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.traefik.dynamicConfigOptions = lib.mkIf cfg.reverseProxy.enable {
|
||||||
|
services.actual.loadBalancer.servers = [
|
||||||
|
{
|
||||||
|
url = "http://${cfg.localAddress}:${toString cfg.port}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
routers.actual = {
|
||||||
|
entryPoints = [ "websecure" ];
|
||||||
|
rule = "Host(`${cfg.reverseProxy.host}`)";
|
||||||
|
service = "actual";
|
||||||
|
middlewares = cfg.reverseProxy.middlewares;
|
||||||
|
tls.certResolver = "letsencrypt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
nat = {
|
||||||
|
forwardPorts = [
|
||||||
|
{
|
||||||
|
destination = "${cfg.localAddress}:${toString cfg.port}";
|
||||||
|
sourcePort = cfg.port;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
firewall = {
|
||||||
|
allowedTCPPorts = [ cfg.port ];
|
||||||
|
allowedUDPPorts = [ cfg.port ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
37
modules/nixos/actual/options.nix
Normal file
37
modules/nixos/actual/options.nix
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{ lib, namespace, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.${namespace}.services.actual = {
|
||||||
|
enable = mkEnableOption "actual service";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 80;
|
||||||
|
};
|
||||||
|
|
||||||
|
localAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
reverseProxy = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
middlewares = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
70
modules/nixos/amd/default.nix
Executable file
70
modules/nixos/amd/default.nix
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.share.hardware.amd;
|
||||||
|
pkgsVersion = pkgs; # .unstable;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ./options.nix ];
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
boot = {
|
||||||
|
kernelModules = [ "nct6775" ];
|
||||||
|
kernelParams = [ (if cfg.enable then "amdgpu.ppfeaturemask=0xffffffff" else null) ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure programs
|
||||||
|
programs.corectrl = {
|
||||||
|
enable = cfg.corectrl.enable;
|
||||||
|
package = pkgsVersion.corectrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure environment
|
||||||
|
environment = {
|
||||||
|
# Force radv
|
||||||
|
variables = {
|
||||||
|
AMD_VULKAN_ICD = "RADV";
|
||||||
|
STEAM_FORCE_DESKTOPUI_SCALING = "1.0";
|
||||||
|
GDK_SCALE = "1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure polkit
|
||||||
|
security.polkit = lib.mkIf cfg.corectrl.enablePolkit {
|
||||||
|
extraConfig = ''
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if ((action.id == "org.corectrl.helper.init" ||
|
||||||
|
action.id == "org.corectrl.helperkiller.init") &&
|
||||||
|
subject.local == true &&
|
||||||
|
subject.active == true &&
|
||||||
|
subject.isInGroup("${cfg.corectrl.polkitGroup}")) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# nixpkg is broken so need to manually define
|
||||||
|
systemd.services.lactd = lib.mkIf cfg.lact.enable {
|
||||||
|
description = "AMDGPU Control Daemon";
|
||||||
|
path = with pkgsVersion; [
|
||||||
|
bash
|
||||||
|
lact
|
||||||
|
];
|
||||||
|
script = ''
|
||||||
|
lact daemon
|
||||||
|
'';
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure environment
|
||||||
|
environment = {
|
||||||
|
systemPackages = with pkgsVersion; lib.mkIf cfg.lact.enable [ lact ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
27
modules/nixos/amd/options.nix
Executable file
27
modules/nixos/amd/options.nix
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.share.hardware.amd = {
|
||||||
|
enable = mkEnableOption "amd hardware config";
|
||||||
|
|
||||||
|
corectrl.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
corectrl.enablePolkit = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
corectrl.polkitGroup = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "wheel";
|
||||||
|
};
|
||||||
|
|
||||||
|
lact.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
# Enable AppImage
|
# Enable AppImage
|
||||||
binfmt.registrations.appimage = {
|
binfmt.registrations.appimage = {
|
||||||
wrapInterpreterInShell = lib.mkDefault false;
|
wrapInterpreterInShell = lib.mkDefault false;
|
||||||
interpreter = "${lib.getExe pkgs.appimage-run}/bin/appimage-run";
|
interpreter = "${pkgs.appimage-run}/bin/appimage-run";
|
||||||
recognitionType = "magic";
|
recognitionType = "magic";
|
||||||
offset = 0;
|
offset = 0;
|
||||||
mask = "\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\xff\\xff\\xff";
|
mask = "\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\xff\\xff\\xff";
|
||||||
@@ -170,10 +170,6 @@ in
|
|||||||
|
|
||||||
# Bind mount directories from host
|
# Bind mount directories from host
|
||||||
bindMounts = {
|
bindMounts = {
|
||||||
"/etc/resolv.conf" = {
|
|
||||||
hostPath = "/etc/resolv.conf";
|
|
||||||
isReadOnly = true;
|
|
||||||
};
|
|
||||||
"${radarrDataDir}" = {
|
"${radarrDataDir}" = {
|
||||||
hostPath = cfg.radarr.dataDir;
|
hostPath = cfg.radarr.dataDir;
|
||||||
isReadOnly = false;
|
isReadOnly = false;
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
system,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) mkOpt mkBoolOpt;
|
|
||||||
cfg = config.${namespace}.boot.common;
|
|
||||||
isArm = ("aarch64-linux" == system) || ("aarch64-darwin" == system);
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.boot.common = {
|
|
||||||
enable = mkBoolOpt true "Enable common boot stuff";
|
|
||||||
|
|
||||||
yubikeyEncryption = mkBoolOpt false "Enable Yubikey root encryption";
|
|
||||||
|
|
||||||
yubikeyGracePeriod = mkOpt types.int 180 "Time to wait for yubikey in seconds";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
boot = {
|
|
||||||
|
|
||||||
binfmt = lib.mkIf isArm {
|
|
||||||
registrations."x86_64-linux" = {
|
|
||||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00'';
|
|
||||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
|
||||||
openBinary = true;
|
|
||||||
interpreter = "${lib.getExe pkgs.box64}";
|
|
||||||
preserveArgvZero = true;
|
|
||||||
matchCredentials = true;
|
|
||||||
fixBinary = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
supportedFilesystems = [ "bcachefs" ];
|
|
||||||
|
|
||||||
consoleLogLevel = lib.mkForce 3;
|
|
||||||
bootspec.enable = (!isArm);
|
|
||||||
|
|
||||||
initrd = {
|
|
||||||
luks = mkIf cfg.yubikeyEncryption {
|
|
||||||
devices = {
|
|
||||||
"${config.disko.devices.disk.main.content.partitions.root.name}" = {
|
|
||||||
yubikey = {
|
|
||||||
storage = {
|
|
||||||
device = "/dev/disk/by-label/${config.disko.devices.disk.main.content.partitions.root.name}";
|
|
||||||
fsType = config.${namespace}.hardware.disko.filesystem;
|
|
||||||
path = "/";
|
|
||||||
};
|
|
||||||
slot = 2;
|
|
||||||
twoFactor = false;
|
|
||||||
gracePeriod = yubikeyGracePeriod;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
zramSwap.enable = lib.mkDefault true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
32
modules/nixos/boot/default.nix
Normal file
32
modules/nixos/boot/default.nix
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
system,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
isArm = ("aarch64-linux" == system);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
boot = {
|
||||||
|
kernelParams = [
|
||||||
|
"quiet"
|
||||||
|
];
|
||||||
|
|
||||||
|
binfmt = lib.mkIf isArm {
|
||||||
|
registrations."x86_64-linux" = {
|
||||||
|
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00'';
|
||||||
|
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||||
|
openBinary = true;
|
||||||
|
interpreter = "${pkgs.box64}/bin/box64";
|
||||||
|
preserveArgvZero = true;
|
||||||
|
matchCredentials = true;
|
||||||
|
fixBinary = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
supportedFilesystems = [ "bcachefs" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
zramSwap.enable = true;
|
||||||
|
}
|
||||||
@@ -7,31 +7,17 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.${namespace}.bootloader.lanzaboote;
|
cfg = config.${namespace}.bootloader.lanzaboote;
|
||||||
inherit (lib.${namespace}) mkOpt;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.bootloader.lanzaboote = {
|
imports = [ ./options.nix ];
|
||||||
enable = mkEnableOption "enable lanzaboote";
|
|
||||||
|
|
||||||
configLimit = mkOpt types.int 10 "Number of boot items to keep";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
boot = {
|
boot.lanzaboote = {
|
||||||
loader = {
|
enable = cfg.enable;
|
||||||
efi = {
|
pkiBundle = "/etc/secureboot";
|
||||||
canTouchEfiVariables = true;
|
settings = {
|
||||||
efiSysMountPoint = "/boot";
|
console-mode = "max";
|
||||||
};
|
|
||||||
};
|
|
||||||
lanzaboote = {
|
|
||||||
enable = cfg.enable;
|
|
||||||
pkiBundle = "/etc/secureboot";
|
|
||||||
settings = {
|
|
||||||
console-mode = "max";
|
|
||||||
};
|
|
||||||
configurationLimit = cfg.configLimit;
|
|
||||||
};
|
};
|
||||||
|
configurationLimit = cfg.configLimit;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
12
modules/nixos/boot/lanzaboote/options.nix
Normal file
12
modules/nixos/boot/lanzaboote/options.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{ lib, namespace, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.${namespace}.bootloader.lanzaboote = {
|
||||||
|
enable = mkEnableOption "enable lanzaboote";
|
||||||
|
|
||||||
|
configLimit = mkOption {
|
||||||
|
type = with types; int;
|
||||||
|
default = 10;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{ lib, ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
boot.plymouth = {
|
boot.plymouth = {
|
||||||
enable = lib.mkDefault true;
|
enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}) mkOpt;
|
|
||||||
cfg = config.${namespace}.boot.systemd-boot;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.${namespace}.boot.systemd-boot = {
|
|
||||||
enable = mkEnableOption "enable systemd-boot";
|
|
||||||
|
|
||||||
configLimit = mkOpt types.int 10 "Number of boot items to keep";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
boot = {
|
|
||||||
loader = {
|
|
||||||
systemd-boot = {
|
|
||||||
enable = mkDefault true;
|
|
||||||
configurationLimit = cfg.configLimit;
|
|
||||||
};
|
|
||||||
|
|
||||||
efi = {
|
|
||||||
canTouchEfiVariables = mkDefault true;
|
|
||||||
efiSysMountPoint = "/boot";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
68
modules/nixos/crowdsec/default.nix
Executable file
68
modules/nixos/crowdsec/default.nix
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.services.crowdsec;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ./options.nix ];
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services = {
|
||||||
|
crowdsec =
|
||||||
|
let
|
||||||
|
yaml = (pkgs.formats.yaml { }).generate;
|
||||||
|
acquisitions_file = yaml "acquisitions.yaml" {
|
||||||
|
source = "journalctl";
|
||||||
|
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
|
||||||
|
labels.type = "syslog";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
enrollKeyFile = "${cfg.dataDir}/enroll.key";
|
||||||
|
settings = {
|
||||||
|
crowdsec_service.acquisition_path = acquisitions_file;
|
||||||
|
api.server = {
|
||||||
|
listen_uri = "0.0.0.0:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
crowdsec-firewall-bouncer = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
api_key = cfg.apiKey;
|
||||||
|
api_url = "http://${cfg.apiAddress}:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.crowdsec.serviceConfig = {
|
||||||
|
ExecStartPre =
|
||||||
|
let
|
||||||
|
script = pkgs.writeScriptBin "register-bouncer" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
if ! cscli bouncers list | grep -q "nas-bouncer"; then
|
||||||
|
cscli bouncers add "nas-bouncer" --key "${cfg.apiKey}"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
[ "${script}/bin/register-bouncer" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
firewall = {
|
||||||
|
allowedTCPPorts = [ cfg.port ];
|
||||||
|
allowedUDPPorts = [ cfg.port ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user