Compare commits
17 Commits
5d70868e4f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b8fa60540 | |||
| 86dc80eb3c | |||
| f1bd5146a3 | |||
| 6f35d60aab | |||
| 3d2e74d115 | |||
| 548a438f6a | |||
| 0939766e3a | |||
| f424ab98c7 | |||
| 15a4d8d5e8 | |||
| 5f7e9cada5 | |||
| c4a0eb0a98 | |||
| 103a485bf8 | |||
| 13f35677be | |||
| 579a120326 | |||
| c90d368432 | |||
| a787840ce2 | |||
| e2fd47aa58 |
+14
-4
@@ -17,16 +17,26 @@ How to work on it: [conventions.md](./conventions.md).
|
|||||||
|
|
||||||
Each machine: `modules/hosts/<name>/default.nix` → `nixosConfigurations.<name>`, real config in `*Configuration` + optional `_private/` and `_services/`.
|
Each machine: `modules/hosts/<name>/default.nix` → `nixosConfigurations.<name>`, real config in `*Configuration` + optional `_private/` and `_services/`.
|
||||||
|
|
||||||
|
## Features at a glance
|
||||||
|
|
||||||
|
- **Users catalog** — one catalog in `modules/system/users.nix`, pick who exists on a host with `chiasson.users.enabled = [ "example" ]`, override per host. Home Manager wires itself from the same list.
|
||||||
|
- **SSH + Bitwarden (rbw) keys** — one ed25519 keypair per catalog user, private key in Bitwarden, public key in `modules/ssh/inventory.nix`. Outbound SSH uses a `.pub` filter against the rbw agent; inbound `authorized_keys` are generated from the same inventory. [Full wiring in conventions.md](./conventions.md#ssh-model).
|
||||||
|
- **Wisdom modules** — Home Manager slices in `modules/wisdom/` auto-catalog via `lib.wisdomCatalogExtraModules` (defined in `modules/desktop/options.nix`). The baseline `wisdom` module handles git identity + shared tools; all other `wisdom*` exports are pulled in once per user through `desktopHomeBase` → `chiasson.users.extraModules.olivier`. Hosts only flip `chiasson.home.<category>.<slice>.enable` — no manual imports in `home.nix`. Categories include `apps` (spotify, discord, localsend), `browsers` (chrome, edge, zen, …), `editors` (cursor, vscode, obsidian, …), `shells` (bash, fish, oh-my-posh, yazi), `desktop` (gtk-qt-theming, screenshot), and `terminals` (kitty). Trivial single-package slices can be written with the `lib.wisdomSlice` helper instead of repeating the `root`/`cfg` + `mkIf` boilerplate.
|
||||||
|
- **Wallpapers from a dedicated repo** — `modules/desktop/wallpapers.nix` pins `inputs.wallpapers` into the store and exposes it as `CHIASSON_NIX_WALLPAPERS` and `/etc/wallpapers`. Override `chiasson.desktop.wallpapers.source` if needed.
|
||||||
|
- **Private host data** — import-tree skips `_private/` globally, so machine-only files (firmware quirks, display configs, service tweaks) live next to the host module without leaking elsewhere.
|
||||||
|
|
||||||
## Deploy / rebuild
|
## Deploy / rebuild
|
||||||
|
|
||||||
Remote builds use the `builder` user (`systemDeployBuilder`, wired through `client-services` on desktops).
|
Remote builds use the `builder` user (`systemDeployBuilder`, wired through `client-services` on desktops/laptops/tablets).
|
||||||
|
|
||||||
Fleet deploy is [Navi](https://github.com/cafkafk/navi) — config in `modules/deploy/navi.nix`, outputs `flake.navi` / `flake.naviHive`.
|
Fleet deploy is [Navi](https://github.com/cafkafk/navi) — config in `modules/deploy/navi.nix`, outputs `flake.navi` / `flake.naviHive`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix develop # devShell has navi + hints
|
nix develop # devShell has navi + just + hints
|
||||||
|
just # list local helpers like `sync-dms`
|
||||||
navi apply --on <host>
|
navi apply --on <host>
|
||||||
navi apply-local --node 14900k --sudo # this machine, if hostname matches
|
navi apply-local --node 14900k --sudo # this machine, if hostname matches
|
||||||
|
navi tui # interactive fleet dashboard
|
||||||
```
|
```
|
||||||
|
|
||||||
Plain rebuild still works: `sudo nixos-rebuild switch --flake .#<host>`.
|
Plain rebuild still works: `sudo nixos-rebuild switch --flake .#<host>`.
|
||||||
@@ -37,11 +47,11 @@ Plain rebuild still works: `sudo nixos-rebuild switch --flake .#<host>`.
|
|||||||
modules/
|
modules/
|
||||||
hosts/<host>/ # per-machine composition
|
hosts/<host>/ # per-machine composition
|
||||||
system/ # nixosModules.system aggregate
|
system/ # nixosModules.system aggregate
|
||||||
desktop/ # GUI stack
|
desktop/ # GUI stack (niri, hyprland, plasma, DMS)
|
||||||
wisdom/ # HM modules (exports still named wisdom*)
|
wisdom/ # HM modules (exports still named wisdom*)
|
||||||
ssh/ # inbound NixOS + outbound HM
|
ssh/ # inbound NixOS + outbound HM
|
||||||
deploy/ # navi hive
|
deploy/ # navi hive
|
||||||
lib/ # pure helpers → flake.lib
|
patches/ # one-off patches (yt-dlp, t2fanrd, …)
|
||||||
```
|
```
|
||||||
|
|
||||||
Machine-only stuff lives in `hosts/<host>/_private/` — import-tree skips `_private/` globally, so those files only get pulled in where you import them.
|
Machine-only stuff lives in `hosts/<host>/_private/` — import-tree skips `_private/` globally, so those files only get pulled in where you import them.
|
||||||
|
|||||||
+8
-6
@@ -47,7 +47,7 @@ Leave upstream `services.*`, `networking.*`, `home.*`, etc. alone.
|
|||||||
|
|
||||||
Aggregates: `nixosModules.system` and `nixosModules.desktop` import their leaves. Host configs import those stacks and set options — they shouldn't reimplement whole subsystems.
|
Aggregates: `nixosModules.system` and `nixosModules.desktop` import their leaves. Host configs import those stacks and set options — they shouldn't reimplement whole subsystems.
|
||||||
|
|
||||||
**Home** — files under `modules/wisdom/`. Baseline is `homeManagerModules.wisdom` (`chiasson.home.enable`, wired via `chiasson.desktop.homeManager.bundleWisdom`). Other `wisdom*` slices auto-wire once per user via `lib.wisdomCatalogExtraModules self` (`modules/lib/wisdom-catalog.nix`); hosts only set matching `chiasson.home.*.enable` toggles — no re-import in `home.nix`.
|
**Home** — files under `modules/wisdom/`. Baseline is `homeManagerModules.wisdom` (`chiasson.home.enable`, wired via `chiasson.desktop.homeManager.bundleWisdom`). Other `wisdom*` slices auto-wire once per user via `lib.wisdomCatalogExtraModules self` (`modules/desktop/options.nix`); hosts only set matching `chiasson.home.*.enable` toggles — no re-import in `home.nix`.
|
||||||
|
|
||||||
User apps / dotfiles → wisdom. Daemons, firewall, kernel → NixOS. Sometimes both (LocalSend: HM installs, `systemLocalsend` opens the firewall).
|
User apps / dotfiles → wisdom. Daemons, firewall, kernel → NixOS. Sometimes both (LocalSend: HM installs, `systemLocalsend` opens the firewall).
|
||||||
|
|
||||||
@@ -76,9 +76,9 @@ SSH authentication has two independent sides:
|
|||||||
| **Client** (connecting from) | identity private keys | "Here's proof I own key K" |
|
| **Client** (connecting from) | identity private keys | "Here's proof I own key K" |
|
||||||
| **Server** (connecting to) | `authorized_keys` | "Do I trust key K?" |
|
| **Server** (connecting to) | `authorized_keys` | "Do I trust key K?" |
|
||||||
|
|
||||||
A key is just a cryptographic identity — it's not bound to a host or a machine account name. The model is **one key per user account**: each catalog account (`olivier`, `server`, `builder`) has its own keypair in `modules/lib/ssh-inventory.nix`, regardless of which machine that account runs on. Concretely: when `olivier@14900k` sshes to `server@r5500`, OpenSSH routes via a `Match user server` block (generated from `chiasson.ssh.outbound.rbw.extraIdentities`) → `IdentityFile ~/.ssh/id_ed25519_server.pub` (written from `users.server.publicKey`) to ask the rbw agent for the `server` private key; r5500's `server` `authorized_keys` holds the matching server pubkey. olivier's catalog default sets `extraIdentities = [ "server" "builder" ]` so `ssh <account>@<host>` Just Works for every catalog role. We also support `from="ip,cidr"` constraints per account to scope which source IPs may authenticate as it.
|
A key is just a cryptographic identity — it's not bound to a host or a machine account name. The model is **one key per user account**: each catalog account (`olivier`, `server`, `builder`) has its own keypair in `modules/ssh/inventory.nix`, regardless of which machine that account runs on. Concretely: when `olivier@14900k` sshes to `server@r5500`, OpenSSH routes via a `Match user server` block (generated from `chiasson.ssh.outbound.rbw.extraIdentities`) → `IdentityFile ~/.ssh/id_ed25519_server.pub` (written from `users.server.publicKey`) to ask the rbw agent for the `server` private key; r5500's `server` `authorized_keys` holds the matching server pubkey. olivier's catalog default sets `extraIdentities = [ "server" "builder" ]` so `ssh <account>@<host>` Just Works for every catalog role. We also support `from="ip,cidr"` constraints per account to scope which source IPs may authenticate as it.
|
||||||
|
|
||||||
This repo enforces "one key per user": every user has one ed25519 keypair, the private key in Bitwarden, the public key inline in `modules/lib/ssh-inventory.nix`. On SSH connect:
|
This repo enforces "one key per user": every user has one ed25519 keypair, the private key in Bitwarden, the public key inline in `modules/ssh/inventory.nix`. On SSH connect:
|
||||||
|
|
||||||
1. `~/.ssh/config` (managed by home-manager) sets `IdentityAgent SSH_AUTH_SOCK` and `IdentityFile ~/.ssh/id_ed25519_<user>.pub` for every host block.
|
1. `~/.ssh/config` (managed by home-manager) sets `IdentityAgent SSH_AUTH_SOCK` and `IdentityFile ~/.ssh/id_ed25519_<user>.pub` for every host block.
|
||||||
2. OpenSSH reads the `.pub` file as a **filter** against the agent (OpenSSH 7.3+ trick — `.pub` as IdentityFile tells the agent "give me the private key matching this pub"), so even with multiple keys loaded, only the matching one is tried. This is why the old "too many auth failures" symptom is gone by construction.
|
2. OpenSSH reads the `.pub` file as a **filter** against the agent (OpenSSH 7.3+ trick — `.pub` as IdentityFile tells the agent "give me the private key matching this pub"), so even with multiple keys loaded, only the matching one is tried. This is why the old "too many auth failures" symptom is gone by construction.
|
||||||
@@ -105,7 +105,7 @@ ssh root@nix-server nixos-rebuild switch --flake .#nix-server
|
|||||||
|
|
||||||
### Adding a host
|
### Adding a host
|
||||||
|
|
||||||
Edit `modules/lib/ssh-inventory.nix` and add:
|
Edit `modules/ssh/inventory.nix` and add:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
hosts."newhost" = {
|
hosts."newhost" = {
|
||||||
@@ -119,7 +119,7 @@ Then add `self.nixosModules.<host>Configuration` to `modules/deploy/navi.nix`.
|
|||||||
### Adding a catalog user
|
### Adding a catalog user
|
||||||
|
|
||||||
1. Generate a keypair: `rbw gen ssh-key <name>`.
|
1. Generate a keypair: `rbw gen ssh-key <name>`.
|
||||||
2. Add a `users.<name> = { publicKey = "ssh-ed25519 …"; };` line under `users` in `modules/lib/ssh-inventory.nix`.
|
2. Add a `users.<name> = { publicKey = "ssh-ed25519 …"; };` line under `users` in `modules/ssh/inventory.nix`.
|
||||||
3. Add a `<name> = { isNormalUser = true; … ssh.inbound.enable = true; ssh.inbound.authorizedHosts = "all"; }` entry under `chiasson.users.catalog` in `modules/system/users.nix`.
|
3. Add a `<name> = { isNormalUser = true; … ssh.inbound.enable = true; ssh.inbound.authorizedHosts = "all"; }` entry under `chiasson.users.catalog` in `modules/system/users.nix`.
|
||||||
4. Enable on every host that needs that user, e.g.:
|
4. Enable on every host that needs that user, e.g.:
|
||||||
|
|
||||||
@@ -172,7 +172,9 @@ The integration block at the bottom of `modules/system/users.nix` turns the cata
|
|||||||
|
|
||||||
**New NixOS leaf:** export `flake.nixosModules.whatever`, wire from `system/default.nix` or `desktop/default.nix` if it's global, or only from a host `configuration.nix` if it's not. `nix flake check`. Git-add new paths if eval uses the git tree.
|
**New NixOS leaf:** export `flake.nixosModules.whatever`, wire from `system/default.nix` or `desktop/default.nix` if it's global, or only from a host `configuration.nix` if it's not. `nix flake check`. Git-add new paths if eval uses the git tree.
|
||||||
|
|
||||||
**New HM slice:** add `modules/wisdom/.../foo.nix` exporting `flake.homeManagerModules.wisdomFoo` (import-tree picks it up; `wisdomCatalogExtraModules` includes every `wisdom*` export except `wisdom` / `wisdomShellBash`). Gate packages on `chiasson.home.*.enable`, set `mkDefault true` in `desktop-home-base.nix` if shared, or `enable = true` in a host `home.nix`. Upstream HM deps stay imported unconditionally — use `mkIf` on `cfg.enable` for config (never `config`-dependent `imports`; that recurses).
|
**New HM slice:** add `modules/wisdom/.../foo.nix` exporting `flake.homeManagerModules.wisdomFoo` (import-tree picks it up; `wisdomCatalogExtraModules` includes every `wisdom*` export). Every `wisdom*` slice auto-catalogs — including the bash shell — so the root module no longer manually `imports` it. Gate packages on `chiasson.home.*.enable`, and set the slice's own `enable` default with `mkEnableOption "…" // { default = true/false }` in that same module — defaults live with the option that owns them, not in a shared defaults file. Hosts flip toggles in `home.nix`. Upstream HM deps stay imported unconditionally — use `mkIf` on `cfg.enable` for config (never `config`-dependent `imports`; that recurses).
|
||||||
|
|
||||||
|
**Trivial single-package slice:** use `self.lib.wisdomSlice { path = "a.b"; default = true/false; description = "…"; packages = pkgs: [ … ]; }` instead of the `root`/`cfg` + `mkIf (root.enable && cfg.enable)` boilerplate. `packages` is a `pkgs -> [ drv ]` function responsible for its own `availableOn`/platform gating. Several such slices may share one `simple.nix` in their category dir (each still exporting its own `wisdom*` module), rather than one file per slice.
|
||||||
|
|
||||||
**Derivations:** `let` inside a fragment, or `flake.packages` / `flake.lib` — not a bare `mkDerivation` file import-tree will try to load.
|
**Derivations:** `let` inside a fragment, or `flake.packages` / `flake.lib` — not a bare `mkDerivation` file import-tree will try to load.
|
||||||
|
|
||||||
|
|||||||
+32
-1
@@ -98,9 +98,40 @@ let
|
|||||||
metaNixpkgs = import inputs.nixpkgs {
|
metaNixpkgs = import inputs.nixpkgs {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
};
|
};
|
||||||
|
# Build a raw Navi hive attrset from host specs + deployment targets.
|
||||||
|
# `inputs.navi.lib.makeHive` turns the result into `flake.naviHive`.
|
||||||
|
mkNaviHiveConfig =
|
||||||
|
{
|
||||||
|
metaNixpkgs,
|
||||||
|
hostSpecs,
|
||||||
|
deployments,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
deployNodes = lib.filterAttrs (name: _: deployments ? ${name}) hostSpecs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.navi = self.lib.mkNaviHiveConfig {
|
meta = {
|
||||||
|
nixpkgs = metaNixpkgs;
|
||||||
|
nodeNixpkgs = lib.mapAttrs (
|
||||||
|
name: spec:
|
||||||
|
import inputs.nixpkgs {
|
||||||
|
system = spec.system;
|
||||||
|
}
|
||||||
|
) deployNodes;
|
||||||
|
nodeSpecialArgs = lib.mapAttrs (_: spec: spec.specialArgs) deployNodes;
|
||||||
|
allowApplyAll = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// lib.mapAttrs (
|
||||||
|
name: spec:
|
||||||
|
{
|
||||||
|
imports = spec.modules or [ spec.configuration ];
|
||||||
|
deployment = deployments.${name};
|
||||||
|
}
|
||||||
|
) deployNodes;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
flake.navi = mkNaviHiveConfig {
|
||||||
inherit metaNixpkgs hostSpecs deployments;
|
inherit metaNixpkgs hostSpecs deployments;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+53
-12
@@ -1,4 +1,38 @@
|
|||||||
{ ... }: {
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
flake.lib.wisdomCatalogExtraModules =
|
||||||
|
self:
|
||||||
|
let
|
||||||
|
names = lib.sort builtins.lessThan (
|
||||||
|
lib.filter (n: lib.hasPrefix "wisdom" n && n != "wisdom") (
|
||||||
|
builtins.attrNames self.homeManagerModules
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
map (name: self.homeManagerModules.${name}) names;
|
||||||
|
|
||||||
|
flake.lib.wisdomSlice =
|
||||||
|
{ path, default, description, packages }:
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
segs = lib.splitString "." path;
|
||||||
|
optPath = [
|
||||||
|
"chiasson"
|
||||||
|
"home"
|
||||||
|
]
|
||||||
|
++ segs
|
||||||
|
++ [ "enable" ];
|
||||||
|
root = config.chiasson.home;
|
||||||
|
cfg = lib.getAttrFromPath segs root;
|
||||||
|
enabled = lib.getAttrFromPath optPath config;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = lib.setAttrByPath optPath (lib.mkEnableOption description // { inherit default; });
|
||||||
|
config = lib.mkIf (root.enable && enabled) {
|
||||||
|
home.packages = lib.filter (lib.meta.availableOn pkgs.stdenv.hostPlatform) (packages pkgs);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
flake.nixosModules.desktopOptions =
|
flake.nixosModules.desktopOptions =
|
||||||
{ config, options, lib, pkgs, self, inputs, ... }:
|
{ config, options, lib, pkgs, self, inputs, ... }:
|
||||||
let
|
let
|
||||||
@@ -34,11 +68,13 @@
|
|||||||
{
|
{
|
||||||
options.chiasson.desktop = {
|
options.chiasson.desktop = {
|
||||||
defaultSession = lib.mkOption {
|
defaultSession = lib.mkOption {
|
||||||
type = lib.types.nullOr (lib.types.enum [
|
type = lib.types.nullOr (
|
||||||
|
lib.types.enum [
|
||||||
"hyprland"
|
"hyprland"
|
||||||
"niri"
|
"niri"
|
||||||
"plasma"
|
"plasma"
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
default = null;
|
default = null;
|
||||||
example = "niri";
|
example = "niri";
|
||||||
description = ''
|
description = ''
|
||||||
@@ -56,10 +92,12 @@
|
|||||||
|
|
||||||
displayManager = {
|
displayManager = {
|
||||||
variant = lib.mkOption {
|
variant = lib.mkOption {
|
||||||
type = lib.types.nullOr (lib.types.enum [
|
type = lib.types.nullOr (
|
||||||
|
lib.types.enum [
|
||||||
"sddm"
|
"sddm"
|
||||||
"dankgreeter"
|
"dankgreeter"
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
SDDM vs DankGreeter (greetd + DMS — [docs](https://danklinux.com/docs/dankgreeter/nixos-flake)).
|
SDDM vs DankGreeter (greetd + DMS — [docs](https://danklinux.com/docs/dankgreeter/nixos-flake)).
|
||||||
@@ -80,9 +118,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
displayManager.sddm = {
|
displayManager.sddm = {
|
||||||
wayland.enable = lib.mkEnableOption ''
|
wayland.enable =
|
||||||
|
lib.mkEnableOption ''
|
||||||
SDDM greeter on Wayland (nicer on HiDPI; turn off if the greeter glitches on your GPU).
|
SDDM greeter on Wayland (nicer on HiDPI; turn off if the greeter glitches on your GPU).
|
||||||
'' // {
|
''
|
||||||
|
// {
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,10 +199,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
keyring = {
|
keyring = {
|
||||||
enable = lib.mkEnableOption ''
|
enable =
|
||||||
|
lib.mkEnableOption ''
|
||||||
gnome-keyring + pam (login + sddm or greetd) + HM user service + `gcr` + `services.xserver.updateDbusEnvironment`.
|
gnome-keyring + pam (login + sddm or greetd) + HM user service + `gcr` + `services.xserver.updateDbusEnvironment`.
|
||||||
niri/hyprland: `dbus-update-activation-environment` at compositor start so libsecret/Electron see `WAYLAND_DISPLAY`.
|
niri/hyprland: `dbus-update-activation-environment` at compositor start so libsecret/Electron see `WAYLAND_DISPLAY`.
|
||||||
'' // {
|
''
|
||||||
|
// {
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -184,8 +226,7 @@
|
|||||||
message = "chiasson.desktop.defaultSession = \"plasma\" requires chiasson.desktop.plasma.enable = true.";
|
message = "chiasson.desktop.defaultSession = \"plasma\" requires chiasson.desktop.plasma.enable = true.";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion =
|
assertion = cfg.displayManager.variant != "dankgreeter" || cfg.hyprland.enable || cfg.niri.enable;
|
||||||
cfg.displayManager.variant != "dankgreeter" || cfg.hyprland.enable || cfg.niri.enable;
|
|
||||||
message = "chiasson.desktop.displayManager.variant = \"dankgreeter\" requires chiasson.desktop.hyprland or chiasson.desktop.niri.";
|
message = "chiasson.desktop.displayManager.variant = \"dankgreeter\" requires chiasson.desktop.hyprland or chiasson.desktop.niri.";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -210,7 +251,7 @@
|
|||||||
(lib.mkIf (dmsEnabled && hmAvailable) {
|
(lib.mkIf (dmsEnabled && hmAvailable) {
|
||||||
"home-manager".sharedModules = [ self.homeManagerModules.desktopShellDms ];
|
"home-manager".sharedModules = [ self.homeManagerModules.desktopShellDms ];
|
||||||
})
|
})
|
||||||
(lib.mkIf (hmAvailable && (dmsEnabled || cfg.niri.enable)) {
|
(lib.mkIf hmAvailable {
|
||||||
"home-manager".extraSpecialArgs = { inherit inputs; };
|
"home-manager".extraSpecialArgs = { inherit inputs; };
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,25 +1,15 @@
|
|||||||
# Monitor layout for 14900k.
|
# Monitor layout for 14900k.
|
||||||
# NVIDIA (default): DP-3 ultrawide, HDMI-A-3 + DP-4 side/top stack; DP-2 virtual 4K when streamingDisplay enabled.
|
# NVIDIA (default): DP-3 ultrawide, HDMI-A-3 + DP-4 stack; DP-2 virtual 4K when streamingDisplay is on.
|
||||||
# Intel iGPU (gpu passthru): DP-1 ultrawide, HDMI-A-2 Samsung to the left.
|
# Intel iGPU (gpu passthru): DP-1 ultrawide, HDMI-A-2 to the left.
|
||||||
# Niri: `extraSettings` (KDL via `extraConfig`, other wrapper-modules keys) + `extraBinds` (merged keybinds).
|
# Niri uses `extraSettings.extraConfig`; Hyprland uses `chiasson.desktop.hyprland.settings`.
|
||||||
# Hyprland: `chiasson.desktop.hyprland.settings` (merged in HM when `chiasson.desktop.hyprland.enable`).
|
|
||||||
|
|
||||||
#TODO[epic=Moderate] Clean this up, move to host's configuration.nix.
|
#TODO[epic=Moderate] Clean this up, move to host's configuration.nix.
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
|
streamingDisplay = config.chiasson.system.streamingDisplay;
|
||||||
gpuPassthru = config.chiasson.system.gpuPassthru.enable;
|
gpuPassthru = config.chiasson.system.gpuPassthru.enable;
|
||||||
streamingDisplay = config.chiasson.system.streamingDisplay.enable or false;
|
|
||||||
streamingCfg = config.chiasson.system.streamingDisplay or { };
|
|
||||||
|
|
||||||
virtualOutputNiri =
|
|
||||||
lib.optionalString streamingDisplay ''
|
|
||||||
output "${streamingCfg.connector}" {
|
|
||||||
mode "${streamingCfg.mode}"
|
|
||||||
scale ${toString (streamingCfg.niriScale or 1.0)}
|
|
||||||
position ${streamingCfg.niriPosition}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
|
# Niri outputs: a static block per GPU layout, plus the optional virtual 4K panel.
|
||||||
niriOutputs =
|
niriOutputs =
|
||||||
(if gpuPassthru then
|
(if gpuPassthru then
|
||||||
''
|
''
|
||||||
@@ -54,48 +44,30 @@ let
|
|||||||
position x=0 y=-1080
|
position x=0 y=-1080
|
||||||
}
|
}
|
||||||
'')
|
'')
|
||||||
+ virtualOutputNiri;
|
+ lib.optionalString streamingDisplay.enable ''
|
||||||
|
output "${streamingDisplay.connector}" {
|
||||||
virtualOutputHyprland =
|
mode "${streamingDisplay.mode}"
|
||||||
lib.optionalString streamingDisplay
|
scale ${toString streamingDisplay.niriScale}
|
||||||
"${streamingCfg.connector}, ${streamingCfg.mode}, 7680x0, ${toString (streamingCfg.niriScale or 1.0)}";
|
position ${streamingDisplay.niriPosition}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Hyprland monitor strings, with the virtual panel appended when enabled.
|
||||||
hyprlandMonitors =
|
hyprlandMonitors =
|
||||||
(if gpuPassthru then
|
(if gpuPassthru then
|
||||||
[
|
[ "DP-1, 2560x1080@144, 0x0, 1" "HDMI-A-2, 1920x1080@60, -1920x0, 1" ]
|
||||||
"DP-1, 2560x1080@144, 0x0, 1"
|
|
||||||
"HDMI-A-2, 1920x1080@60, -1920x0, 1"
|
|
||||||
]
|
|
||||||
else
|
else
|
||||||
[
|
[ "DP-3, 2560x1080@144, 0x0, 1" "DP-4, 1920x1080@144, 0x-1080, 1" "HDMI-A-3, 1920x1080@60, -1920x0, 1" ])
|
||||||
"DP-3, 2560x1080@144, 0x0, 1"
|
++ lib.optional streamingDisplay.enable "${streamingDisplay.connector}, ${streamingDisplay.mode}, 7680x0, ${toString streamingDisplay.niriScale}";
|
||||||
"DP-4, 1920x1080@144, 0x-1080, 1"
|
|
||||||
"HDMI-A-3, 1920x1080@60, -1920x0, 1"
|
|
||||||
])
|
|
||||||
++ lib.optional streamingDisplay virtualOutputHyprland;
|
|
||||||
|
|
||||||
hyprlandWorkspaces =
|
hyprlandWorkspaces =
|
||||||
if gpuPassthru then
|
if gpuPassthru then
|
||||||
[
|
[ "1, monitor:DP-1, default:true" "2, monitor:DP-1" "3, monitor:DP-1"
|
||||||
"1, monitor:DP-1, default:true"
|
"4, monitor:HDMI-A-2, default:true" "5, monitor:HDMI-A-2" "6, monitor:HDMI-A-2" ]
|
||||||
"2, monitor:DP-1"
|
|
||||||
"3, monitor:DP-1"
|
|
||||||
"4, monitor:HDMI-A-2, default:true"
|
|
||||||
"5, monitor:HDMI-A-2"
|
|
||||||
"6, monitor:HDMI-A-2"
|
|
||||||
]
|
|
||||||
else
|
else
|
||||||
[
|
[ "1, monitor:DP-3, default:true" "2, monitor:DP-3" "3, monitor:DP-3"
|
||||||
"1, monitor:DP-3, default:true"
|
"4, monitor:HDMI-A-3, default:true" "5, monitor:HDMI-A-3" "6, monitor:HDMI-A-3"
|
||||||
"2, monitor:DP-3"
|
"7, monitor:DP-4" "8, monitor:DP-4" "9, monitor:DP-4" ];
|
||||||
"3, monitor:DP-3"
|
|
||||||
"4, monitor:HDMI-A-3, default:true"
|
|
||||||
"5, monitor:HDMI-A-3"
|
|
||||||
"6, monitor:HDMI-A-3"
|
|
||||||
"7, monitor:DP-4"
|
|
||||||
"8, monitor:DP-4"
|
|
||||||
"9, monitor:DP-4"
|
|
||||||
];
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
chiasson.desktop.niri.extraSettings = {
|
chiasson.desktop.niri.extraSettings = {
|
||||||
@@ -103,10 +75,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
chiasson.desktop.niri.extraBinds."XF86Tools".spawn = [
|
chiasson.desktop.niri.extraBinds."XF86Tools".spawn = [
|
||||||
"wpctl"
|
"wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"
|
||||||
"set-mute"
|
|
||||||
"@DEFAULT_AUDIO_SOURCE@"
|
|
||||||
"toggle"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
chiasson.desktop.hyprland.settings = lib.mkIf config.chiasson.desktop.hyprland.enable {
|
chiasson.desktop.hyprland.settings = lib.mkIf config.chiasson.desktop.hyprland.enable {
|
||||||
|
|||||||
@@ -39,7 +39,8 @@
|
|||||||
"hassUrl": "https://home.chiasson.cloud/",
|
"hassUrl": "https://home.chiasson.cloud/",
|
||||||
"hassTokenPath": "/run/secrets/home-assistant/auth-token",
|
"hassTokenPath": "/run/secrets/home-assistant/auth-token",
|
||||||
"showButtonsOnStatusBar": true,
|
"showButtonsOnStatusBar": true,
|
||||||
"showAttributes": false
|
"showAttributes": false,
|
||||||
|
"haRefreshCounter": 1
|
||||||
},
|
},
|
||||||
"unifiedTaskbar": {
|
"unifiedTaskbar": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
"customThemeFile": "",
|
"customThemeFile": "",
|
||||||
"registryThemeVariants": {},
|
"registryThemeVariants": {},
|
||||||
"matugenScheme": "scheme-tonal-spot",
|
"matugenScheme": "scheme-tonal-spot",
|
||||||
|
"matugenContrast": 0,
|
||||||
"runUserMatugenTemplates": true,
|
"runUserMatugenTemplates": true,
|
||||||
"matugenTargetMonitor": "",
|
"matugenTargetMonitor": "",
|
||||||
"popupTransparency": 1,
|
"popupTransparency": 1,
|
||||||
"dockTransparency": 1,
|
"dockTransparency": 1,
|
||||||
"widgetBackgroundColor": "sch",
|
"widgetBackgroundColor": "sch",
|
||||||
|
"widgetBackgroundCustomColor": "#6750A4",
|
||||||
|
"widgetBackgroundCustomStrength": 0.5,
|
||||||
"widgetColorMode": "default",
|
"widgetColorMode": "default",
|
||||||
"controlCenterTileColorMode": "primary",
|
"controlCenterTileColorMode": "primary",
|
||||||
"buttonColorMode": "primary",
|
"buttonColorMode": "primary",
|
||||||
@@ -17,11 +20,18 @@
|
|||||||
"niriLayoutRadiusOverride": -1,
|
"niriLayoutRadiusOverride": -1,
|
||||||
"niriLayoutBorderSize": -1,
|
"niriLayoutBorderSize": -1,
|
||||||
"hyprlandLayoutGapsOverride": -1,
|
"hyprlandLayoutGapsOverride": -1,
|
||||||
|
"hyprlandLayoutGapsOutOverride": -1,
|
||||||
"hyprlandLayoutRadiusOverride": -1,
|
"hyprlandLayoutRadiusOverride": -1,
|
||||||
"hyprlandLayoutBorderSize": -1,
|
"hyprlandLayoutBorderSize": -1,
|
||||||
|
"hyprlandResizeOnBorder": false,
|
||||||
"mangoLayoutGapsOverride": -1,
|
"mangoLayoutGapsOverride": -1,
|
||||||
|
"mangoLayoutGapsOutOverride": -1,
|
||||||
"mangoLayoutRadiusOverride": -1,
|
"mangoLayoutRadiusOverride": -1,
|
||||||
"mangoLayoutBorderSize": -1,
|
"mangoLayoutBorderSize": -1,
|
||||||
|
"mangoTrackpadNaturalScrolling": true,
|
||||||
|
"firstDayOfWeek": -1,
|
||||||
|
"showWeekNumber": false,
|
||||||
|
"calendarBackend": "auto",
|
||||||
"use24HourClock": false,
|
"use24HourClock": false,
|
||||||
"showSeconds": true,
|
"showSeconds": true,
|
||||||
"padHours12Hour": false,
|
"padHours12Hour": false,
|
||||||
@@ -36,6 +46,17 @@
|
|||||||
"modalAnimationSpeed": 1,
|
"modalAnimationSpeed": 1,
|
||||||
"modalCustomAnimationDuration": 150,
|
"modalCustomAnimationDuration": 150,
|
||||||
"enableRippleEffects": true,
|
"enableRippleEffects": true,
|
||||||
|
"animationVariant": 0,
|
||||||
|
"motionEffect": 0,
|
||||||
|
"m3ElevationEnabled": true,
|
||||||
|
"m3ElevationIntensity": 12,
|
||||||
|
"m3ElevationOpacity": 30,
|
||||||
|
"m3ElevationColorMode": "default",
|
||||||
|
"m3ElevationLightDirection": "top",
|
||||||
|
"m3ElevationCustomColor": "#000000",
|
||||||
|
"modalElevationEnabled": true,
|
||||||
|
"popoutElevationEnabled": true,
|
||||||
|
"barElevationEnabled": false,
|
||||||
"blurEnabled": false,
|
"blurEnabled": false,
|
||||||
"blurForegroundLayers": true,
|
"blurForegroundLayers": true,
|
||||||
"blurLayerOutlineOpacity": 0.12,
|
"blurLayerOutlineOpacity": 0.12,
|
||||||
@@ -45,6 +66,8 @@
|
|||||||
"wallpaperFillMode": "Fill",
|
"wallpaperFillMode": "Fill",
|
||||||
"blurredWallpaperLayer": false,
|
"blurredWallpaperLayer": false,
|
||||||
"blurWallpaperOnOverview": false,
|
"blurWallpaperOnOverview": false,
|
||||||
|
"wallpaperBackgroundColorMode": "black",
|
||||||
|
"wallpaperBackgroundCustomColor": "#000000",
|
||||||
"showLauncherButton": true,
|
"showLauncherButton": true,
|
||||||
"showWorkspaceSwitcher": true,
|
"showWorkspaceSwitcher": true,
|
||||||
"showFocusedWindow": true,
|
"showFocusedWindow": true,
|
||||||
@@ -64,6 +87,12 @@
|
|||||||
"showClock": true,
|
"showClock": true,
|
||||||
"showNotificationButton": true,
|
"showNotificationButton": true,
|
||||||
"showBattery": true,
|
"showBattery": true,
|
||||||
|
"showBatteryPercent": true,
|
||||||
|
"showBatteryPercentOnlyOnBattery": false,
|
||||||
|
"showBatteryTime": false,
|
||||||
|
"showBatteryTimeOnlyOnBattery": false,
|
||||||
|
"batteryPillStyle": false,
|
||||||
|
"batteryPillPercentSign": false,
|
||||||
"showControlCenterButton": true,
|
"showControlCenterButton": true,
|
||||||
"showCapsLockIndicator": true,
|
"showCapsLockIndicator": true,
|
||||||
"controlCenterShowNetworkIcon": true,
|
"controlCenterShowNetworkIcon": true,
|
||||||
@@ -78,6 +107,8 @@
|
|||||||
"controlCenterShowBatteryIcon": false,
|
"controlCenterShowBatteryIcon": false,
|
||||||
"controlCenterShowPrinterIcon": false,
|
"controlCenterShowPrinterIcon": false,
|
||||||
"controlCenterShowScreenSharingIcon": true,
|
"controlCenterShowScreenSharingIcon": true,
|
||||||
|
"controlCenterShowIdleInhibitorIcon": false,
|
||||||
|
"controlCenterShowDoNotDisturbIcon": false,
|
||||||
"showPrivacyButton": true,
|
"showPrivacyButton": true,
|
||||||
"privacyShowMicIcon": false,
|
"privacyShowMicIcon": false,
|
||||||
"privacyShowCameraIcon": false,
|
"privacyShowCameraIcon": false,
|
||||||
@@ -133,29 +164,57 @@
|
|||||||
"maxWorkspaceIcons": 9,
|
"maxWorkspaceIcons": 9,
|
||||||
"workspaceAppIconSizeOffset": 1,
|
"workspaceAppIconSizeOffset": 1,
|
||||||
"groupWorkspaceApps": true,
|
"groupWorkspaceApps": true,
|
||||||
|
"groupActiveWorkspaceApps": false,
|
||||||
"workspaceFollowFocus": false,
|
"workspaceFollowFocus": false,
|
||||||
"showOccupiedWorkspacesOnly": true,
|
"showOccupiedWorkspacesOnly": true,
|
||||||
"reverseScrolling": false,
|
"reverseScrolling": false,
|
||||||
"dwlShowAllTags": false,
|
"dwlShowAllTags": false,
|
||||||
|
"workspaceActiveAppHighlightEnabled": false,
|
||||||
"workspaceColorMode": "default",
|
"workspaceColorMode": "default",
|
||||||
|
"workspaceFocusedCustomColor": "#6750A4",
|
||||||
"workspaceOccupiedColorMode": "none",
|
"workspaceOccupiedColorMode": "none",
|
||||||
|
"workspaceOccupiedCustomColor": "#625B71",
|
||||||
"workspaceUnfocusedColorMode": "default",
|
"workspaceUnfocusedColorMode": "default",
|
||||||
|
"workspaceUnfocusedCustomColor": "#49454E",
|
||||||
"workspaceUrgentColorMode": "default",
|
"workspaceUrgentColorMode": "default",
|
||||||
|
"workspaceUrgentCustomColor": "#B3261E",
|
||||||
"workspaceFocusedBorderEnabled": false,
|
"workspaceFocusedBorderEnabled": false,
|
||||||
"workspaceFocusedBorderColor": "primary",
|
"workspaceFocusedBorderColor": "primary",
|
||||||
|
"workspaceFocusedBorderCustomColor": "#6750A4",
|
||||||
"workspaceFocusedBorderThickness": 2,
|
"workspaceFocusedBorderThickness": 2,
|
||||||
|
"workspaceUnfocusedMonitorSeparateAppearance": false,
|
||||||
|
"workspaceUnfocusedMonitorColorMode": "default",
|
||||||
|
"workspaceUnfocusedMonitorFocusedCustomColor": "#6750A4",
|
||||||
|
"workspaceUnfocusedMonitorOccupiedColorMode": "none",
|
||||||
|
"workspaceUnfocusedMonitorOccupiedCustomColor": "#625B71",
|
||||||
|
"workspaceUnfocusedMonitorUnfocusedColorMode": "default",
|
||||||
|
"workspaceUnfocusedMonitorUnfocusedCustomColor": "#49454E",
|
||||||
|
"workspaceUnfocusedMonitorUrgentColorMode": "default",
|
||||||
|
"workspaceUnfocusedMonitorUrgentCustomColor": "#B3261E",
|
||||||
|
"workspaceUnfocusedMonitorBorderEnabled": false,
|
||||||
|
"workspaceUnfocusedMonitorBorderColor": "primary",
|
||||||
|
"workspaceUnfocusedMonitorBorderCustomColor": "#6750A4",
|
||||||
|
"workspaceUnfocusedMonitorBorderThickness": 2,
|
||||||
"workspaceNameIcons": {},
|
"workspaceNameIcons": {},
|
||||||
"waveProgressEnabled": true,
|
"waveProgressEnabled": true,
|
||||||
"scrollTitleEnabled": true,
|
"scrollTitleEnabled": true,
|
||||||
|
"mediaAdaptiveWidthEnabled": true,
|
||||||
"audioVisualizerEnabled": true,
|
"audioVisualizerEnabled": true,
|
||||||
"audioScrollMode": "volume",
|
"audioScrollMode": "volume",
|
||||||
"audioWheelScrollAmount": 5,
|
"audioWheelScrollAmount": 5,
|
||||||
|
"audioDeviceScrollVolumeEnabled": false,
|
||||||
|
"mediaExcludePlayers": [],
|
||||||
"clockCompactMode": false,
|
"clockCompactMode": false,
|
||||||
"focusedWindowCompactMode": false,
|
"focusedWindowCompactMode": false,
|
||||||
|
"focusedWindowSize": 1,
|
||||||
|
"focusedWindowShowIcon": true,
|
||||||
"runningAppsCompactMode": true,
|
"runningAppsCompactMode": true,
|
||||||
"barMaxVisibleApps": 0,
|
"barMaxVisibleApps": 0,
|
||||||
"barMaxVisibleRunningApps": 0,
|
"barMaxVisibleRunningApps": 0,
|
||||||
"barShowOverflowBadge": true,
|
"barShowOverflowBadge": true,
|
||||||
|
"trayAutoOverflow": true,
|
||||||
|
"trayPopupSingleLine": true,
|
||||||
|
"trayMaxVisibleItems": 0,
|
||||||
"appsDockHideIndicators": false,
|
"appsDockHideIndicators": false,
|
||||||
"appsDockColorizeActive": false,
|
"appsDockColorizeActive": false,
|
||||||
"appsDockActiveColorMode": "primary",
|
"appsDockActiveColorMode": "primary",
|
||||||
@@ -163,6 +222,7 @@
|
|||||||
"appsDockEnlargePercentage": 125,
|
"appsDockEnlargePercentage": 125,
|
||||||
"appsDockIconSizePercentage": 100,
|
"appsDockIconSizePercentage": 100,
|
||||||
"keyboardLayoutNameCompactMode": false,
|
"keyboardLayoutNameCompactMode": false,
|
||||||
|
"keyboardLayoutNameShowIcon": false,
|
||||||
"runningAppsCurrentWorkspace": true,
|
"runningAppsCurrentWorkspace": true,
|
||||||
"runningAppsGroupByApp": false,
|
"runningAppsGroupByApp": false,
|
||||||
"runningAppsCurrentMonitor": false,
|
"runningAppsCurrentMonitor": false,
|
||||||
@@ -198,9 +258,18 @@
|
|||||||
"lockDateFormat": "dddd, MMMM d",
|
"lockDateFormat": "dddd, MMMM d",
|
||||||
"greeterRememberLastSession": true,
|
"greeterRememberLastSession": true,
|
||||||
"greeterRememberLastUser": true,
|
"greeterRememberLastUser": true,
|
||||||
|
"greeterAutoLogin": false,
|
||||||
"greeterEnableFprint": false,
|
"greeterEnableFprint": false,
|
||||||
"greeterEnableU2f": false,
|
"greeterEnableU2f": false,
|
||||||
"greeterWallpaperPath": "",
|
"greeterWallpaperPath": "",
|
||||||
|
"greeterUse24HourClock": true,
|
||||||
|
"greeterShowSeconds": false,
|
||||||
|
"greeterPadHours12Hour": false,
|
||||||
|
"greeterLockDateFormat": "",
|
||||||
|
"greeterFontFamily": "",
|
||||||
|
"greeterWallpaperFillMode": "",
|
||||||
|
"greeterSyncPending": false,
|
||||||
|
"greeterSyncBaseline": {},
|
||||||
"mediaSize": 1,
|
"mediaSize": 1,
|
||||||
"appLauncherViewMode": "list",
|
"appLauncherViewMode": "list",
|
||||||
"spotlightModalViewMode": "list",
|
"spotlightModalViewMode": "list",
|
||||||
@@ -211,19 +280,53 @@
|
|||||||
"sortAppsAlphabetically": false,
|
"sortAppsAlphabetically": false,
|
||||||
"appLauncherGridColumns": 4,
|
"appLauncherGridColumns": 4,
|
||||||
"spotlightCloseNiriOverview": true,
|
"spotlightCloseNiriOverview": true,
|
||||||
|
"rememberLastQuery": false,
|
||||||
|
"rememberLastMode": true,
|
||||||
"spotlightSectionViewModes": {},
|
"spotlightSectionViewModes": {},
|
||||||
"appDrawerSectionViewModes": {},
|
"appDrawerSectionViewModes": {},
|
||||||
"niriOverviewOverlayEnabled": true,
|
"niriOverviewOverlayEnabled": true,
|
||||||
"dankLauncherV2Size": "compact",
|
"dankLauncherV2Size": "medium",
|
||||||
|
"dankLauncherV2ShowSourceBadges": true,
|
||||||
"dankLauncherV2BorderEnabled": false,
|
"dankLauncherV2BorderEnabled": false,
|
||||||
"dankLauncherV2BorderThickness": 2,
|
"dankLauncherV2BorderThickness": 2,
|
||||||
"dankLauncherV2BorderColor": "primary",
|
"dankLauncherV2BorderColor": "primary",
|
||||||
"dankLauncherV2ShowFooter": true,
|
"dankLauncherV2ShowFooter": true,
|
||||||
"dankLauncherV2UnloadOnClose": false,
|
"dankLauncherV2UnloadOnClose": true,
|
||||||
|
"dankLauncherV2IncludeFilesInAll": false,
|
||||||
|
"dankLauncherV2IncludeFoldersInAll": false,
|
||||||
|
"launcherUseOverlayLayer": false,
|
||||||
|
"launcherStyle": "spotlight",
|
||||||
|
"spotlightBarShowModeChips": true,
|
||||||
|
"keybindsFloatingWindow": false,
|
||||||
"useAutoLocation": false,
|
"useAutoLocation": false,
|
||||||
"weatherEnabled": true,
|
"weatherEnabled": true,
|
||||||
"networkPreference": "auto",
|
"dashTabs": [
|
||||||
"iconTheme": "WhiteSur-dark",
|
{
|
||||||
|
"id": "overview",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "media",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "wallpaper",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "weather",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "settings",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"networkPreference": "ethernet",
|
||||||
|
"iconThemeDark": "System Default",
|
||||||
|
"iconThemeLight": "System Default",
|
||||||
|
"iconThemePerMode": false,
|
||||||
|
"lastAppliedIconTheme": "",
|
||||||
"cursorSettings": {
|
"cursorSettings": {
|
||||||
"theme": "System Default",
|
"theme": "System Default",
|
||||||
"size": 24,
|
"size": 24,
|
||||||
@@ -240,9 +343,9 @@
|
|||||||
"cursorHideTimeout": 0
|
"cursorHideTimeout": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"launcherLogoMode": "apps",
|
"launcherLogoMode": "os",
|
||||||
"launcherLogoCustomPath": "",
|
"launcherLogoCustomPath": "",
|
||||||
"launcherLogoColorOverride": "",
|
"launcherLogoColorOverride": "primary",
|
||||||
"launcherLogoColorInvertOnMode": false,
|
"launcherLogoColorInvertOnMode": false,
|
||||||
"launcherLogoBrightness": 0.5,
|
"launcherLogoBrightness": 0.5,
|
||||||
"launcherLogoContrast": 1,
|
"launcherLogoContrast": 1,
|
||||||
@@ -251,28 +354,50 @@
|
|||||||
"monoFontFamily": "Fira Code",
|
"monoFontFamily": "Fira Code",
|
||||||
"fontWeight": 400,
|
"fontWeight": 400,
|
||||||
"fontScale": 1,
|
"fontScale": 1,
|
||||||
|
"textRenderType": 0,
|
||||||
|
"textRenderQuality": 0,
|
||||||
"notepadUseMonospace": true,
|
"notepadUseMonospace": true,
|
||||||
"notepadFontFamily": "",
|
"notepadFontFamily": "",
|
||||||
"notepadFontSize": 14,
|
"notepadFontSize": 14,
|
||||||
|
"notificationSummaryFontSize": 0,
|
||||||
|
"notificationBodyFontSize": 0,
|
||||||
"notepadShowLineNumbers": false,
|
"notepadShowLineNumbers": false,
|
||||||
|
"notepadAutoSave": false,
|
||||||
|
"notepadSlideoutSide": "right",
|
||||||
|
"notepadDefaultMode": "slideout",
|
||||||
"notepadTransparencyOverride": -1,
|
"notepadTransparencyOverride": -1,
|
||||||
"notepadLastCustomTransparency": 0.7,
|
"notepadLastCustomTransparency": 0.7,
|
||||||
|
"notepadUseCompositorGap": false,
|
||||||
|
"notepadEdgeGap": 0,
|
||||||
"soundsEnabled": true,
|
"soundsEnabled": true,
|
||||||
"useSystemSoundTheme": false,
|
"useSystemSoundTheme": false,
|
||||||
|
"soundLogin": false,
|
||||||
"soundNewNotification": true,
|
"soundNewNotification": true,
|
||||||
"soundVolumeChanged": true,
|
"soundVolumeChanged": true,
|
||||||
"soundPluggedIn": true,
|
"soundPluggedIn": true,
|
||||||
|
"muteSoundsWhenMediaPlaying": true,
|
||||||
"acMonitorTimeout": 0,
|
"acMonitorTimeout": 0,
|
||||||
"acLockTimeout": 0,
|
"acLockTimeout": 0,
|
||||||
"acSuspendTimeout": 0,
|
"acSuspendTimeout": 0,
|
||||||
"acSuspendBehavior": 0,
|
"acSuspendBehavior": 0,
|
||||||
"acProfileName": "",
|
"acProfileName": "",
|
||||||
|
"acPostLockMonitorTimeout": 0,
|
||||||
"batteryMonitorTimeout": 0,
|
"batteryMonitorTimeout": 0,
|
||||||
"batteryLockTimeout": 0,
|
"batteryLockTimeout": 0,
|
||||||
"batterySuspendTimeout": 0,
|
"batterySuspendTimeout": 0,
|
||||||
"batterySuspendBehavior": 0,
|
"batterySuspendBehavior": 0,
|
||||||
"batteryProfileName": "",
|
"batteryProfileName": "",
|
||||||
|
"batteryPostLockMonitorTimeout": 0,
|
||||||
"batteryChargeLimit": 100,
|
"batteryChargeLimit": 100,
|
||||||
|
"batteryNotifyChargeLimit": false,
|
||||||
|
"batteryCriticalThreshold": 10,
|
||||||
|
"batteryNotifyCritical": true,
|
||||||
|
"batteryLowThreshold": 20,
|
||||||
|
"batteryNotifyLow": false,
|
||||||
|
"batteryChargeLimitNotificationType": 0,
|
||||||
|
"batteryLowNotificationType": 0,
|
||||||
|
"batteryCriticalNotificationType": 1,
|
||||||
|
"batteryAutoPowerSaver": false,
|
||||||
"lockBeforeSuspend": false,
|
"lockBeforeSuspend": false,
|
||||||
"loginctlLockIntegration": true,
|
"loginctlLockIntegration": true,
|
||||||
"fadeToLockEnabled": true,
|
"fadeToLockEnabled": true,
|
||||||
@@ -304,6 +429,7 @@
|
|||||||
"matugenTemplatePywalfox": true,
|
"matugenTemplatePywalfox": true,
|
||||||
"matugenTemplateZenBrowser": true,
|
"matugenTemplateZenBrowser": true,
|
||||||
"matugenTemplateVesktop": false,
|
"matugenTemplateVesktop": false,
|
||||||
|
"matugenTemplateVencord": true,
|
||||||
"matugenTemplateEquibop": true,
|
"matugenTemplateEquibop": true,
|
||||||
"matugenTemplateGhostty": true,
|
"matugenTemplateGhostty": true,
|
||||||
"matugenTemplateKitty": true,
|
"matugenTemplateKitty": true,
|
||||||
@@ -316,10 +442,23 @@
|
|||||||
"matugenTemplateVscode": true,
|
"matugenTemplateVscode": true,
|
||||||
"matugenTemplateEmacs": true,
|
"matugenTemplateEmacs": true,
|
||||||
"matugenTemplateZed": true,
|
"matugenTemplateZed": true,
|
||||||
|
"matugenTemplateNeovimSettings": {
|
||||||
|
"dark": {
|
||||||
|
"baseTheme": "github_dark",
|
||||||
|
"harmony": 0.5
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"baseTheme": "github_light",
|
||||||
|
"harmony": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"matugenTemplateNeovimSetBackground": true,
|
||||||
"showDock": false,
|
"showDock": false,
|
||||||
"dockAutoHide": false,
|
"dockAutoHide": false,
|
||||||
"dockSmartAutoHide": false,
|
"dockSmartAutoHide": false,
|
||||||
|
"dockUseOverlayLayer": false,
|
||||||
"dockGroupByApp": false,
|
"dockGroupByApp": false,
|
||||||
|
"dockRestoreSpecialWorkspaceOnClick": false,
|
||||||
"dockOpenOnOverview": false,
|
"dockOpenOnOverview": false,
|
||||||
"dockPosition": 1,
|
"dockPosition": 1,
|
||||||
"dockSpacing": 4,
|
"dockSpacing": 4,
|
||||||
@@ -342,6 +481,9 @@
|
|||||||
"dockMaxVisibleApps": 0,
|
"dockMaxVisibleApps": 0,
|
||||||
"dockMaxVisibleRunningApps": 0,
|
"dockMaxVisibleRunningApps": 0,
|
||||||
"dockShowOverflowBadge": true,
|
"dockShowOverflowBadge": true,
|
||||||
|
"dockShowTrash": false,
|
||||||
|
"dockTrashFileManager": "default",
|
||||||
|
"dockTrashCustomCommand": "",
|
||||||
"notificationOverlayEnabled": false,
|
"notificationOverlayEnabled": false,
|
||||||
"notificationPopupShadowEnabled": true,
|
"notificationPopupShadowEnabled": true,
|
||||||
"notificationPopupPrivacyMode": false,
|
"notificationPopupPrivacyMode": false,
|
||||||
@@ -359,14 +501,21 @@
|
|||||||
"maxFprintTries": 15,
|
"maxFprintTries": 15,
|
||||||
"enableU2f": false,
|
"enableU2f": false,
|
||||||
"u2fMode": "or",
|
"u2fMode": "or",
|
||||||
"lockScreenActiveMonitor": "all",
|
|
||||||
"lockScreenInactiveColor": "#000000",
|
"lockScreenInactiveColor": "#000000",
|
||||||
"lockScreenNotificationMode": 0,
|
"lockScreenNotificationMode": 0,
|
||||||
|
"lockScreenVideoEnabled": false,
|
||||||
|
"lockScreenVideoPath": "",
|
||||||
|
"lockScreenVideoCycling": false,
|
||||||
|
"lockScreenWallpaperPath": "",
|
||||||
|
"lockScreenWallpaperFillMode": "",
|
||||||
|
"lockScreenFontFamily": "",
|
||||||
"hideBrightnessSlider": false,
|
"hideBrightnessSlider": false,
|
||||||
"notificationTimeoutLow": 5000,
|
"notificationTimeoutLow": 5000,
|
||||||
"notificationTimeoutNormal": 5000,
|
"notificationTimeoutNormal": 5000,
|
||||||
"notificationTimeoutCritical": 0,
|
"notificationTimeoutCritical": 0,
|
||||||
"notificationCompactMode": false,
|
"notificationCompactMode": false,
|
||||||
|
"notificationShowTimeoutBar": false,
|
||||||
|
"notificationDedupeEnabled": true,
|
||||||
"notificationPopupPosition": 0,
|
"notificationPopupPosition": 0,
|
||||||
"notificationAnimationSpeed": 1,
|
"notificationAnimationSpeed": 1,
|
||||||
"notificationCustomAnimationDuration": 400,
|
"notificationCustomAnimationDuration": 400,
|
||||||
@@ -377,6 +526,7 @@
|
|||||||
"notificationHistorySaveNormal": true,
|
"notificationHistorySaveNormal": true,
|
||||||
"notificationHistorySaveCritical": true,
|
"notificationHistorySaveCritical": true,
|
||||||
"notificationRules": [],
|
"notificationRules": [],
|
||||||
|
"notificationFocusedMonitor": false,
|
||||||
"osdAlwaysShowValue": false,
|
"osdAlwaysShowValue": false,
|
||||||
"osdPosition": 5,
|
"osdPosition": 5,
|
||||||
"osdVolumeEnabled": true,
|
"osdVolumeEnabled": true,
|
||||||
@@ -407,9 +557,13 @@
|
|||||||
"customPowerActionReboot": "",
|
"customPowerActionReboot": "",
|
||||||
"customPowerActionPowerOff": "",
|
"customPowerActionPowerOff": "",
|
||||||
"updaterHideWidget": false,
|
"updaterHideWidget": false,
|
||||||
|
"updaterCheckOnStart": false,
|
||||||
"updaterUseCustomCommand": false,
|
"updaterUseCustomCommand": false,
|
||||||
"updaterCustomCommand": "",
|
"updaterCustomCommand": "",
|
||||||
"updaterTerminalAdditionalParams": "",
|
"updaterTerminalAdditionalParams": "",
|
||||||
|
"updaterIntervalSeconds": 1800,
|
||||||
|
"updaterIncludeFlatpak": true,
|
||||||
|
"updaterAllowAUR": true,
|
||||||
"displayNameMode": "system",
|
"displayNameMode": "system",
|
||||||
"screenPreferences": {},
|
"screenPreferences": {},
|
||||||
"showOnLastDisplay": {},
|
"showOnLastDisplay": {},
|
||||||
@@ -420,6 +574,7 @@
|
|||||||
"displayProfileAutoSelect": false,
|
"displayProfileAutoSelect": false,
|
||||||
"displayShowDisconnected": false,
|
"displayShowDisconnected": false,
|
||||||
"displaySnapToEdge": true,
|
"displaySnapToEdge": true,
|
||||||
|
"connectedFrameBarStyleBackups": {},
|
||||||
"barConfigs": [
|
"barConfigs": [
|
||||||
{
|
{
|
||||||
"bottomGap": 0,
|
"bottomGap": 0,
|
||||||
@@ -486,10 +641,6 @@
|
|||||||
{
|
{
|
||||||
"name": "DP-3",
|
"name": "DP-3",
|
||||||
"model": "34GL750"
|
"model": "34GL750"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Virtual-1",
|
|
||||||
"model": "Virtual-1"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"showOnLastDisplay": false,
|
"showOnLastDisplay": false,
|
||||||
@@ -517,7 +668,7 @@
|
|||||||
"id": "gpuTemp",
|
"id": "gpuTemp",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"selectedGpuIndex": 0,
|
"selectedGpuIndex": 0,
|
||||||
"pciId": "",
|
"pciId": "10de:1f07",
|
||||||
"minimumWidth": true
|
"minimumWidth": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -685,6 +836,14 @@
|
|||||||
"desktopWidgetPositions": {},
|
"desktopWidgetPositions": {},
|
||||||
"desktopWidgetGridSettings": {
|
"desktopWidgetGridSettings": {
|
||||||
"DP-3": {
|
"DP-3": {
|
||||||
|
"enabled": true,
|
||||||
|
"size": 40
|
||||||
|
},
|
||||||
|
"HDMI-A-3": {
|
||||||
|
"enabled": true,
|
||||||
|
"size": 50
|
||||||
|
},
|
||||||
|
"DP-4": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"size": 50
|
"size": 50
|
||||||
}
|
}
|
||||||
@@ -696,7 +855,7 @@
|
|||||||
"name": "Desktop Clock",
|
"name": "Desktop Clock",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"config": {
|
"config": {
|
||||||
"style": "analog",
|
"style": "digital",
|
||||||
"transparency": 0.8,
|
"transparency": 0.8,
|
||||||
"colorMode": "primary",
|
"colorMode": "primary",
|
||||||
"customColor": "#ffffff",
|
"customColor": "#ffffff",
|
||||||
@@ -704,347 +863,48 @@
|
|||||||
"showAnalogNumbers": false,
|
"showAnalogNumbers": false,
|
||||||
"showAnalogSeconds": true,
|
"showAnalogSeconds": true,
|
||||||
"displayPreferences": [
|
"displayPreferences": [
|
||||||
"all"
|
{
|
||||||
]
|
"name": "DP-2",
|
||||||
},
|
"model": "SUN-4K"
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 300,
|
|
||||||
"height": 300,
|
|
||||||
"x": 1550,
|
|
||||||
"y": 50
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 1708.3671875,
|
|
||||||
"y": 4.84765625
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "dw_1782021988600_vdg97np4g",
|
"name": "DP-3",
|
||||||
"widgetType": "systemMonitor",
|
"model": "34GL750"
|
||||||
"name": "System Monitor",
|
},
|
||||||
"enabled": true,
|
{
|
||||||
"config": {
|
"name": "DP-4",
|
||||||
"showHeader": true,
|
"model": "ZOWIE XL LCD"
|
||||||
"transparency": 0.8,
|
}
|
||||||
"colorMode": "primary",
|
],
|
||||||
"customColor": "#ffffff",
|
"showDigitalSeconds": false,
|
||||||
"showCpu": true,
|
"showOnOverlay": false,
|
||||||
"showCpuGraph": true,
|
"showOnOverviewOnly": false,
|
||||||
"showCpuTemp": true,
|
"showOnOverview": false
|
||||||
"showGpuTemp": false,
|
|
||||||
"gpuPciId": "",
|
|
||||||
"showMemory": true,
|
|
||||||
"showMemoryGraph": true,
|
|
||||||
"showNetwork": true,
|
|
||||||
"showNetworkGraph": true,
|
|
||||||
"showDisk": true,
|
|
||||||
"showTopProcesses": false,
|
|
||||||
"topProcessCount": 3,
|
|
||||||
"topProcessSortBy": "cpu",
|
|
||||||
"layoutMode": "auto",
|
|
||||||
"graphInterval": 60,
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"positions": {
|
"positions": {
|
||||||
"DP-3": {
|
"DP-3": {
|
||||||
"width": 500,
|
"width": 240,
|
||||||
|
"height": 240,
|
||||||
|
"x": 2240,
|
||||||
|
"y": 40
|
||||||
|
},
|
||||||
|
"DP-4": {
|
||||||
|
"width": 240.484375,
|
||||||
|
"height": 240.484375,
|
||||||
|
"x": 1350,
|
||||||
|
"y": 50
|
||||||
|
},
|
||||||
|
"HDMI-A-3": {
|
||||||
|
"width": 250,
|
||||||
"height": 250,
|
"height": 250,
|
||||||
"x": 2000,
|
"x": 1650,
|
||||||
"y": 50
|
"y": 50
|
||||||
},
|
},
|
||||||
"DP-4": {
|
"DP-2": {
|
||||||
"width": 320,
|
|
||||||
"height": 480,
|
|
||||||
"x": 800,
|
|
||||||
"y": 300
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 320,
|
|
||||||
"height": 480,
|
|
||||||
"x": 1595.0546875,
|
|
||||||
"y": 556.515625
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dw_1782022081429_08ufxr98h",
|
|
||||||
"widgetType": "appShortcut",
|
|
||||||
"name": "Application Shortcut: Obsidian",
|
|
||||||
"enabled": true,
|
|
||||||
"config": {
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
],
|
|
||||||
"showOnOverlay": false,
|
|
||||||
"showOnOverview": false,
|
|
||||||
"showOnOverviewOnly": false,
|
|
||||||
"clickThrough": false,
|
|
||||||
"shortcutApp": "obsidian",
|
|
||||||
"followTheme": false,
|
|
||||||
"drawOutlines": false,
|
|
||||||
"syncPositionAcrossScreens": true
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 100,
|
|
||||||
"height": 100,
|
|
||||||
"x": 150,
|
|
||||||
"y": 200
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
"width": 200,
|
||||||
"height": 200,
|
"height": 200,
|
||||||
"x": 860,
|
"x": 412,
|
||||||
"y": 440
|
"y": 284
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"_synced": {
|
|
||||||
"x": 0.05859375,
|
|
||||||
"y": 0.18518518518518517,
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dw_1782022155947_1a4381zan",
|
|
||||||
"widgetType": "appShortcut",
|
|
||||||
"name": "Application Shortcut: Steam",
|
|
||||||
"enabled": true,
|
|
||||||
"config": {
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
],
|
|
||||||
"showOnOverlay": false,
|
|
||||||
"showOnOverview": false,
|
|
||||||
"showOnOverviewOnly": false,
|
|
||||||
"clickThrough": false,
|
|
||||||
"shortcutApp": "steam",
|
|
||||||
"followTheme": false,
|
|
||||||
"drawOutlines": false,
|
|
||||||
"syncPositionAcrossScreens": true
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 100,
|
|
||||||
"height": 100,
|
|
||||||
"x": 50,
|
|
||||||
"y": 900
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"_synced": {
|
|
||||||
"x": 0.01953125,
|
|
||||||
"y": 0.8333333333333334,
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dw_1782022159047_a0w7xwkkz",
|
|
||||||
"widgetType": "appShortcut",
|
|
||||||
"name": "Application Shortcut: Vesktop",
|
|
||||||
"enabled": true,
|
|
||||||
"config": {
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
],
|
|
||||||
"showOnOverlay": false,
|
|
||||||
"showOnOverview": false,
|
|
||||||
"showOnOverviewOnly": false,
|
|
||||||
"clickThrough": false,
|
|
||||||
"shortcutApp": "vesktop",
|
|
||||||
"followTheme": false,
|
|
||||||
"drawOutlines": false,
|
|
||||||
"syncPositionAcrossScreens": true
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 100,
|
|
||||||
"height": 100,
|
|
||||||
"x": 50,
|
|
||||||
"y": 200
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"_synced": {
|
|
||||||
"x": 0.01953125,
|
|
||||||
"y": 0.18518518518518517,
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dw_1782022160265_i4vr22k1v",
|
|
||||||
"widgetType": "appShortcut",
|
|
||||||
"name": "Application Shortcut: PrismLauncher",
|
|
||||||
"enabled": true,
|
|
||||||
"config": {
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
],
|
|
||||||
"showOnOverlay": false,
|
|
||||||
"showOnOverview": false,
|
|
||||||
"showOnOverviewOnly": false,
|
|
||||||
"clickThrough": false,
|
|
||||||
"shortcutApp": "org.prismlauncher.PrismLauncher",
|
|
||||||
"followTheme": false,
|
|
||||||
"drawOutlines": false,
|
|
||||||
"syncPositionAcrossScreens": true
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 100,
|
|
||||||
"height": 100,
|
|
||||||
"x": 250,
|
|
||||||
"y": 900
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"_synced": {
|
|
||||||
"x": 0.09765625,
|
|
||||||
"y": 0.8333333333333334,
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dw_1782022161442_3vfjq50gk",
|
|
||||||
"widgetType": "appShortcut",
|
|
||||||
"name": "Application Shortcut: Pokeclicker",
|
|
||||||
"enabled": true,
|
|
||||||
"config": {
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
],
|
|
||||||
"showOnOverlay": false,
|
|
||||||
"showOnOverview": false,
|
|
||||||
"showOnOverviewOnly": false,
|
|
||||||
"clickThrough": false,
|
|
||||||
"shortcutApp": "pokeclicker-desktop-with-scripts",
|
|
||||||
"followTheme": false,
|
|
||||||
"drawOutlines": false,
|
|
||||||
"syncPositionAcrossScreens": true
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 100,
|
|
||||||
"height": 100,
|
|
||||||
"x": 150,
|
|
||||||
"y": 900
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"_synced": {
|
|
||||||
"x": 0.05859375,
|
|
||||||
"y": 0.8333333333333334,
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dw_1782022229421_fuo32iz2s",
|
|
||||||
"widgetType": "appShortcut",
|
|
||||||
"name": "Application Shortcut: Edge",
|
|
||||||
"enabled": true,
|
|
||||||
"config": {
|
|
||||||
"displayPreferences": [
|
|
||||||
"all"
|
|
||||||
],
|
|
||||||
"showOnOverlay": false,
|
|
||||||
"showOnOverview": false,
|
|
||||||
"showOnOverviewOnly": false,
|
|
||||||
"clickThrough": false,
|
|
||||||
"shortcutApp": "microsoft-edge",
|
|
||||||
"followTheme": false,
|
|
||||||
"drawOutlines": false,
|
|
||||||
"syncPositionAcrossScreens": true
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"DP-3": {
|
|
||||||
"width": 150,
|
|
||||||
"height": 150,
|
|
||||||
"x": 50,
|
|
||||||
"y": 50
|
|
||||||
},
|
|
||||||
"DP-4": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"HDMI-A-3": {
|
|
||||||
"width": 200,
|
|
||||||
"height": 200,
|
|
||||||
"x": 860,
|
|
||||||
"y": 440
|
|
||||||
},
|
|
||||||
"_synced": {
|
|
||||||
"x": 0.01953125,
|
|
||||||
"y": 0.046296296296296294,
|
|
||||||
"width": 150,
|
|
||||||
"height": 150
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1052,7 +912,7 @@
|
|||||||
"id": "dw_1782022922490_aiumfxf49",
|
"id": "dw_1782022922490_aiumfxf49",
|
||||||
"widgetType": "cavaVisualizer",
|
"widgetType": "cavaVisualizer",
|
||||||
"name": "Cava Visualizer",
|
"name": "Cava Visualizer",
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"config": {
|
"config": {
|
||||||
"displayPreferences": [
|
"displayPreferences": [
|
||||||
"all"
|
"all"
|
||||||
@@ -1087,8 +947,8 @@
|
|||||||
"y": 440
|
"y": 440
|
||||||
},
|
},
|
||||||
"_synced": {
|
"_synced": {
|
||||||
"x": 0.2734375,
|
"x": 0.27313639322916666,
|
||||||
"y": 0.5092592592592593,
|
"y": 0.5089156539351852,
|
||||||
"width": 1100,
|
"width": 1100,
|
||||||
"height": 500
|
"height": 500
|
||||||
}
|
}
|
||||||
@@ -1101,16 +961,19 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"config": {
|
"config": {
|
||||||
"displayPreferences": [
|
"displayPreferences": [
|
||||||
"all"
|
{
|
||||||
|
"name": "DP-4",
|
||||||
|
"model": "ZOWIE XL LCD"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"syncPositionAcrossScreens": true,
|
"syncPositionAcrossScreens": true,
|
||||||
"viewMode": "detailed",
|
"viewMode": "compact",
|
||||||
"colorMode": "primary",
|
"colorMode": "primary",
|
||||||
"backgroundOpacity": 80,
|
"backgroundOpacity": 80,
|
||||||
"showPressure": true,
|
"showPressure": true,
|
||||||
"forecastDays": 7,
|
"forecastDays": 7,
|
||||||
"showHourlyForecast": true,
|
"showHourlyForecast": false,
|
||||||
"hourlyCount": 6,
|
"hourlyCount": 12,
|
||||||
"showLocation": false,
|
"showLocation": false,
|
||||||
"showCondition": true,
|
"showCondition": true,
|
||||||
"showFeelsLike": true
|
"showFeelsLike": true
|
||||||
@@ -1135,17 +998,95 @@
|
|||||||
"y": 440
|
"y": 440
|
||||||
},
|
},
|
||||||
"_synced": {
|
"_synced": {
|
||||||
"x": 0.78125,
|
"x": 0.859375,
|
||||||
"y": 0.32407407407407407,
|
"y": 0.046296296296296294,
|
||||||
"width": 500,
|
"width": 250,
|
||||||
"height": 650
|
"height": 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "dw_1782021988600_vdg97np4g",
|
||||||
|
"widgetType": "systemMonitor",
|
||||||
|
"name": "System Monitor",
|
||||||
|
"enabled": true,
|
||||||
|
"config": {
|
||||||
|
"showHeader": true,
|
||||||
|
"transparency": 0.8,
|
||||||
|
"colorMode": "primary",
|
||||||
|
"customColor": "#ffffff",
|
||||||
|
"showCpu": true,
|
||||||
|
"showCpuGraph": true,
|
||||||
|
"showCpuTemp": true,
|
||||||
|
"showGpuTemp": false,
|
||||||
|
"gpuPciId": "",
|
||||||
|
"showMemory": true,
|
||||||
|
"showMemoryGraph": true,
|
||||||
|
"showNetwork": true,
|
||||||
|
"showNetworkGraph": true,
|
||||||
|
"showDisk": true,
|
||||||
|
"showTopProcesses": false,
|
||||||
|
"topProcessCount": 3,
|
||||||
|
"topProcessSortBy": "cpu",
|
||||||
|
"layoutMode": "auto",
|
||||||
|
"graphInterval": 300,
|
||||||
|
"displayPreferences": [
|
||||||
|
{
|
||||||
|
"name": "DP-2",
|
||||||
|
"model": "SUN-4K"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DP-4",
|
||||||
|
"model": "ZOWIE XL LCD"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"positions": {
|
||||||
|
"DP-3": {
|
||||||
|
"width": 800,
|
||||||
|
"height": 350,
|
||||||
|
"x": 1650,
|
||||||
|
"y": 650
|
||||||
|
},
|
||||||
|
"DP-4": {
|
||||||
|
"width": 800,
|
||||||
|
"height": 350,
|
||||||
|
"x": 1100,
|
||||||
|
"y": 650
|
||||||
|
},
|
||||||
|
"HDMI-A-3": {
|
||||||
|
"width": 700,
|
||||||
|
"height": 350,
|
||||||
|
"x": 1200,
|
||||||
|
"y": 650
|
||||||
|
},
|
||||||
|
"DP-2": {
|
||||||
|
"width": 320,
|
||||||
|
"height": 480,
|
||||||
|
"x": 352,
|
||||||
|
"y": 144
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"desktopWidgetGroups": [],
|
"desktopWidgetGroups": [],
|
||||||
"builtInPluginSettings": {},
|
"builtInPluginSettings": {
|
||||||
|
"dms_settings_search": {
|
||||||
|
"trigger": "?"
|
||||||
|
},
|
||||||
|
"dms_clipboard_search": {
|
||||||
|
"trigger": "cb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clipboardClickToPaste": false,
|
||||||
"clipboardEnterToPaste": false,
|
"clipboardEnterToPaste": false,
|
||||||
|
"clipboardRememberTypeFilter": false,
|
||||||
|
"clipboardTypeFilter": "all",
|
||||||
|
"clipboardVisibleEntryActions": [
|
||||||
|
"pin",
|
||||||
|
"edit",
|
||||||
|
"delete"
|
||||||
|
],
|
||||||
"launcherPluginVisibility": {
|
"launcherPluginVisibility": {
|
||||||
"obsidianSearch": {
|
"obsidianSearch": {
|
||||||
"allowWithoutTrigger": false
|
"allowWithoutTrigger": false
|
||||||
@@ -1155,5 +1096,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"launcherPluginOrder": [],
|
"launcherPluginOrder": [],
|
||||||
"configVersion": 5
|
"frameEnabled": false,
|
||||||
|
"frameThickness": 100,
|
||||||
|
"frameRounding": 100,
|
||||||
|
"frameColor": "surface",
|
||||||
|
"frameOpacity": 0.69,
|
||||||
|
"frameScreenPreferences": [
|
||||||
|
"all"
|
||||||
|
],
|
||||||
|
"frameBarSize": 100,
|
||||||
|
"frameShowOnOverview": false,
|
||||||
|
"frameBlurEnabled": true,
|
||||||
|
"frameCloseGaps": false,
|
||||||
|
"frameLauncherEmergeSide": "bottom",
|
||||||
|
"frameLauncherArcExtender": true,
|
||||||
|
"frameLauncherEdgeHover": true,
|
||||||
|
"frameMode": "connected",
|
||||||
|
"barInsetPaddingShared": -1,
|
||||||
|
"barInsetPaddingSyncAll": false,
|
||||||
|
"frameBarInsetPadding": 26,
|
||||||
|
"configVersion": 12
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
# Extra local disks. Declared here, not in hardware.nix (hardware.nix is generated).
|
# Extra local disks. Declared here, not in hardware.nix (hardware.nix is generated).
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
|
||||||
# Stable UID so NTFS `uid=` matches `users.users.olivier` (override if your account is not 1000).
|
|
||||||
olivierUid = config.users.users.olivier.uid or 1000;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
users.users.olivier.uid = lib.mkDefault 1000;
|
users.users.olivier.uid = lib.mkDefault 1000;
|
||||||
# LABEL="MediaLibrary" (btrfs on sda1 by UUID). No subvol=@ — this disk has no @ subvolume.
|
# LABEL="MediaLibrary" (btrfs on sda1 by UUID). No subvol=@ — this disk has no @ subvolume.
|
||||||
@@ -33,15 +29,4 @@ in
|
|||||||
# LABEL="Deep Storage Unit". Owner olivier, group nfsmedia (990) so:
|
# LABEL="Deep Storage Unit". Owner olivier, group nfsmedia (990) so:
|
||||||
# - local logins write as user 1000 (owner rwx);
|
# - local logins write as user 1000 (owner rwx);
|
||||||
# - NFS (all_squash → uid/gid 990) matches group 990 → rwx (see jellyfin-nfs-export).
|
# - NFS (all_squash → uid/gid 990) matches group 990 → rwx (see jellyfin-nfs-export).
|
||||||
#fileSystems."/mnt/test" = {
|
|
||||||
# device = "/dev/disk/by-uuid/BC12E55E12E51DE0";
|
|
||||||
# fsType = "ntfs-3g";
|
|
||||||
# options = [
|
|
||||||
# "rw"
|
|
||||||
# "force"
|
|
||||||
# "uid=${toString olivierUid}"
|
|
||||||
# "gid=990"
|
|
||||||
# "umask=0002"
|
|
||||||
# ];
|
|
||||||
#};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
# Headless 4K virtual output for Sunshine → Moonlight on a client TV.
|
# Headless 4K virtual output for Sunshine → Moonlight on a client TV.
|
||||||
#
|
#
|
||||||
# NVIDIA proprietary driver: both kernel params are required —
|
# NVIDIA: force-enable a spare DRM connector with a custom EDID via kernel params:
|
||||||
# video=<connector>:e force-enables the connector
|
# video=<connector>:e force-enables the connector
|
||||||
# drm.edid_firmware=<connector>:… loads modes from the EDID blob
|
# drm.edid_firmware=<connector>:… loads modes from the EDID blob
|
||||||
#
|
#
|
||||||
# Pick a connector that is disconnected on the host (check after boot):
|
# Capture is pinned to the connector by name (Sunshine `output_name`), which is
|
||||||
# grep -H . /sys/class/drm/card*-*/status
|
# stable across reboots/hotplug — unlike a numeric monitor index.
|
||||||
#
|
# Reboot after changing connector or EDID. 4K@60 is realistic on RTX 2070.
|
||||||
# Reboot after changing connector or EDID. 4K@60 is realistic on RTX 2070;
|
|
||||||
# 4K@120 on a sink-less connector needs driver patches (see NVIDIA issue #1184).
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.chiasson.system.streamingDisplay;
|
cfg = config.chiasson.system.streamingDisplay;
|
||||||
@@ -16,14 +14,13 @@ let
|
|||||||
edidFirmware = pkgs.runCommand "sunshine-virtual-4k-edid" {
|
edidFirmware = pkgs.runCommand "sunshine-virtual-4k-edid" {
|
||||||
nativeBuildInputs = [ pkgs.python3 ];
|
nativeBuildInputs = [ pkgs.python3 ];
|
||||||
} ''
|
} ''
|
||||||
${pkgs.python3}/bin/python3 ${./generate-virtual-edid.py} $TMPDIR/${cfg.edidFileName}
|
|
||||||
mkdir -p $out/lib/firmware/edid
|
mkdir -p $out/lib/firmware/edid
|
||||||
cp $TMPDIR/${cfg.edidFileName} $out/lib/firmware/edid/${cfg.edidFileName}
|
${pkgs.python3}/bin/python3 ${./generate-virtual-edid.py} $out/lib/firmware/edid/${cfg.edidFileName}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Sunshine 2025.924 wlr capture only accepts a numeric monitor index (not "DP-2").
|
# On stream start: scale + focus the virtual 4K output so streamed windows
|
||||||
# If the index drifts after hotplug, check:
|
# land there. Capture is pinned to the connector via Sunshine `output_name`,
|
||||||
# journalctl --user -u sunshine -b | rg 'Monitor [0-9]+ is'
|
# so no fragile numeric-index detection is needed.
|
||||||
streamDisplayUp = pkgs.writeShellScriptBin "stream-display-up" ''
|
streamDisplayUp = pkgs.writeShellScriptBin "stream-display-up" ''
|
||||||
${pkgs.niri}/bin/niri msg output ${cfg.connector} scale ${toString cfg.niriScale}
|
${pkgs.niri}/bin/niri msg output ${cfg.connector} scale ${toString cfg.niriScale}
|
||||||
${pkgs.niri}/bin/niri msg action focus-monitor ${cfg.connector}
|
${pkgs.niri}/bin/niri msg action focus-monitor ${cfg.connector}
|
||||||
@@ -87,18 +84,6 @@ in
|
|||||||
default = "DP-3";
|
default = "DP-3";
|
||||||
description = "Niri monitor to refocus when a Moonlight session ends.";
|
description = "Niri monitor to refocus when a Moonlight session ends.";
|
||||||
};
|
};
|
||||||
|
|
||||||
sunshineOutputIndex = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "3";
|
|
||||||
example = "3";
|
|
||||||
description = ''
|
|
||||||
Wayland/wlr monitor index for Sunshine `output_name`. Sunshine 2025.924 ignores
|
|
||||||
connector strings like `DP-2` and falls back to monitor 0 (your primary).
|
|
||||||
Find the index with:
|
|
||||||
`journalctl --user -u sunshine -b | rg "Monitor [0-9]+ is ${cfg.connector}"`
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
@@ -118,7 +103,11 @@ in
|
|||||||
(lib.mkIf config.chiasson.system.gaming.sunshine.enable {
|
(lib.mkIf config.chiasson.system.gaming.sunshine.enable {
|
||||||
services.sunshine.settings = {
|
services.sunshine.settings = {
|
||||||
capture = "wlr";
|
capture = "wlr";
|
||||||
output_name = cfg.sunshineOutputIndex;
|
# Pin capture to the virtual display by connector name (stable across
|
||||||
|
# reboots/hotplug). A numeric index drifted to the ultrawide before.
|
||||||
|
output_name = cfg.connector;
|
||||||
|
# RTX 2070 has no AV1 NVENC; avoid probing av1_nvenc.
|
||||||
|
encoder = "hevc_nvenc,h264_nvenc";
|
||||||
global_prep_cmd = "[{\"do\":\"${streamDisplayUp}/bin/stream-display-up\",\"undo\":\"${streamDisplayDown}/bin/stream-display-down\"}]";
|
global_prep_cmd = "[{\"do\":\"${streamDisplayUp}/bin/stream-display-up\",\"undo\":\"${streamDisplayDown}/bin/stream-display-down\"}]";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
host = "14900k";
|
|
||||||
system = "x86_64-linux";
|
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
self.nixosModules."14900kConfiguration"
|
self.nixosModules."14900kConfiguration"
|
||||||
|
|||||||
@@ -23,6 +23,13 @@
|
|||||||
pokeclicker.enable = true;
|
pokeclicker.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
editors.vscode = {
|
||||||
|
enable = true;
|
||||||
|
extensions = with pkgs.vscode-extensions; [
|
||||||
|
alefragnani.project-manager
|
||||||
|
johnpapa.vscode-peacock
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -17,10 +17,6 @@
|
|||||||
userCli.enable = true;
|
userCli.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
chiasson.users.extraModules.olivier =
|
chiasson.users.extraModules.olivier = self.lib.wisdomCatalogExtraModules self;
|
||||||
self.lib.wisdomCatalogExtraModules self
|
|
||||||
++ [
|
|
||||||
self.homeManagerModules.desktopHomeDefaults
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
# Shared HM defaults for desktop hosts (git identity, wisdom catalog toggles).
|
|
||||||
{ ... }: {
|
|
||||||
flake.homeManagerModules.desktopHomeDefaults =
|
|
||||||
{ lib, pkgs, ... }:
|
|
||||||
let
|
|
||||||
aarch64 = pkgs.stdenv.hostPlatform.isAarch64;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
programs.git = {
|
|
||||||
enable = lib.mkDefault true;
|
|
||||||
settings.user = {
|
|
||||||
name = "OlivierChiasson";
|
|
||||||
email = "olivierchiasson@hotmail.fr";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#TODO[epic=Moderate] Check if git-crypt should belong in desktop-home-base.
|
|
||||||
home.packages = [ pkgs.git-crypt pkgs.feishin ];
|
|
||||||
|
|
||||||
chiasson.home = {
|
|
||||||
shell = {
|
|
||||||
fish.enable = lib.mkDefault true;
|
|
||||||
ohMyPosh.enable = lib.mkDefault true;
|
|
||||||
yazi.enable = lib.mkDefault true;
|
|
||||||
};
|
|
||||||
|
|
||||||
terminals.kitty.enable = lib.mkDefault true;
|
|
||||||
|
|
||||||
filebrowsers.nemo.enable = lib.mkDefault true;
|
|
||||||
|
|
||||||
browsers = {
|
|
||||||
chrome.enable = lib.mkDefault false;
|
|
||||||
chromiumHevc = {
|
|
||||||
enable = lib.mkDefault true;
|
|
||||||
packages = lib.mkDefault (
|
|
||||||
if aarch64 then
|
|
||||||
[ "chromium" ]
|
|
||||||
else
|
|
||||||
[ "google-chrome" ]
|
|
||||||
);
|
|
||||||
} // lib.optionalAttrs (!aarch64) {
|
|
||||||
vaapi.gpu = lib.mkDefault "intel";
|
|
||||||
};
|
|
||||||
edge.enable = lib.mkDefault false;
|
|
||||||
flow.enable = lib.mkDefault false;
|
|
||||||
orion.enable = lib.mkDefault false;
|
|
||||||
zen.enable = lib.mkDefault false;
|
|
||||||
};
|
|
||||||
|
|
||||||
editors = {
|
|
||||||
cursor.enable = lib.mkDefault true;
|
|
||||||
kate.enable = lib.mkDefault false;
|
|
||||||
obsidian.enable = lib.mkDefault true;
|
|
||||||
};
|
|
||||||
|
|
||||||
apps = {
|
|
||||||
discord.enable = lib.mkDefault false;
|
|
||||||
localsend.enable = lib.mkDefault true;
|
|
||||||
pokeclicker.enable = lib.mkDefault false;
|
|
||||||
spotify = {
|
|
||||||
enable = lib.mkDefault false;
|
|
||||||
openDiscoveryFirewall = lib.mkDefault false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
desktop = {
|
|
||||||
screenshot = {
|
|
||||||
enable = lib.mkDefault true;
|
|
||||||
swiftshareApiKeyFile = "/run/secrets/swiftshare/API_KEY"; #TODO[epic=sops] redo this by passing sops file output directly
|
|
||||||
};
|
|
||||||
theming.enable = lib.mkDefault true;
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.uconsoleGamepad.enable = lib.mkDefault false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -42,12 +42,7 @@
|
|||||||
# rebuilds Mobile NixOS' script-loader against the patched mruby.
|
# rebuilds Mobile NixOS' script-loader against the patched mruby.
|
||||||
chiasson.system.ideapadMrubyOverlay.enable = true;
|
chiasson.system.ideapadMrubyOverlay.enable = true;
|
||||||
|
|
||||||
# Wi-Fi modem (qcom-wcn3990) + Bluetooth (QCA crnv32) need binary blobs.
|
# Wi-Fi modem (qcom-wcn3990) + Bluetooth (QCA crnv32) need binary blobs
|
||||||
nixpkgs.config.allowUnfreePredicate =
|
|
||||||
pkg: builtins.elem (lib.getName pkg) [
|
|
||||||
"chromeos-sc7180-unredistributable-firmware"
|
|
||||||
"chromeos-sc7180-unredistributable-firmware-zstd"
|
|
||||||
];
|
|
||||||
hardware.firmware = [ pkgs.chromeos-sc7180-unredistributable-firmware ];
|
hardware.firmware = [ pkgs.chromeos-sc7180-unredistributable-firmware ];
|
||||||
hardware.enableRedistributableFirmware = true;
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
host = "ideapad";
|
|
||||||
system = "aarch64-linux";
|
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
self.nixosModules.ideapadConfiguration
|
self.nixosModules.ideapadConfiguration
|
||||||
|
|||||||
@@ -4,18 +4,5 @@
|
|||||||
{ self, ... }:
|
{ self, ... }:
|
||||||
{
|
{
|
||||||
imports = [ self.nixosModules.desktopHomeBase ];
|
imports = [ self.nixosModules.desktopHomeBase ];
|
||||||
|
|
||||||
# Host-only HM overrides (tablet apps, toggles off from desktop-home-base, …).
|
|
||||||
chiasson.users.extraModules.olivier = [
|
|
||||||
# {
|
|
||||||
# chiasson.home = {
|
|
||||||
# # editors.kate.enable = true;
|
|
||||||
# };
|
|
||||||
# }
|
|
||||||
# (
|
|
||||||
# { pkgs, ... }:
|
|
||||||
# { home.packages = with pkgs; [ ]; }
|
|
||||||
# )
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
# NFS mounts of nixdesk (14900k) bulk storage for nix-server. Exports live in
|
|
||||||
# modules/hosts/14900k/_private/jellyfin-nfs-export.nix
|
|
||||||
#
|
|
||||||
# Jellyfin library paths (see also services/jellyfin.nix):
|
|
||||||
# Movies → /mnt/nixdesk-jellyfin/movies
|
|
||||||
# Shows → /mnt/nixdesk-jellyfin/tv
|
|
||||||
#
|
|
||||||
# If you see "Stale file handle" under /mnt after changing exports or fsid on nixdesk, drop the
|
|
||||||
# old client mount and let automount reattach, e.g.:
|
|
||||||
# sudo umount -l /mnt/nixdesk-jellyfin
|
|
||||||
# ls /mnt/nixdesk-jellyfin
|
|
||||||
# (or reboot nix-server.)
|
|
||||||
{ ... }:
|
|
||||||
let
|
|
||||||
nfsExportHost = "192.168.2.25";
|
|
||||||
# nfsvers+tcp: predictable Linux↔Linux; lookupcache=none: fewer stale dentries after export changes.
|
|
||||||
nfsClientOpts = [
|
|
||||||
"rw"
|
|
||||||
"noatime"
|
|
||||||
"nofail"
|
|
||||||
"_netdev"
|
|
||||||
"nfsvers=3"
|
|
||||||
"tcp"
|
|
||||||
"lookupcache=none"
|
|
||||||
"x-systemd.automount"
|
|
||||||
"x-systemd.idle-timeout=3600"
|
|
||||||
];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
fileSystems."/mnt/nixdesk-jellyfin" = {
|
|
||||||
device = "${nfsExportHost}:/mnt/deep/jellyfin";
|
|
||||||
fsType = "nfs";
|
|
||||||
options = nfsClientOpts;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
host = "nix-server";
|
|
||||||
system = "x86_64-linux";
|
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
self.nixosModules.nix-serverConfiguration
|
self.nixosModules.nix-serverConfiguration
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
# NFS mounts of nixdesk (14900k) bulk storage for r5500. Exports live in
|
|
||||||
# modules/hosts/14900k/_private/jellyfin-nfs-export.nix
|
|
||||||
#
|
|
||||||
# Jellyfin library paths:
|
|
||||||
# Movies → /mnt/nixdesk-jellyfin/movies
|
|
||||||
# Shows → /mnt/nixdesk-jellyfin/tv
|
|
||||||
{ ... }:
|
|
||||||
let
|
|
||||||
nfsExportHost = "192.168.2.25";
|
|
||||||
nfsClientOpts = [
|
|
||||||
"rw"
|
|
||||||
"noatime"
|
|
||||||
"nofail"
|
|
||||||
"_netdev"
|
|
||||||
"nfsvers=3"
|
|
||||||
"tcp"
|
|
||||||
"lookupcache=none"
|
|
||||||
"x-systemd.automount"
|
|
||||||
"x-systemd.idle-timeout=3600"
|
|
||||||
];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
fileSystems."/mnt/nixdesk-jellyfin" = {
|
|
||||||
device = "${nfsExportHost}:/mnt/deep/jellyfin";
|
|
||||||
fsType = "nfs";
|
|
||||||
options = nfsClientOpts;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
./_private/media-disk.nix
|
./_private/media-disk.nix
|
||||||
./_private/media-paths.nix
|
./_private/media-paths.nix
|
||||||
./_services/docker-media.nix
|
./_services/docker-media.nix
|
||||||
./_services/nixdesk-nfs-client.nix
|
self.nixosModules.nixdeskJellyfin
|
||||||
./_services/jellyfin.nix
|
./_services/jellyfin.nix
|
||||||
./_services/sonarr.nix
|
./_services/sonarr.nix
|
||||||
./_services/radarr.nix
|
./_services/radarr.nix
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
host = "r5500";
|
|
||||||
system = "x86_64-linux";
|
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
self.nixosModules.r5500Configuration
|
self.nixosModules.r5500Configuration
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
host = "t2mbp";
|
|
||||||
system = "x86_64-linux";
|
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
self.nixosModules.t2mbpConfiguration
|
self.nixosModules.t2mbpConfiguration
|
||||||
|
|||||||
@@ -1,24 +1,29 @@
|
|||||||
{ self, inputs, ... }:
|
{ self, inputs, ... }:
|
||||||
{
|
{
|
||||||
flake.nixosModules.t2mbpHome =
|
flake.nixosModules.t2mbpHome =
|
||||||
{ self, ... }:
|
{ self, pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [ self.nixosModules.desktopHomeBase ];
|
imports = [ self.nixosModules.desktopHomeBase ];
|
||||||
|
|
||||||
chiasson.users.extraModules.olivier = [
|
chiasson.users.extraModules.olivier = [
|
||||||
{
|
{
|
||||||
chiasson.home = {
|
chiasson.home = {
|
||||||
browsers = {
|
browsers.edge.enable = true;
|
||||||
edge.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
apps = {
|
apps = {
|
||||||
discord.enable = true;
|
discord.enable = true;
|
||||||
pokeclicker.enable = true;
|
pokeclicker.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
editors.vscode = {
|
||||||
|
enable = true;
|
||||||
|
extensions = with pkgs.vscode-extensions; [
|
||||||
|
alefragnani.project-manager
|
||||||
|
johnpapa.vscode-peacock
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
specialArgs = inputs // {
|
specialArgs = inputs // {
|
||||||
inherit self;
|
inherit self;
|
||||||
inputs = inputs;
|
inputs = inputs;
|
||||||
host = "uConsole";
|
|
||||||
system = "aarch64-linux";
|
|
||||||
};
|
};
|
||||||
trustCaches = false;
|
trustCaches = false;
|
||||||
modules = [
|
modules = [
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
{ self, inputs, ... }:
|
{ self, inputs, ... }:
|
||||||
{
|
{
|
||||||
flake.nixosModules.uConsoleHome =
|
flake.nixosModules.uConsoleHome =
|
||||||
{ self, ... }:
|
{ self, pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [ self.nixosModules.desktopHomeBase ];
|
imports = [ self.nixosModules.desktopHomeBase ];
|
||||||
|
|
||||||
chiasson.users.extraModules.olivier = [
|
chiasson.users.extraModules.olivier = [
|
||||||
{
|
{
|
||||||
chiasson.home = {
|
chiasson.home.hardware.uconsoleGamepad.enable = true;
|
||||||
hardware.uconsoleGamepad.enable = true;
|
|
||||||
|
chiasson.home.editors.vscode = {
|
||||||
|
enable = true;
|
||||||
|
extensions = with pkgs.vscode-extensions; [
|
||||||
|
alefragnani.project-manager
|
||||||
|
johnpapa.vscode-peacock
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
# Build a raw Navi hive attrset from host specs + deployment targets.
|
|
||||||
# Call `inputs.navi.lib.makeHive` on the result to produce `flake.naviHive`.
|
|
||||||
{ lib, inputs, ... }: {
|
|
||||||
flake.lib.mkNaviHiveConfig =
|
|
||||||
{
|
|
||||||
metaNixpkgs,
|
|
||||||
hostSpecs,
|
|
||||||
deployments,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
deployNodes = lib.filterAttrs (name: _: deployments ? ${name}) hostSpecs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
meta = {
|
|
||||||
nixpkgs = metaNixpkgs;
|
|
||||||
nodeNixpkgs = lib.mapAttrs (
|
|
||||||
name: spec:
|
|
||||||
import inputs.nixpkgs {
|
|
||||||
system = spec.system;
|
|
||||||
}
|
|
||||||
) deployNodes;
|
|
||||||
nodeSpecialArgs = lib.mapAttrs (_: spec: spec.specialArgs) deployNodes;
|
|
||||||
allowApplyAll = false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// lib.mapAttrs (
|
|
||||||
name: spec:
|
|
||||||
{
|
|
||||||
imports = spec.modules or [ spec.configuration ];
|
|
||||||
deployment = deployments.${name};
|
|
||||||
}
|
|
||||||
) deployNodes;
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{ ... }: {
|
|
||||||
flake.lib.rbwSshSocket =
|
|
||||||
let
|
|
||||||
# Bash/Fish init snippets — used by wisdom/shells/{bash,fish}.nix.
|
|
||||||
bashSnippet = ''
|
|
||||||
if [ -z "''${SSH_AUTH_SOCK:-}" ]; then
|
|
||||||
if [ -n "''${XDG_RUNTIME_DIR:-}" ]; then
|
|
||||||
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/rbw/ssh-agent-socket"
|
|
||||||
else
|
|
||||||
export SSH_AUTH_SOCK="/run/user/$(id -u)/rbw/ssh-agent-socket"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
fishSnippet =
|
|
||||||
pkgs: ''
|
|
||||||
if test -z "$SSH_AUTH_SOCK"
|
|
||||||
if test -n "$XDG_RUNTIME_DIR"
|
|
||||||
set -gx SSH_AUTH_SOCK "$XDG_RUNTIME_DIR/rbw/ssh-agent-socket"
|
|
||||||
else
|
|
||||||
set -l _hm_uid (${pkgs.coreutils}/bin/id -u)
|
|
||||||
set -gx SSH_AUTH_SOCK "/run/user/$_hm_uid/rbw/ssh-agent-socket"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
inherit bashSnippet fishSnippet;
|
|
||||||
# Used by home-manager modules to expose SSH_AUTH_SOCK to GUI apps
|
|
||||||
# and HM-managed shells declaratively (no activation script needed).
|
|
||||||
sessionVariable = "$XDG_RUNTIME_DIR/rbw/ssh-agent-socket";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
# Pure helpers: catalog → NixOS/HM/SSH shapes (`self.lib.usersMerge lib`).
|
|
||||||
{ ... }: {
|
|
||||||
flake.lib.usersMerge =
|
|
||||||
lib:
|
|
||||||
let
|
|
||||||
userHm = user: user.homeManager or { };
|
|
||||||
userSsh = user: user.ssh or { };
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
resolveHomeManagerModule =
|
|
||||||
moduleSpec:
|
|
||||||
let
|
|
||||||
t = builtins.typeOf moduleSpec;
|
|
||||||
in
|
|
||||||
if t == "path" || t == "string" then import moduleSpec else moduleSpec;
|
|
||||||
|
|
||||||
selectedUsersAttr =
|
|
||||||
{ catalog, enabled, hostOverrides }:
|
|
||||||
lib.listToAttrs (
|
|
||||||
map (name: {
|
|
||||||
inherit name;
|
|
||||||
value = lib.recursiveUpdate catalog.${name} (hostOverrides.${name} or { });
|
|
||||||
}) enabled
|
|
||||||
);
|
|
||||||
|
|
||||||
missingEnabledNames = catalog: enabled: builtins.filter (name: !(builtins.hasAttr name catalog)) enabled;
|
|
||||||
|
|
||||||
strayHomeUserKeys = homeUsers: enabled:
|
|
||||||
builtins.filter (k: !(builtins.elem k enabled)) (builtins.attrNames homeUsers);
|
|
||||||
|
|
||||||
mkNixosUser =
|
|
||||||
name: user:
|
|
||||||
{
|
|
||||||
isNormalUser = user.isNormalUser or true;
|
|
||||||
description = user.description or name;
|
|
||||||
extraGroups = user.extraGroups or [ ];
|
|
||||||
}
|
|
||||||
// lib.optionalAttrs (user ? hashedPasswordFile && user.hashedPasswordFile != null) {
|
|
||||||
hashedPasswordFile = user.hashedPasswordFile;
|
|
||||||
};
|
|
||||||
|
|
||||||
hmWiredNames =
|
|
||||||
selectedUsers:
|
|
||||||
lib.attrNames (
|
|
||||||
lib.filterAttrs (_: user:
|
|
||||||
let
|
|
||||||
hm = userHm user;
|
|
||||||
in
|
|
||||||
(hm.enable or false) && (hm.module or null) != null
|
|
||||||
) selectedUsers
|
|
||||||
);
|
|
||||||
|
|
||||||
rbwOutboundSnippet =
|
|
||||||
name: user:
|
|
||||||
let
|
|
||||||
outboundCfg = ((userSsh user).outbound or { }).rbw or { };
|
|
||||||
in
|
|
||||||
lib.mkIf (outboundCfg.enable or false) {
|
|
||||||
chiasson.ssh.outbound.rbw.enable = true;
|
|
||||||
chiasson.ssh.outbound.rbw.user = name;
|
|
||||||
chiasson.ssh.outbound.rbw.hosts =
|
|
||||||
if (outboundCfg.hosts or "all") == "all" then [ "all" ] else outboundCfg.hosts;
|
|
||||||
chiasson.ssh.outbound.rbw.extraIdentities = outboundCfg.extraIdentities or [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
mkHmUserModule =
|
|
||||||
{ name, user, hostExtraModules }:
|
|
||||||
let
|
|
||||||
hm = userHm user;
|
|
||||||
hmModule = resolveHomeManagerModule hm.module;
|
|
||||||
in
|
|
||||||
lib.mkMerge (
|
|
||||||
[
|
|
||||||
hmModule
|
|
||||||
(rbwOutboundSnippet name user)
|
|
||||||
]
|
|
||||||
++ (hm.extraModules or [ ])
|
|
||||||
++ hostExtraModules
|
|
||||||
);
|
|
||||||
|
|
||||||
inboundAuthorizedOrNull =
|
|
||||||
user:
|
|
||||||
let
|
|
||||||
inboundCfg = (userSsh user).inbound or { };
|
|
||||||
in
|
|
||||||
if !(inboundCfg.enable or false) then
|
|
||||||
null
|
|
||||||
else if (inboundCfg.authorizedHosts or "all") == "all" then
|
|
||||||
"all"
|
|
||||||
else
|
|
||||||
inboundCfg.authorizedHosts;
|
|
||||||
|
|
||||||
inboundHostsAttr =
|
|
||||||
selectedUsers:
|
|
||||||
lib.pipe selectedUsers [
|
|
||||||
(lib.mapAttrs (_: inboundAuthorizedOrNull))
|
|
||||||
(lib.filterAttrs (_: v: v != null))
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# Resolve `wisdom*` HM slices for NixOS `extraModules` (`self` is not an HM specialArg).
|
|
||||||
# Slices are gated by `chiasson.home.*.enable`; hosts only flip toggles in `home.nix`.
|
|
||||||
{ lib, ... }: {
|
|
||||||
flake.lib.wisdomCatalogExtraModules =
|
|
||||||
self:
|
|
||||||
let
|
|
||||||
names = lib.sort builtins.lessThan (
|
|
||||||
lib.filter (
|
|
||||||
n:
|
|
||||||
lib.hasPrefix "wisdom" n
|
|
||||||
&& n != "wisdom"
|
|
||||||
&& n != "wisdomShellBash"
|
|
||||||
) (builtins.attrNames self.homeManagerModules)
|
|
||||||
);
|
|
||||||
in
|
|
||||||
map (name: self.homeManagerModules.${name}) names;
|
|
||||||
}
|
|
||||||
@@ -7,10 +7,7 @@
|
|||||||
# Resolve which hosts to emit blocks for, and which user identity to
|
# Resolve which hosts to emit blocks for, and which user identity to
|
||||||
# use as the IdentityFile filter against the rbw agent.
|
# use as the IdentityFile filter against the rbw agent.
|
||||||
selectedHostNames =
|
selectedHostNames =
|
||||||
if cfg.hosts == [ "all" ] then
|
if cfg.hosts == [ "all" ] then builtins.attrNames inventory.activeHosts else cfg.hosts;
|
||||||
builtins.attrNames inventory.activeHosts
|
|
||||||
else
|
|
||||||
cfg.hosts;
|
|
||||||
missingHosts = builtins.filter (name: !(builtins.hasAttr name inventory.hosts)) selectedHostNames;
|
missingHosts = builtins.filter (name: !(builtins.hasAttr name inventory.hosts)) selectedHostNames;
|
||||||
# Resolve to the actual host attrs for the template. The "all" case
|
# Resolve to the actual host attrs for the template. The "all" case
|
||||||
# reuses `activeHosts` directly instead of rebuilding the same attrset.
|
# reuses `activeHosts` directly instead of rebuilding the same attrset.
|
||||||
@@ -18,20 +15,21 @@
|
|||||||
if cfg.hosts == [ "all" ] then
|
if cfg.hosts == [ "all" ] then
|
||||||
inventory.activeHosts
|
inventory.activeHosts
|
||||||
else
|
else
|
||||||
builtins.listToAttrs (map (n: { name = n; value = inventory.hosts.${n}; }) selectedHostNames);
|
builtins.listToAttrs (
|
||||||
|
map (n: {
|
||||||
|
name = n;
|
||||||
|
value = inventory.hosts.${n};
|
||||||
|
}) selectedHostNames
|
||||||
|
);
|
||||||
# All identities this HM user may authenticate AS: cfg.user ∪
|
# All identities this HM user may authenticate AS: cfg.user ∪
|
||||||
# extraIdentities. `cfg.user` can be null (e.g. user not in inventory
|
# extraIdentities. `cfg.user` can be null (e.g. user not in inventory
|
||||||
# yet) — in that case the Host-block IdentityFile line is suppressed
|
# yet) — in that case the Host-block IdentityFile line is suppressed
|
||||||
# and cross-account SSH is wired from extraIdentities alone.
|
# and cross-account SSH is wired from extraIdentities alone.
|
||||||
effectiveIdentities = lib.filter (n: n != null) ([ cfg.user ] ++ cfg.extraIdentities);
|
effectiveIdentities = lib.filter (n: n != null) ([ cfg.user ] ++ cfg.extraIdentities);
|
||||||
defaultUserHasKey =
|
defaultUserHasKey = cfg.user == null || (inventory.users.${cfg.user}.publicKey or "") != "";
|
||||||
cfg.user == null
|
|
||||||
|| (inventory.users.${cfg.user}.publicKey or "") != "";
|
|
||||||
# Each extra identity must have a pubkey in the inventory. Dropping
|
# Each extra identity must have a pubkey in the inventory. Dropping
|
||||||
# it silently would produce a dead Match block — fail the build.
|
# it silently would produce a dead Match block — fail the build.
|
||||||
missingExtraKeys = lib.filter
|
missingExtraKeys = lib.filter (n: (inventory.users.${n}.publicKey or "") == "") cfg.extraIdentities;
|
||||||
(n: (inventory.users.${n}.publicKey or "") == "")
|
|
||||||
cfg.extraIdentities;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.ssh.outbound.rbw = {
|
options.chiasson.ssh.outbound.rbw = {
|
||||||
@@ -64,11 +62,14 @@
|
|||||||
extraIdentities = lib.mkOption {
|
extraIdentities = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
example = [ "server" "builder" ];
|
example = [
|
||||||
|
"server"
|
||||||
|
"builder"
|
||||||
|
];
|
||||||
description = ''
|
description = ''
|
||||||
Catalog accounts this HM user may authenticate AS, in addition
|
Catalog accounts this HM user may authenticate AS, in addition
|
||||||
to `cfg.user`. Each entry must have a publicKey pasted into
|
to `cfg.user`. Each entry must have a publicKey pasted into
|
||||||
`modules/lib/ssh-inventory.nix`. Typical for the operator's
|
`modules/ssh/inventory.nix`. Typical for the operator's
|
||||||
primary laptop: `[ "server" "builder" ]` so fleet/ops commands
|
primary laptop: `[ "server" "builder" ]` so fleet/ops commands
|
||||||
like `ssh server@r5500` or `ssh builder@nix-server` work
|
like `ssh server@r5500` or `ssh builder@nix-server` work
|
||||||
without touching `/etc/passwd` on each host.
|
without touching `/etc/passwd` on each host.
|
||||||
@@ -76,7 +77,8 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
config = lib.mkIf cfg.enable (
|
||||||
|
lib.mkMerge [
|
||||||
{
|
{
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
@@ -85,11 +87,11 @@
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion = defaultUserHasKey;
|
assertion = defaultUserHasKey;
|
||||||
message = "ssh.outbound.rbw: no publicKey for inventory user `${cfg.user}` in `modules/lib/ssh-inventory.nix`.";
|
message = "ssh.outbound.rbw: no publicKey for inventory user `${cfg.user}` in `modules/ssh/inventory.nix`.";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion = missingExtraKeys == [ ];
|
assertion = missingExtraKeys == [ ];
|
||||||
message = "ssh.outbound.rbw: extraIdentities has entries with no publicKey in `modules/lib/ssh-inventory.nix`: ${builtins.concatStringsSep ", " missingExtraKeys}";
|
message = "ssh.outbound.rbw: extraIdentities has entries with no publicKey in `modules/ssh/inventory.nix`: ${builtins.concatStringsSep ", " missingExtraKeys}";
|
||||||
}
|
}
|
||||||
# `enable=true` with neither a default user nor any extras gives the
|
# `enable=true` with neither a default user nor any extras gives the
|
||||||
# agent no IdentityFile at all; with IdentitiesOnly yes the user
|
# agent no IdentityFile at all; with IdentitiesOnly yes the user
|
||||||
@@ -102,19 +104,22 @@
|
|||||||
}
|
}
|
||||||
(lib.mkMerge [
|
(lib.mkMerge [
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [ rbw pinentry-gtk2 ];
|
home.packages = with pkgs; [
|
||||||
|
rbw
|
||||||
|
pinentry-gtk2
|
||||||
|
];
|
||||||
home.sessionVariables.SSH_AUTH_SOCK = self.lib.rbwSshSocket.sessionVariable;
|
home.sessionVariables.SSH_AUTH_SOCK = self.lib.rbwSshSocket.sessionVariable;
|
||||||
# Write a `.pub` file per identity this HM user may act as
|
# Write a `.pub` file per identity this HM user may act as
|
||||||
# (cfg.user ∪ extraIdentities). OpenSSH reads each one via
|
# (cfg.user ∪ extraIdentities). OpenSSH reads each one via
|
||||||
# IdentityFile/Match to filter agent keys — they never hold
|
# IdentityFile/Match to filter agent keys — they never hold
|
||||||
# private key material, so 0644 (HM's default) is fine.
|
# private key material, so 0644 (HM's default) is fine.
|
||||||
# OpenSSH's StrictModes only rejects group/other-writable files.
|
# OpenSSH's StrictModes only rejects group/other-writable files.
|
||||||
home.file = lib.listToAttrs (map
|
home.file = lib.listToAttrs (
|
||||||
(n: {
|
map (n: {
|
||||||
name = inventory.mkIdentityFileName n;
|
name = inventory.mkIdentityFileName n;
|
||||||
value.text = "${inventory.users.${n}.publicKey}\n";
|
value.text = "${inventory.users.${n}.publicKey}\n";
|
||||||
})
|
}) effectiveIdentities
|
||||||
effectiveIdentities);
|
);
|
||||||
programs.ssh.enable = lib.mkIf cfg.manageSshConfig false;
|
programs.ssh.enable = lib.mkIf cfg.manageSshConfig false;
|
||||||
}
|
}
|
||||||
(lib.mkIf cfg.manageSshConfig {
|
(lib.mkIf cfg.manageSshConfig {
|
||||||
@@ -143,6 +148,7 @@
|
|||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
{
|
{
|
||||||
assertions = [{
|
assertions = [{
|
||||||
assertion = cfg.enable -> missingKeys == [ ];
|
assertion = cfg.enable -> missingKeys == [ ];
|
||||||
message = "chiasson.ssh.inbound: users enabled but missing public key in `modules/lib/ssh-inventory.nix`: ${lib.concatStringsSep ", " missingKeys}";
|
message = "chiasson.ssh.inbound: users enabled but missing public key in `modules/ssh/inventory.nix`: ${lib.concatStringsSep ", " missingKeys}";
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
(lib.mkIf cfg.enable {
|
(lib.mkIf cfg.enable {
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# rbw (Bitwarden) SSH-agent socket wiring, shared across shells and the
|
||||||
|
# outbound-rbw Home Manager module. Exposed as `flake.lib.rbwSshSocket`.
|
||||||
|
{ ... }: {
|
||||||
|
flake.lib.rbwSshSocket =
|
||||||
|
let
|
||||||
|
socketPath = "$XDG_RUNTIME_DIR/rbw/ssh-agent-socket";
|
||||||
|
|
||||||
|
# Bash init snippet — used by wisdom/shells/bash.nix (profile + interactive).
|
||||||
|
bashSnippet = ''
|
||||||
|
if [ -z "''${SSH_AUTH_SOCK:-}" ]; then
|
||||||
|
if [ -n "''${XDG_RUNTIME_DIR:-}" ]; then
|
||||||
|
export SSH_AUTH_SOCK="${socketPath}"
|
||||||
|
else
|
||||||
|
export SSH_AUTH_SOCK="/run/user/$(id -u)/rbw/ssh-agent-socket"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Fish init snippet — used by wisdom/shells/fish.nix.
|
||||||
|
fishSnippet = pkgs: ''
|
||||||
|
if test -z "$SSH_AUTH_SOCK"
|
||||||
|
if test -n "$XDG_RUNTIME_DIR"
|
||||||
|
set -gx SSH_AUTH_SOCK "${socketPath}"
|
||||||
|
else
|
||||||
|
set -l _hm_uid (${pkgs.coreutils}/bin/id -u)
|
||||||
|
set -gx SSH_AUTH_SOCK "/run/user/$_hm_uid/rbw/ssh-agent-socket"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit bashSnippet fishSnippet;
|
||||||
|
# Used by home-manager modules to expose SSH_AUTH_SOCK to GUI apps
|
||||||
|
# and HM-managed shells declaratively (no activation script needed).
|
||||||
|
sessionVariable = socketPath;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -17,10 +17,9 @@
|
|||||||
++ lib.optionals pkgs.stdenv.isx86_64 [ heroic ];
|
++ lib.optionals pkgs.stdenv.isx86_64 [ heroic ];
|
||||||
|
|
||||||
steamExtraPkgs =
|
steamExtraPkgs =
|
||||||
if !cfg.steam.steamTinkerLaunch.enable then
|
lib.optional (cfg.steam.steamTinkerLaunch.enable && lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.steamtinkerlaunch) pkgs.steamtinkerlaunch;
|
||||||
[ ]
|
|
||||||
else
|
launcherSet = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages;
|
||||||
lib.optional (lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.steamtinkerlaunch) pkgs.steamtinkerlaunch;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.system.gaming = {
|
options.chiasson.system.gaming = {
|
||||||
@@ -194,11 +193,11 @@
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
(lib.mkIf (cfg.launchers.forUsers == null) {
|
(lib.mkIf (cfg.launchers.forUsers == null) {
|
||||||
environment.systemPackages = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages;
|
environment.systemPackages = launcherSet;
|
||||||
})
|
})
|
||||||
(lib.mkIf (cfg.launchers.forUsers != null) {
|
(lib.mkIf (cfg.launchers.forUsers != null) {
|
||||||
users.users = lib.genAttrs cfg.launchers.forUsers (_: {
|
users.users = lib.genAttrs cfg.launchers.forUsers (_: {
|
||||||
packages = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages;
|
packages = launcherSet;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# NFS mount of nixdesk (14900k) bulk storage for clients. Exports live in
|
||||||
|
# modules/hosts/14900k/_private/jellyfin-nfs-export.nix
|
||||||
|
#
|
||||||
|
# Jellyfin library paths (see also jellyfin.nix):
|
||||||
|
# Movies → /mnt/nixdesk-jellyfin/movies
|
||||||
|
# Shows → /mnt/nixdesk-jellyfin/tv
|
||||||
|
#
|
||||||
|
# If you see "Stale file handle" under /mnt after changing exports or fsid on nixdesk, drop the
|
||||||
|
# old client mount and let automount reattach, e.g.:
|
||||||
|
# sudo umount -l /mnt/nixdesk-jellyfin
|
||||||
|
# ls /mnt/nixdesk-jellyfin
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
flake.nixosModules.nixdeskJellyfin =
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
nfsExportHost = "192.168.2.25";
|
||||||
|
# nfsvers+tcp: predictable Linux↔Linux; lookupcache=none: fewer stale dentries after export changes.
|
||||||
|
nfsClientOpts = [
|
||||||
|
"rw"
|
||||||
|
"noatime"
|
||||||
|
"nofail"
|
||||||
|
"_netdev"
|
||||||
|
"nfsvers=3"
|
||||||
|
"tcp"
|
||||||
|
"lookupcache=none"
|
||||||
|
"x-systemd.automount"
|
||||||
|
"x-systemd.idle-timeout=3600"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
fileSystems."/mnt/nixdesk-jellyfin" = {
|
||||||
|
device = "${nfsExportHost}:/mnt/deep/jellyfin";
|
||||||
|
fsType = "nfs";
|
||||||
|
options = nfsClientOpts;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
+151
-28
@@ -8,18 +8,115 @@
|
|||||||
{ config, options, lib, ... }:
|
{ config, options, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.chiasson.users;
|
cfg = config.chiasson.users;
|
||||||
usersLib = self.lib.usersMerge lib;
|
usersLib =
|
||||||
|
let
|
||||||
|
userHm = user: user.homeManager or { };
|
||||||
|
userSsh = user: user.ssh or { };
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
resolveHomeManagerModule =
|
||||||
|
moduleSpec:
|
||||||
|
let
|
||||||
|
t = builtins.typeOf moduleSpec;
|
||||||
|
in
|
||||||
|
if t == "path" || t == "string" then import moduleSpec else moduleSpec;
|
||||||
|
|
||||||
|
selectedUsersAttr =
|
||||||
|
{ catalog, enabled, hostOverrides }:
|
||||||
|
lib.listToAttrs (
|
||||||
|
map (name: {
|
||||||
|
inherit name;
|
||||||
|
value = lib.recursiveUpdate catalog.${name} (hostOverrides.${name} or { });
|
||||||
|
}) enabled
|
||||||
|
);
|
||||||
|
|
||||||
|
missingEnabledNames =
|
||||||
|
catalog: enabled: builtins.filter (name: !(builtins.hasAttr name catalog)) enabled;
|
||||||
|
|
||||||
|
strayHomeUserKeys =
|
||||||
|
homeUsers: enabled: builtins.filter (k: !(builtins.elem k enabled)) (builtins.attrNames homeUsers);
|
||||||
|
|
||||||
|
mkNixosUser =
|
||||||
|
name: user:
|
||||||
|
{
|
||||||
|
isNormalUser = user.isNormalUser or true;
|
||||||
|
description = user.description or name;
|
||||||
|
extraGroups = user.extraGroups or [ ];
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (user ? hashedPasswordFile && user.hashedPasswordFile != null) {
|
||||||
|
hashedPasswordFile = user.hashedPasswordFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
hmWiredNames =
|
||||||
|
selectedUsers:
|
||||||
|
lib.attrNames (
|
||||||
|
lib.filterAttrs (
|
||||||
|
_: user:
|
||||||
|
let
|
||||||
|
hm = userHm user;
|
||||||
|
in
|
||||||
|
(hm.enable or false) && (hm.module or null) != null
|
||||||
|
) selectedUsers
|
||||||
|
);
|
||||||
|
|
||||||
|
rbwOutboundSnippet =
|
||||||
|
name: user:
|
||||||
|
let
|
||||||
|
outboundCfg = ((userSsh user).outbound or { }).rbw or { };
|
||||||
|
in
|
||||||
|
lib.mkIf (outboundCfg.enable or false) {
|
||||||
|
chiasson.ssh.outbound.rbw.enable = true;
|
||||||
|
chiasson.ssh.outbound.rbw.user = name;
|
||||||
|
chiasson.ssh.outbound.rbw.hosts =
|
||||||
|
if (outboundCfg.hosts or "all") == "all" then [ "all" ] else outboundCfg.hosts;
|
||||||
|
chiasson.ssh.outbound.rbw.extraIdentities = outboundCfg.extraIdentities or [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
mkHmUserModule =
|
||||||
|
{ name, user, hostExtraModules }:
|
||||||
|
let
|
||||||
|
hm = userHm user;
|
||||||
|
hmModule = resolveHomeManagerModule hm.module;
|
||||||
|
in
|
||||||
|
lib.mkMerge (
|
||||||
|
[
|
||||||
|
hmModule
|
||||||
|
(rbwOutboundSnippet name user)
|
||||||
|
]
|
||||||
|
++ (hm.extraModules or [ ])
|
||||||
|
++ hostExtraModules
|
||||||
|
);
|
||||||
|
|
||||||
|
inboundAuthorizedOrNull =
|
||||||
|
user:
|
||||||
|
let
|
||||||
|
inboundCfg = (userSsh user).inbound or { };
|
||||||
|
in
|
||||||
|
if !(inboundCfg.enable or false) then
|
||||||
|
null
|
||||||
|
else if (inboundCfg.authorizedHosts or "all") == "all" then
|
||||||
|
"all"
|
||||||
|
else
|
||||||
|
inboundCfg.authorizedHosts;
|
||||||
|
|
||||||
|
inboundHostsAttr =
|
||||||
|
selectedUsers:
|
||||||
|
lib.pipe selectedUsers [
|
||||||
|
(lib.mapAttrs (_: inboundAuthorizedOrNull))
|
||||||
|
(lib.filterAttrs (_: v: v != null))
|
||||||
|
];
|
||||||
|
};
|
||||||
inventory = self.lib.sshInventory;
|
inventory = self.lib.sshInventory;
|
||||||
|
|
||||||
olivierEnabled = lib.elem "olivier" cfg.enabled;
|
olivierEnabled = lib.elem "olivier" cfg.enabled;
|
||||||
|
|
||||||
# Merge catalog + per-host overrides into the final user attrs.
|
# Merge catalog + per-host overrides into the final user attrs.
|
||||||
selectedUsers = lib.listToAttrs (map
|
selectedUsers = lib.listToAttrs (
|
||||||
(name: {
|
map (name: {
|
||||||
inherit name;
|
inherit name;
|
||||||
value = lib.recursiveUpdate cfg.catalog.${name} (cfg.hostOverrides.${name} or { });
|
value = lib.recursiveUpdate cfg.catalog.${name} (cfg.hostOverrides.${name} or { });
|
||||||
})
|
}) cfg.enabled
|
||||||
cfg.enabled);
|
);
|
||||||
|
|
||||||
names = usersLib.hmWiredNames selectedUsers;
|
names = usersLib.hmWiredNames selectedUsers;
|
||||||
missing = usersLib.missingEnabledNames cfg.catalog cfg.enabled;
|
missing = usersLib.missingEnabledNames cfg.catalog cfg.enabled;
|
||||||
@@ -27,26 +124,27 @@
|
|||||||
hmAvailable = lib.hasAttrByPath [ "home-manager" "users" ] options;
|
hmAvailable = lib.hasAttrByPath [ "home-manager" "users" ] options;
|
||||||
inboundUsersAttr = usersLib.inboundHostsAttr selectedUsers;
|
inboundUsersAttr = usersLib.inboundHostsAttr selectedUsers;
|
||||||
|
|
||||||
hmUsersAttr = lib.listToAttrs (map
|
hmUsersAttr = lib.listToAttrs (
|
||||||
(name: {
|
map (name: {
|
||||||
inherit name;
|
inherit name;
|
||||||
value = usersLib.mkHmUserModule {
|
value = usersLib.mkHmUserModule {
|
||||||
inherit name;
|
inherit name;
|
||||||
user = selectedUsers.${name};
|
user = selectedUsers.${name};
|
||||||
hostExtraModules = cfg.extraModules.${name} or [ ];
|
hostExtraModules = cfg.extraModules.${name} or [ ];
|
||||||
};
|
};
|
||||||
})
|
}) names
|
||||||
names);
|
);
|
||||||
|
|
||||||
# Fish shell wiring: HM's fish module declares its package, but
|
# Fish shell wiring: HM's fish module declares its package, but
|
||||||
# /etc/passwd + /etc/shells need updating so login shells work.
|
# /etc/passwd + /etc/shells need updating so login shells work.
|
||||||
# Only fires for HM users that actually enable fish.
|
# Only fires for HM users that actually enable fish.
|
||||||
hmFishUsers =
|
hmFishUsers =
|
||||||
if !hmAvailable then { }
|
if !hmAvailable then
|
||||||
|
{ }
|
||||||
else
|
else
|
||||||
lib.filterAttrs
|
lib.filterAttrs (
|
||||||
(name: hmUser: (hmUser.programs.fish.enable or false) && builtins.elem name names)
|
name: hmUser: (hmUser.programs.fish.enable or false) && builtins.elem name names
|
||||||
config.home-manager.users;
|
) config.home-manager.users;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@@ -108,23 +206,41 @@
|
|||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
description = "Olivier";
|
description = "Olivier";
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"networkmanager" "wheel" "docker" "fuse" "uinput" "kvm"
|
"networkmanager"
|
||||||
|
"wheel"
|
||||||
|
"docker"
|
||||||
|
"fuse"
|
||||||
|
"uinput"
|
||||||
|
"kvm"
|
||||||
# `video` lets brightnessctl/light udev rules own /sys/backlight without sudo.
|
# `video` lets brightnessctl/light udev rules own /sys/backlight without sudo.
|
||||||
# Harmless on headless hosts (no devices).
|
# Harmless on headless hosts (no devices).
|
||||||
"video"
|
"video"
|
||||||
# DRI render + input for gamescope / Steam on Wayland, no sudo.
|
# DRI render + input for gamescope / Steam on Wayland, no sudo.
|
||||||
"render" "input"
|
"render"
|
||||||
|
"input"
|
||||||
];
|
];
|
||||||
hashedPasswordFile = lib.mkIf olivierEnabled (
|
hashedPasswordFile = lib.mkIf olivierEnabled (
|
||||||
config.sops.secrets."users/olivier/hashedPassword".path
|
config.sops.secrets."users/olivier/hashedPassword".path
|
||||||
);
|
);
|
||||||
homeManager = {
|
homeManager = {
|
||||||
enable = true;
|
enable = true;
|
||||||
module = { ... }: {
|
module = { pkgs, ... }: {
|
||||||
home.username = "olivier";
|
home.username = "olivier";
|
||||||
home.homeDirectory = "/home/olivier";
|
home.homeDirectory = "/home/olivier";
|
||||||
home.stateVersion = "25.11";
|
home.stateVersion = "25.11";
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
|
|
||||||
|
# Declarative rbw config — replaces per-host
|
||||||
|
# `rbw config set email|base_url`. Neither value is a
|
||||||
|
# secret (URL + login email), so plaintext is fine, same
|
||||||
|
# as the public keys committed in ssh-inventory.nix.
|
||||||
|
programs.rbw = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
email = "olivierchiasson@hotmail.fr";
|
||||||
|
base_url = "https://bitwarden.chiasson.cloud";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ssh.inbound.enable = true;
|
ssh.inbound.enable = true;
|
||||||
@@ -135,14 +251,20 @@
|
|||||||
# `.pub` filter for each of these and emits a `Match user`
|
# `.pub` filter for each of these and emits a `Match user`
|
||||||
# block, so `ssh server@r5500` / `ssh builder@nix-server`
|
# block, so `ssh server@r5500` / `ssh builder@nix-server`
|
||||||
# route the right private key from the rbw agent.
|
# route the right private key from the rbw agent.
|
||||||
ssh.outbound.rbw.extraIdentities = [ "server" "builder" ];
|
ssh.outbound.rbw.extraIdentities = [
|
||||||
|
"server"
|
||||||
|
"builder"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
server = {
|
server = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
description = "Server user";
|
description = "Server user";
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
homeManager = { enable = false; module = null; };
|
homeManager = {
|
||||||
|
enable = false;
|
||||||
|
module = null;
|
||||||
|
};
|
||||||
ssh.inbound.enable = true;
|
ssh.inbound.enable = true;
|
||||||
ssh.inbound.authorizedHosts = "all";
|
ssh.inbound.authorizedHosts = "all";
|
||||||
ssh.outbound.rbw.enable = false;
|
ssh.outbound.rbw.enable = false;
|
||||||
@@ -154,7 +276,10 @@
|
|||||||
description = "Navi fleet deploy (push + activate only)";
|
description = "Navi fleet deploy (push + activate only)";
|
||||||
extraGroups = [ ];
|
extraGroups = [ ];
|
||||||
createHome = false;
|
createHome = false;
|
||||||
homeManager = { enable = false; module = null; };
|
homeManager = {
|
||||||
|
enable = false;
|
||||||
|
module = null;
|
||||||
|
};
|
||||||
ssh.inbound.enable = true;
|
ssh.inbound.enable = true;
|
||||||
ssh.inbound.authorizedHosts = "all";
|
ssh.inbound.authorizedHosts = "all";
|
||||||
};
|
};
|
||||||
@@ -183,9 +308,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
# NixOS user accounts (no HM, raw).
|
# NixOS user accounts (no HM, raw).
|
||||||
users.users = lib.mapAttrs
|
users.users = lib.mapAttrs (name: user: usersLib.mkNixosUser name user) selectedUsers;
|
||||||
(name: user: usersLib.mkNixosUser name user)
|
|
||||||
selectedUsers;
|
|
||||||
}
|
}
|
||||||
(lib.optionalAttrs hmAvailable {
|
(lib.optionalAttrs hmAvailable {
|
||||||
"home-manager".useGlobalPkgs = lib.mkIf (cfg.homeManager.autoWire && names != [ ]) true;
|
"home-manager".useGlobalPkgs = lib.mkIf (cfg.homeManager.autoWire && names != [ ]) true;
|
||||||
@@ -204,12 +327,12 @@
|
|||||||
# /etc/shells with `mkForce`. `mkNixosUser` doesn't emit `shell`, so
|
# /etc/shells with `mkForce`. `mkNixosUser` doesn't emit `shell`, so
|
||||||
# the force is uncontested.
|
# the force is uncontested.
|
||||||
(lib.mkIf (hmFishUsers != { }) {
|
(lib.mkIf (hmFishUsers != { }) {
|
||||||
environment.shells = lib.mkAfter (lib.mapAttrsToList
|
environment.shells = lib.mkAfter (
|
||||||
(_: hmUser: lib.getExe hmUser.programs.fish.package)
|
lib.mapAttrsToList (_: hmUser: lib.getExe hmUser.programs.fish.package) hmFishUsers
|
||||||
hmFishUsers);
|
);
|
||||||
users.users = lib.mapAttrs
|
users.users = lib.mapAttrs (name: hmUser: {
|
||||||
(name: hmUser: { shell = lib.mkForce (lib.getExe hmUser.programs.fish.package); })
|
shell = lib.mkForce (lib.getExe hmUser.programs.fish.package);
|
||||||
hmFishUsers;
|
}) hmFishUsers;
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
options.chiasson.home.apps.discord.enable = lib.mkEnableOption ''
|
options.chiasson.home.apps.discord.enable = lib.mkEnableOption ''
|
||||||
Vesktop (nixcord). Needs nixpkgs `discord` — breaks on e.g. aarch64-linux.
|
Vesktop (nixcord). Needs nixpkgs `discord` — breaks on e.g. aarch64-linux.
|
||||||
'';
|
'' // {
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf root.enable (lib.mkMerge [
|
config = lib.mkIf root.enable (lib.mkMerge [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.nixosModules.systemLocalsend =
|
flake.nixosModules.systemLocalsend =
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
@@ -19,23 +19,10 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.homeManagerModules.wisdomAppsLocalsend =
|
flake.homeManagerModules.wisdomAppsLocalsend = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "apps.localsend";
|
||||||
let
|
default = true;
|
||||||
root = config.chiasson.home;
|
description = "LocalSend client; open the firewall on NixOS with `system.localsend` if you want inbound.";
|
||||||
cfg = config.chiasson.home.apps.localsend;
|
packages = pkgs: [ pkgs.localsend ];
|
||||||
in
|
|
||||||
{
|
|
||||||
options.chiasson.home.apps.localsend = {
|
|
||||||
enable = lib.mkEnableOption ''
|
|
||||||
LocalSend client; open the firewall on NixOS with `system.localsend` if you want inbound.
|
|
||||||
'';
|
|
||||||
|
|
||||||
package = lib.mkPackageOption pkgs "localsend" { };
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = [ cfg.package ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.homeManagerModules.wisdomAppsPokeclicker =
|
flake.homeManagerModules.wisdomAppsPokeclicker = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "apps.pokeclicker";
|
||||||
let
|
default = false;
|
||||||
root = config.chiasson.home;
|
description = "PokéClicker desktop (Farigh fork .deb → nix).";
|
||||||
cfg = config.chiasson.home.apps.pokeclicker;
|
packages = pkgs: [ (pkgs.callPackage ./package { }) ];
|
||||||
pokeclickerPkg = pkgs.callPackage ./package { };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.chiasson.home.apps.pokeclicker.enable = lib.mkEnableOption "PokéClicker desktop (Farigh fork .deb → nix).";
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = [ pokeclickerPkg ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,8 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.homeManagerModules.wisdomBrowsersChrome =
|
flake.homeManagerModules.wisdomBrowsersChrome = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "browsers.chrome";
|
||||||
let
|
default = false;
|
||||||
root = config.chiasson.home;
|
description = "Chrome (unfree, needs `allowUnfree`); skipped if nixpkgs has no build for this platform.";
|
||||||
cfg = config.chiasson.home.browsers.chrome;
|
packages = pkgs: [ pkgs.google-chrome ];
|
||||||
in
|
|
||||||
{
|
|
||||||
options.chiasson.home.browsers.chrome.enable = lib.mkEnableOption ''
|
|
||||||
Chrome (unfree, needs `allowUnfree`); skipped if nixpkgs has no build for this platform.
|
|
||||||
'';
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = lib.optional (
|
|
||||||
lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.google-chrome
|
|
||||||
) pkgs.google-chrome;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,43 @@
|
|||||||
cfg = config.chiasson.system.chromiumHevc;
|
cfg = config.chiasson.system.chromiumHevc;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.system.chromiumHevc.enable = lib.mkEnableOption ''
|
options.chiasson.system.chromiumHevc = {
|
||||||
|
enable = lib.mkEnableOption ''
|
||||||
VA-API packages for Chromium HEVC (Intel iHD + optional NVIDIA nvidia-vaapi-driver).
|
VA-API packages for Chromium HEVC (Intel iHD + optional NVIDIA nvidia-vaapi-driver).
|
||||||
Pair with `wisdomBrowsersChromiumHevc` on the user side.
|
Pair with `wisdomBrowsersChromiumHevc` on the user side.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
gpu = lib.mkOption {
|
||||||
|
type = lib.types.enum [
|
||||||
|
"intel"
|
||||||
|
"nvidia"
|
||||||
|
];
|
||||||
|
default = "intel";
|
||||||
|
description = ''
|
||||||
|
VA-API stack for the `*-hevc` browser launchers. Use **intel** for Jellyfin
|
||||||
|
(Chromium + nvidia-vaapi-driver is unsupported upstream and fails with
|
||||||
|
`failed Initialize()ing the frame pool` in Jellyfin). **nvidia** adds the
|
||||||
|
nvidia-vaapi-driver and keep renderD129 + VaapiOnNvidiaGPUs for experiments only.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
hardware.graphics.enable = lib.mkDefault true;
|
hardware.graphics.enable = lib.mkDefault true;
|
||||||
hardware.graphics.extraPackages = lib.mkAfter (
|
hardware.graphics.extraPackages = lib.mkAfter (
|
||||||
with pkgs;
|
lib.optionals (cfg.gpu == "nvidia") [
|
||||||
[ nvidia-vaapi-driver ]
|
pkgs.nvidia-vaapi-driver
|
||||||
|
]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.homeManagerModules.wisdomBrowsersChromiumHevc =
|
flake.homeManagerModules.wisdomBrowsersChromiumHevc =
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, osConfig ? { }, ... }:
|
||||||
let
|
let
|
||||||
root = config.chiasson.home;
|
root = config.chiasson.home;
|
||||||
cfg = config.chiasson.home.browsers.chromiumHevc;
|
cfg = config.chiasson.home.browsers.chromiumHevc;
|
||||||
|
gpu = lib.attrByPath [ "chiasson" "system" "chromiumHevc" "gpu" ] "intel" osConfig;
|
||||||
|
|
||||||
browserCatalog = {
|
browserCatalog = {
|
||||||
"google-chrome" = {
|
"google-chrome" = {
|
||||||
@@ -53,7 +71,6 @@
|
|||||||
intel = {
|
intel = {
|
||||||
driver = "iHD";
|
driver = "iHD";
|
||||||
drmDevice = "/dev/dri/renderD128";
|
drmDevice = "/dev/dri/renderD128";
|
||||||
nvdBackend = "direct";
|
|
||||||
enableFeatures = [
|
enableFeatures = [
|
||||||
"VaapiVideoDecodeLinuxGL"
|
"VaapiVideoDecodeLinuxGL"
|
||||||
"VaapiVideoDecoder"
|
"VaapiVideoDecoder"
|
||||||
@@ -69,7 +86,6 @@
|
|||||||
nvidia = {
|
nvidia = {
|
||||||
driver = "nvidia";
|
driver = "nvidia";
|
||||||
drmDevice = "/dev/dri/renderD129";
|
drmDevice = "/dev/dri/renderD129";
|
||||||
nvdBackend = "direct";
|
|
||||||
enableFeatures = [
|
enableFeatures = [
|
||||||
"VaapiVideoDecoder"
|
"VaapiVideoDecoder"
|
||||||
"VaapiIgnoreDriverChecks"
|
"VaapiIgnoreDriverChecks"
|
||||||
@@ -85,21 +101,17 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
activeGpu = gpuProfiles.${cfg.vaapi.gpu};
|
activeGpu = gpuProfiles.${gpu};
|
||||||
|
|
||||||
mkChromiumHevc =
|
|
||||||
packageName:
|
|
||||||
let
|
|
||||||
spec = browserCatalog.${packageName};
|
|
||||||
browser = spec.package;
|
|
||||||
launcherName = spec.launcher;
|
|
||||||
enableFeatures = lib.concatStringsSep "," activeGpu.enableFeatures;
|
enableFeatures = lib.concatStringsSep "," activeGpu.enableFeatures;
|
||||||
disableFeatures = lib.concatStringsSep "," activeGpu.disableFeatures;
|
disableFeatures = lib.concatStringsSep "," activeGpu.disableFeatures;
|
||||||
desktopItem = pkgs.makeDesktopItem {
|
|
||||||
name = launcherName;
|
mkDesktopItem =
|
||||||
|
spec:
|
||||||
|
pkgs.makeDesktopItem {
|
||||||
|
name = spec.launcher;
|
||||||
desktopName = spec.desktopName;
|
desktopName = spec.desktopName;
|
||||||
genericName = "Web Browser";
|
genericName = "Web Browser";
|
||||||
exec = "${launcherName} %U";
|
exec = "${spec.launcher} %U";
|
||||||
icon = spec.icon;
|
icon = spec.icon;
|
||||||
categories = [
|
categories = [
|
||||||
"Network"
|
"Network"
|
||||||
@@ -113,6 +125,14 @@
|
|||||||
"x-scheme-handler/https"
|
"x-scheme-handler/https"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mkChromiumHevc =
|
||||||
|
packageName:
|
||||||
|
let
|
||||||
|
spec = browserCatalog.${packageName};
|
||||||
|
browser = spec.package;
|
||||||
|
launcherName = spec.launcher;
|
||||||
|
desktopItem = mkDesktopItem spec;
|
||||||
in
|
in
|
||||||
pkgs.runCommand launcherName
|
pkgs.runCommand launcherName
|
||||||
{
|
{
|
||||||
@@ -126,7 +146,7 @@
|
|||||||
makeWrapper ${browser}/bin/${spec.binary} $out/bin/${launcherName} \
|
makeWrapper ${browser}/bin/${spec.binary} $out/bin/${launcherName} \
|
||||||
--set LIBVA_DRIVER_NAME ${lib.escapeShellArg activeGpu.driver} \
|
--set LIBVA_DRIVER_NAME ${lib.escapeShellArg activeGpu.driver} \
|
||||||
--set LIBVA_DRM_DEVICE ${lib.escapeShellArg activeGpu.drmDevice} \
|
--set LIBVA_DRM_DEVICE ${lib.escapeShellArg activeGpu.drmDevice} \
|
||||||
--set NVD_BACKEND ${lib.escapeShellArg activeGpu.nvdBackend} \
|
--set NVD_BACKEND direct \
|
||||||
--add-flags "--enable-features=${enableFeatures}" \
|
--add-flags "--enable-features=${enableFeatures}" \
|
||||||
--add-flags "--disable-features=${disableFeatures}" \
|
--add-flags "--disable-features=${disableFeatures}" \
|
||||||
${lib.concatMapStringsSep " " (a: "--add-flags ${lib.escapeShellArg a}") cfg.extraCommandLineArgs}
|
${lib.concatMapStringsSep " " (a: "--add-flags ${lib.escapeShellArg a}") cfg.extraCommandLineArgs}
|
||||||
@@ -136,46 +156,28 @@
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
selectedPackages = lib.filter (
|
selectedPackages = lib.filter (
|
||||||
name:
|
name: lib.meta.availableOn pkgs.stdenv.hostPlatform browserCatalog.${name}.package
|
||||||
let
|
|
||||||
spec = browserCatalog.${name};
|
|
||||||
in
|
|
||||||
lib.meta.availableOn pkgs.stdenv.hostPlatform spec.package
|
|
||||||
) cfg.packages;
|
) cfg.packages;
|
||||||
|
|
||||||
wrappers = map mkChromiumHevc selectedPackages;
|
wrappers = map mkChromiumHevc selectedPackages;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.home.browsers.chromiumHevc = {
|
options.chiasson.home.browsers.chromiumHevc = {
|
||||||
enable = lib.mkEnableOption ''
|
enable =
|
||||||
|
lib.mkEnableOption ''
|
||||||
`google-chrome-hevc`: Chromium with VA-API HEVC for Jellyfin / MSE playback.
|
`google-chrome-hevc`: Chromium with VA-API HEVC for Jellyfin / MSE playback.
|
||||||
|
|
||||||
Default GPU is **Intel** (`vaapi.gpu = "intel"`): Chromium + NVIDIA VA-API is
|
GPU stack comes from `chiasson.system.chromiumHevc.gpu` (default **intel**).
|
||||||
unsupported upstream (`nvidia-vaapi-driver` README) and fails with
|
|
||||||
`failed Initialize()ing the frame pool` in Jellyfin.
|
|
||||||
|
|
||||||
Requires `chiasson.system.chromiumHevc.enable` on NixOS.
|
Requires `chiasson.system.chromiumHevc.enable` on NixOS.
|
||||||
'';
|
''
|
||||||
|
// {
|
||||||
packages = lib.mkOption {
|
default = true;
|
||||||
type = lib.types.listOf (
|
|
||||||
lib.types.enum (lib.attrNames browserCatalog)
|
|
||||||
);
|
|
||||||
default = [ "google-chrome" ];
|
|
||||||
description = "Chromium-based browsers to wrap.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vaapi.gpu = lib.mkOption {
|
packages = lib.mkOption {
|
||||||
type = lib.types.enum [
|
type = lib.types.listOf (lib.types.enum (lib.attrNames browserCatalog));
|
||||||
"intel"
|
default = if pkgs.stdenv.hostPlatform.isAarch64 then [ "chromium" ] else [ "google-chrome" ];
|
||||||
"nvidia"
|
description = "Chromium-based browsers to wrap.";
|
||||||
];
|
|
||||||
default = "intel";
|
|
||||||
description = ''
|
|
||||||
VA-API stack for `google-chrome-hevc`. Use **intel** for Jellyfin (Chromium +
|
|
||||||
nvidia-vaapi-driver is unsupported and hits frame-pool init errors). **nvidia**
|
|
||||||
keeps renderD129 + VaapiOnNvidiaGPUs for experiments only.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extraCommandLineArgs = lib.mkOption {
|
extraCommandLineArgs = lib.mkOption {
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.homeManagerModules.wisdomBrowsersEdge =
|
flake.homeManagerModules.wisdomBrowsersEdge = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "browsers.edge";
|
||||||
let
|
default = false;
|
||||||
root = config.chiasson.home;
|
description = "Edge (unfree); skipped if unavailable on this platform.";
|
||||||
cfg = config.chiasson.home.browsers.edge;
|
packages = pkgs: [ pkgs.microsoft-edge ];
|
||||||
in
|
|
||||||
{
|
|
||||||
options.chiasson.home.browsers.edge.enable = lib.mkEnableOption "Edge (unfree); skipped if unavailable on this platform.";
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = lib.optional (
|
|
||||||
lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.microsoft-edge
|
|
||||||
) pkgs.microsoft-edge;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.homeManagerModules.wisdomBrowsersFlow =
|
flake.homeManagerModules.wisdomBrowsersFlow = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "browsers.flow";
|
||||||
let
|
default = false;
|
||||||
root = config.chiasson.home;
|
description = "[Flow](https://github.com/MultiboxLabs/flow-browser) — upstream AppImage wrapped for NixOS.";
|
||||||
cfg = config.chiasson.home.browsers.flow;
|
packages =
|
||||||
|
pkgs:
|
||||||
flow-browser =
|
|
||||||
let
|
let
|
||||||
pname = "flow-browser";
|
pname = "flow-browser";
|
||||||
version = "0.11.0";
|
version = "0.11.0";
|
||||||
@@ -25,7 +24,8 @@
|
|||||||
|
|
||||||
appimageContents = pkgs.appimageTools.extractType2 { inherit pname version src; };
|
appimageContents = pkgs.appimageTools.extractType2 { inherit pname version src; };
|
||||||
in
|
in
|
||||||
pkgs.appimageTools.wrapType2 {
|
[
|
||||||
|
(pkgs.appimageTools.wrapType2 {
|
||||||
inherit pname version src;
|
inherit pname version src;
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
@@ -45,23 +45,13 @@
|
|||||||
meta = {
|
meta = {
|
||||||
description = "Chromium-based browser (upstream AppImage)";
|
description = "Chromium-based browser (upstream AppImage)";
|
||||||
homepage = "https://github.com/MultiboxLabs/flow-browser";
|
homepage = "https://github.com/MultiboxLabs/flow-browser";
|
||||||
license = lib.licenses.gpl3Plus;
|
license = pkgs.lib.licenses.gpl3Plus;
|
||||||
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
|
sourceProvenance = with pkgs.lib.sourceTypes; [ binaryNativeCode ];
|
||||||
platforms = [ "x86_64-linux" "aarch64-linux" ];
|
platforms = [ "x86_64-linux" "aarch64-linux" ];
|
||||||
mainProgram = pname;
|
mainProgram = pname;
|
||||||
maintainers = [ ];
|
maintainers = [ ];
|
||||||
};
|
};
|
||||||
};
|
})
|
||||||
in
|
];
|
||||||
{
|
|
||||||
options.chiasson.home.browsers.flow.enable = lib.mkEnableOption ''
|
|
||||||
[Flow](https://github.com/MultiboxLabs/flow-browser) — upstream AppImage wrapped for NixOS.
|
|
||||||
'';
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = lib.optional (
|
|
||||||
lib.meta.availableOn pkgs.stdenv.hostPlatform flow-browser
|
|
||||||
) flow-browser;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@
|
|||||||
{
|
{
|
||||||
options.chiasson.home.browsers.orion.enable = lib.mkEnableOption ''
|
options.chiasson.home.browsers.orion.enable = lib.mkEnableOption ''
|
||||||
[Orion](https://orionbrowser.com/) (Kagi) — installs the upstream Flatpak bundle and provides `oriongtk`.
|
[Orion](https://orionbrowser.com/) (Kagi) — installs the upstream Flatpak bundle and provides `oriongtk`.
|
||||||
'';
|
'' // {
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
config = lib.mkIf (root.enable && cfg.enable) {
|
||||||
home.packages = [ oriongtk ];
|
home.packages = [ oriongtk ];
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
{
|
{
|
||||||
imports = [ inputs.zen-browser.homeModules.beta ];
|
imports = [ inputs.zen-browser.homeModules.beta ];
|
||||||
|
|
||||||
options.chiasson.home.browsers.zen.enable = lib.mkEnableOption "Zen Browser + locked-down policies / extensions.";
|
options.chiasson.home.browsers.zen.enable = lib.mkEnableOption "Zen Browser + locked-down policies / extensions." // {
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
config = lib.mkIf (root.enable && cfg.enable) {
|
||||||
programs.zen-browser = {
|
programs.zen-browser = {
|
||||||
|
|||||||
+28
-10
@@ -1,22 +1,21 @@
|
|||||||
# HM side of the flake; option tree is `chiasson.home.*` (docs/conventions.md).
|
# HM side of the flake; option tree is `chiasson.home.*` (docs/conventions.md).
|
||||||
{ self, inputs, ... }: {
|
{ self, inputs, ... }: {
|
||||||
# Root module: chiasson.home.enable + bash. Other `wisdom*` slices auto-wire via
|
# Root module: chiasson.home.enable + git identity. Other `wisdom*` slices (including
|
||||||
# `lib.wisdomCatalogExtraModules`; hosts flip `chiasson.home.*.enable` rather than re-importing.
|
# the bash shell) auto-wire via `lib.wisdomCatalogExtraModules`; hosts flip
|
||||||
|
# `chiasson.home.*.enable` rather than re-importing.
|
||||||
flake.homeManagerModules.wisdom =
|
flake.homeManagerModules.wisdom =
|
||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.chiasson.home;
|
cfg = config.chiasson.home;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
|
||||||
self.homeManagerModules.wisdomShellBash
|
|
||||||
];
|
|
||||||
|
|
||||||
options.chiasson.home = {
|
options.chiasson.home = {
|
||||||
enable = lib.mkEnableOption ''
|
enable =
|
||||||
|
lib.mkEnableOption ''
|
||||||
HM profile root for this flake (bash on by default). Desktop hosts use
|
HM profile root for this flake (bash on by default). Desktop hosts use
|
||||||
`lib.wisdomCatalogExtraModules` once per user and flip `chiasson.home.*.enable` on the host.
|
`lib.wisdomCatalogExtraModules` once per user and flip `chiasson.home.*.enable` on the host.
|
||||||
'' // {
|
''
|
||||||
|
// {
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,6 +28,25 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable { home.packages = cfg.extraPackages; };
|
config = lib.mkIf cfg.enable (
|
||||||
|
lib.mkMerge [
|
||||||
|
{ home.packages = cfg.extraPackages; }
|
||||||
|
|
||||||
|
# Base git identity + encryption/player tools shared by every HM user.
|
||||||
|
{
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
settings.user = {
|
||||||
|
name = "OlivierChiasson";
|
||||||
|
email = "olivierchiasson@hotmail.fr";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
home.packages = [
|
||||||
|
pkgs.git-crypt
|
||||||
|
pkgs.feishin
|
||||||
|
];
|
||||||
|
}
|
||||||
|
]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
enable = lib.mkEnableOption ''
|
enable = lib.mkEnableOption ''
|
||||||
WhiteSur GTK + icon themes, Phinger cursor, and Qt via qt6ct (DMS) or KDE platform theme.
|
WhiteSur GTK + icon themes, Phinger cursor, and Qt via qt6ct (DMS) or KDE platform theme.
|
||||||
Matugen accent colors load via gtk3/gtk4 extraCss when matugenGtkColors is enabled.
|
Matugen accent colors load via gtk3/gtk4 extraCss when matugenGtkColors is enabled.
|
||||||
'';
|
'' // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
matugenGtkColors = lib.mkOption {
|
matugenGtkColors = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
|
|||||||
@@ -13,11 +13,13 @@
|
|||||||
{
|
{
|
||||||
options.chiasson.home.desktop.screenshot.enable = lib.mkEnableOption ''
|
options.chiasson.home.desktop.screenshot.enable = lib.mkEnableOption ''
|
||||||
grim/slurp/swappy + SwiftShare helpers; Hyprland binds if HM Hyprland is on.
|
grim/slurp/swappy + SwiftShare helpers; Hyprland binds if HM Hyprland is on.
|
||||||
'';
|
'' // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
options.chiasson.home.desktop.screenshot.swiftshareApiKeyFile = lib.mkOption {
|
options.chiasson.home.desktop.screenshot.swiftshareApiKeyFile = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = null;
|
default = "/run/secrets/swiftshare/API_KEY";
|
||||||
description = ''
|
description = ''
|
||||||
File with SwiftShare API key (sops path is fine). Required when screenshot module is on.
|
File with SwiftShare API key (sops path is fine). Required when screenshot module is on.
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -33,7 +33,9 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.home.editors.cursor = {
|
options.chiasson.home.editors.cursor = {
|
||||||
enable = lib.mkEnableOption "Cursor editor from the `cursor` flake input.";
|
enable = lib.mkEnableOption "Cursor editor from the `cursor` flake input." // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
setAsDefaultEditor = lib.mkOption {
|
setAsDefaultEditor = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.homeManagerModules.wisdomEditorsKate =
|
flake.homeManagerModules.wisdomEditorsKate = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "editors.kate";
|
||||||
let
|
default = false;
|
||||||
root = config.chiasson.home;
|
description = "Kate.";
|
||||||
cfg = config.chiasson.home.editors.kate;
|
packages = pkgs: [ pkgs.kdePackages.kate ];
|
||||||
in
|
|
||||||
{
|
|
||||||
options.chiasson.home.editors.kate.enable = lib.mkEnableOption "Kate.";
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = lib.optional (
|
|
||||||
lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.kdePackages.kate
|
|
||||||
) pkgs.kdePackages.kate;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,8 @@
|
|||||||
{ ... }: {
|
{ self, ... }: {
|
||||||
flake.homeManagerModules.wisdomEditorsObsidian =
|
flake.homeManagerModules.wisdomEditorsObsidian = self.lib.wisdomSlice {
|
||||||
{ config, lib, pkgs, ... }:
|
path = "editors.obsidian";
|
||||||
let
|
default = true;
|
||||||
root = config.chiasson.home;
|
description = "Obsidian (unfree); skipped if unavailable here.";
|
||||||
cfg = config.chiasson.home.editors.obsidian;
|
packages = pkgs: [ pkgs.obsidian ];
|
||||||
in
|
|
||||||
{
|
|
||||||
options.chiasson.home.editors.obsidian.enable = lib.mkEnableOption ''
|
|
||||||
Obsidian (unfree); skipped if unavailable here.
|
|
||||||
'';
|
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
|
||||||
home.packages = lib.optional (
|
|
||||||
lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.obsidian
|
|
||||||
) pkgs.obsidian;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# Visual Studio Code (Microsoft build, unfree). Default extensions + settings shared by all
|
||||||
|
# hosts; per-host extras (peacock, comment-anchors, project-manager) go via
|
||||||
|
# `chiasson.home.editors.vscode.extensions`.
|
||||||
|
{ self, ... }: {
|
||||||
|
flake.homeManagerModules.wisdomEditorsVscode =
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
root = config.chiasson.home;
|
||||||
|
cfg = config.chiasson.home.editors.vscode;
|
||||||
|
|
||||||
|
defaultExtensions = with pkgs.vscode-extensions; [
|
||||||
|
jnoortheen.nix-ide
|
||||||
|
yzhang.markdown-all-in-one
|
||||||
|
esbenp.prettier-vscode
|
||||||
|
vscjava.vscode-java-pack
|
||||||
|
redhat.java
|
||||||
|
];
|
||||||
|
|
||||||
|
# Wrap VS Code so a JDK is on PATH — the Red Hat Java language server (and
|
||||||
|
# other extension-bundled JVMs) need `java` to run, independent of the
|
||||||
|
# per-project `java.configuration.runtimes` setting.
|
||||||
|
vscodeWithJdk = pkgs.symlinkJoin {
|
||||||
|
name = "vscode-with-jdk";
|
||||||
|
paths = [ pkgs.vscode ];
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram "$out/bin/code" \
|
||||||
|
--prefix PATH : "${pkgs.jdk25}/bin"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
coreSettings = {
|
||||||
|
"nix.enableLanguageServer" = true;
|
||||||
|
"nix.serverPath" = "nixd";
|
||||||
|
"nix.serverSettings" = {
|
||||||
|
nixd = {
|
||||||
|
formatting = {
|
||||||
|
command = "nixfmt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"diffEditor.ignoreTrimWhitespace" = false;
|
||||||
|
"chat.disableAIFeatures" = true;
|
||||||
|
|
||||||
|
"java.configuration.runtimes" = [
|
||||||
|
{
|
||||||
|
name = "JavaSE-21";
|
||||||
|
path = "${pkgs.jdk21}/lib/openjdk";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "JavaSE-25";
|
||||||
|
path = "${pkgs.jdk25}/lib/openjdk";
|
||||||
|
default = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Seed a *writable* settings.json (not a store symlink) so extensions like
|
||||||
|
# kilo-code can edit it at runtime. `force = false` in the config means HM
|
||||||
|
# only writes it when absent, preserving kilo's later edits across `switch`.
|
||||||
|
settingsJson = pkgs.writeText "vscode-user-settings" (
|
||||||
|
builtins.toJSON coreSettings
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.chiasson.home.editors.vscode = {
|
||||||
|
enable = lib.mkEnableOption ''
|
||||||
|
Visual Studio Code (Microsoft build; needs `nixpkgs.config.allowUnfree`). Core
|
||||||
|
extensions (nix-ide, markdown-all-in-one, prettier) + nixd/nixfmt settings are included.
|
||||||
|
'' // {
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
extensions = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.package;
|
||||||
|
default = [ ];
|
||||||
|
description = ''
|
||||||
|
Extra extensions not wanted on every host (e.g. peacock, comment-anchors,
|
||||||
|
project-manager). Per-host via `chiasson.users.extraModules`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (root.enable && cfg.enable) {
|
||||||
|
home.packages = [ ];
|
||||||
|
|
||||||
|
# Writable, seed-once user settings (kilo-code can append to it).
|
||||||
|
home.file.".config/Code/User/settings.json" = {
|
||||||
|
source = settingsJson;
|
||||||
|
force = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.vscode = {
|
||||||
|
enable = true;
|
||||||
|
package = vscodeWithJdk;
|
||||||
|
extensions = defaultExtensions ++ cfg.extensions;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -8,7 +8,9 @@
|
|||||||
{
|
{
|
||||||
options.chiasson.home.filebrowsers.nemo.enable = lib.mkEnableOption ''
|
options.chiasson.home.filebrowsers.nemo.enable = lib.mkEnableOption ''
|
||||||
Nemo file manager (GTK). Colors come from DMS matugen via GTK settings — no KDE/Qt bridge needed.
|
Nemo file manager (GTK). Colors come from DMS matugen via GTK settings — no KDE/Qt bridge needed.
|
||||||
'';
|
'' // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
config = lib.mkIf (root.enable && cfg.enable) {
|
||||||
home.packages = [ pkgs.nemo ];
|
home.packages = [ pkgs.nemo ];
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
{
|
{
|
||||||
options.chiasson.home.hardware.uconsoleGamepad.enable = lib.mkEnableOption ''
|
options.chiasson.home.hardware.uconsoleGamepad.enable = lib.mkEnableOption ''
|
||||||
uConsole gamepad antimicrox profile + Hyprland exec-once when HM Hyprland is on.
|
uConsole gamepad antimicrox profile + Hyprland exec-once when HM Hyprland is on.
|
||||||
'';
|
'' // {
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) (lib.mkMerge [
|
config = lib.mkIf (root.enable && cfg.enable) (lib.mkMerge [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.home.shell.fish = {
|
options.chiasson.home.shell.fish = {
|
||||||
enable = lib.mkEnableOption "Fish + grc, quiet greeting, rbw SSH socket defaults.";
|
enable = lib.mkEnableOption "Fish + grc, quiet greeting, rbw SSH socket defaults." // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
nixYourShell = {
|
nixYourShell = {
|
||||||
enable = lib.mkEnableOption ''
|
enable = lib.mkEnableOption ''
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.home.shell.ohMyPosh = {
|
options.chiasson.home.shell.ohMyPosh = {
|
||||||
enable = lib.mkEnableOption "[Oh My Posh](https://ohmyposh.dev/) prompt.";
|
enable = lib.mkEnableOption "[Oh My Posh](https://ohmyposh.dev/) prompt." // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
builtinTheme = lib.mkOption {
|
builtinTheme = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
cfg = config.chiasson.home.shell.yazi;
|
cfg = config.chiasson.home.shell.yazi;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.chiasson.home.shell.yazi.enable = lib.mkEnableOption "Yazi as `y` + 7zz with rar.";
|
options.chiasson.home.shell.yazi.enable = lib.mkEnableOption "Yazi as `y` + 7zz with rar." // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
config = lib.mkIf (root.enable && cfg.enable) {
|
||||||
programs.yazi = {
|
programs.yazi = {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
{
|
{
|
||||||
options.chiasson.home.terminals.kitty.enable = lib.mkEnableOption ''
|
options.chiasson.home.terminals.kitty.enable = lib.mkEnableOption ''
|
||||||
Kitty + DMS includes; activation strips `*-theme.auto.conf` so matugen colors stick.
|
Kitty + DMS includes; activation strips `*-theme.auto.conf` so matugen colors stick.
|
||||||
'';
|
'' // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf (root.enable && cfg.enable) {
|
config = lib.mkIf (root.enable && cfg.enable) {
|
||||||
programs.kitty = {
|
programs.kitty = {
|
||||||
|
|||||||
Reference in New Issue
Block a user