refactor(niri): base niri.outputs on config.monitors

This commit is contained in:
Nickolaj Jepsen 2025-08-23 18:42:54 +02:00
parent ba100b98ba
commit 1bed4d5d9f
10 changed files with 133 additions and 119 deletions

View file

@ -1,10 +1,7 @@
{ {
description = "NixOS configuration"; description = "NixOS configuration";
outputs = { outputs = {flake-parts, ...} @ inputs:
flake-parts,
...
} @ inputs:
flake-parts.lib.mkFlake {inherit inputs;} { flake-parts.lib.mkFlake {inherit inputs;} {
imports = [ imports = [
inputs.agenix-rekey.flakeModule inputs.agenix-rekey.flakeModule

View file

@ -1,22 +1,40 @@
_: { _: {
monitors = [ monitors = [
{ {
name = "DP-3"; name = "DP-1";
resolution = "2560x1440"; resolution = {
width = 2560;
height = 1440;
};
refreshRate = 144; refreshRate = 144;
position = "1920x0"; position = {
x = 1920;
y = 0;
};
} }
{ {
name = "DP-1"; name = "DP-3";
resolution = "2560x1440"; resolution = {
width = 2560;
height = 1440;
};
refreshRate = 144; refreshRate = 144;
position = "4480x0"; position = {
x = 4480;
y = 0;
};
} }
{ {
name = "HDMI-A-1"; name = "HDMI-A-1";
resolution = "1920x1080"; resolution = {
width = 1920;
height = 1080;
};
refreshRate = 60; refreshRate = 60;
position = "0x0"; position = {
x = 0;
y = 0;
};
} }
]; ];
} }

View file

@ -1,37 +0,0 @@
_: {
fireproof.home-manager.programs.niri.settings.outputs = {
"DP-3" = {
position = {
x = 1920;
y = 0;
};
mode = {
refresh = 164.998;
width = 2560;
height = 1440;
};
};
"DP-1" = {
position = {
x = 4480;
y = 0;
};
mode = {
refresh = 165.000;
width = 2560;
height = 1440;
};
};
"HDMI-A-1" = {
position = {
x = 0;
y = 0;
};
mode = {
refresh = 60.000;
width = 1920;
height = 1080;
};
};
};
}

View file

@ -2,18 +2,36 @@ _: {
monitors = [ monitors = [
{ {
name = "DP-5"; name = "DP-5";
resolution = "1920x1200"; resolution = {
position = "1920x0"; width = 1920;
height = 1200;
};
position = {
x = 1920;
y = 0;
};
} }
{ {
name = "HDMI-A-5"; name = "HDMI-A-5";
resolution = "1920x1080"; resolution = {
position = "0x0"; width = 1920;
height = 1080;
};
position = {
x = 0;
y = 0;
};
} }
{ {
name = "DP-4"; name = "DP-4";
resolution = "1920x1200"; resolution = {
position = "3840x0"; width = 1920;
height = 1200;
};
position = {
x = 3840;
y = 0;
};
transform = 1; transform = 1;
} }
]; ];

View file

@ -1,23 +0,0 @@
_: {
fireproof.home-manager.programs.niri.settings.outputs = {
"DP-5" = {
position = {
x = 1920;
y = 0;
};
};
"HDMI-A-5" = {
position = {
x = 0;
y = 0;
};
};
"DP-4" = {
position = {
x = 3840;
y = 0;
};
transform.rotation = 90;
};
};
}

View file

@ -101,16 +101,13 @@ in {
else ""; else "";
resolution = resolution =
if m.resolution != null if m.resolution != null
then m.resolution then "${builtins.toString m.resolution.width}x${builtins.toString m.resolution.height}"
else "preferred"; else "preferred";
refreshRate = refreshRate =
if m.refreshRate != null if m.refreshRate != null
then "@${builtins.toString m.refreshRate}" then "@${builtins.toString m.refreshRate}"
else ""; else "";
position = position = "${builtins.toString m.position.x}x${builtins.toString m.position.y}";
if m.position != null
then m.position
else "auto";
transform = transform =
if m.transform != null if m.transform != null
then ", transform, ${builtins.toString m.transform}" then ", transform, ${builtins.toString m.transform}"

View file

@ -1,8 +1,12 @@
{ {
pkgs, pkgs,
inputs, inputs,
config,
lib,
... ...
}: { }: let
primaryMonitorName = (builtins.head config.monitors).name or "";
in {
# TODO: Move these to a separate module # TODO: Move these to a separate module
fireproof.home-manager.programs.waybar = { fireproof.home-manager.programs.waybar = {
enable = true; enable = true;
@ -145,21 +149,21 @@
} }
]; ];
workspaces = { workspaces = lib.mkIf (primaryMonitorName != "") {
"01" = { "01" = {
open-on-output = "DP-5"; open-on-output = primaryMonitorName;
}; };
"02" = { "02" = {
open-on-output = "DP-5"; open-on-output = primaryMonitorName;
}; };
"03" = { "03" = {
open-on-output = "DP-5"; open-on-output = primaryMonitorName;
}; };
"04" = { "04" = {
open-on-output = "DP-5"; open-on-output = primaryMonitorName;
}; };
"05" = { "05" = {
open-on-output = "DP-5"; open-on-output = primaryMonitorName;
}; };
}; };
@ -280,5 +284,25 @@
"Mod+Space".action.spawn = ["fuzzel"]; "Mod+Space".action.spawn = ["fuzzel"];
"Mod+Backspace".action.close-window = {}; "Mod+Backspace".action.close-window = {};
}; };
outputs = lib.mkIf (config.monitors != []) (
lib.listToAttrs (map (monitor: let
refreshRateFloat = lib.mkIf (monitor.refreshRate != null) (builtins.fromJSON "${builtins.toString monitor.refreshRate}.0");
in {
inherit (monitor) name;
value = {
inherit (monitor) position;
mode = {
inherit (monitor.resolution) width height;
refresh = refreshRateFloat;
};
transform.rotation =
if (monitor.transform != null)
then monitor.transform * 90
else 0;
};
})
config.monitors)
);
}; };
} }

View file

@ -1,11 +1,14 @@
{pkgs, lib, ...}: let {
pkgs,
lib,
...
}: let
screenshotPkg = pkgs.writeShellScriptBin "screenshot" '' screenshotPkg = pkgs.writeShellScriptBin "screenshot" ''
AREA=$(${lib.getExe pkgs.slurp} -d) AREA=$(${lib.getExe pkgs.slurp} -d)
${lib.getExe pkgs.grim} -t ppm -g "$AREA" - | ${lib.getExe pkgs.satty} -f - --initial-tool=arrow --copy-command=${pkgs.wl-clipboard}/bin/wl-copy --action-on-enter="save-to-clipboard" --disable-notifications ${lib.getExe pkgs.grim} -t ppm -g "$AREA" - | ${lib.getExe pkgs.satty} -f - --initial-tool=arrow --copy-command=${pkgs.wl-clipboard}/bin/wl-copy --action-on-enter="save-to-clipboard" --disable-notifications
''; '';
in {
in {
environment.systemPackages = [ environment.systemPackages = [
screenshotPkg screenshotPkg
]; ];
} }

View file

@ -1,5 +1,9 @@
# https://github.com/ChangeCaps/nixos-config/tree/0cec356abc0e46ca6ba27b3cf01cd51273bd4a69 # https://github.com/ChangeCaps/nixos-config/tree/0cec356abc0e46ca6ba27b3cf01cd51273bd4a69
{lib, ...}: { {
lib,
config,
...
}: {
options.monitors = lib.mkOption { options.monitors = lib.mkOption {
type = lib.types.listOf (lib.types.submodule { type = lib.types.listOf (lib.types.submodule {
options = { options = {
@ -9,10 +13,13 @@
example = "DP-1"; example = "DP-1";
}; };
resolution = lib.mkOption { resolution.width = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.int;
default = null;
};
resolution.height = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null; default = null;
example = "1920x1080";
}; };
refreshRate = lib.mkOption { refreshRate = lib.mkOption {
@ -21,9 +28,13 @@
example = 60; example = 60;
}; };
position = lib.mkOption { position.x = lib.mkOption {
type = lib.types.str; type = lib.types.int;
default = "0x0"; default = 0;
};
position.y = lib.mkOption {
type = lib.types.int;
default = 0;
}; };
scale = lib.mkOption { scale = lib.mkOption {

View file

@ -1,26 +1,32 @@
{pkgs, config, username, pkgsUnstable, ...}: let {
llmConfig = if pkgs.stdenv.isDarwin then pkgs,
"Library/Application Support/io.datasette.llm" config,
else username,
".config/io.datasette.llm"; pkgsUnstable,
pythonEnv = pkgsUnstable.python3.withPackages (pp: with pp; [ ...
llm }: let
llm-anthropic llmConfig =
llm-gemini if pkgs.stdenv.isDarwin
llm-tools-sqlite then "Library/Application Support/io.datasette.llm"
llm-fragments-github else ".config/io.datasette.llm";
llm-cmd pythonEnv = pkgsUnstable.python3.withPackages (pp:
llm-jq with pp; [
llm-github-copilot llm
llm-git llm-anthropic
]); llm-gemini
llm-tools-sqlite
llm-fragments-github
llm-cmd
llm-jq
llm-github-copilot
llm-git
]);
llmPkgWithPlugins = pkgs.writeShellScriptBin "llm" '' llmPkgWithPlugins = pkgs.writeShellScriptBin "llm" ''
unset PYTHONPATH # Otherwise it breaks in Python devenvs unset PYTHONPATH # Otherwise it breaks in Python devenvs
export $(grep -v '^#' ${config.age.secrets.llm-api-key.path} | xargs) export $(grep -v '^#' ${config.age.secrets.llm-api-key.path} | xargs)
exec ${pythonEnv}/bin/llm "''${@}" exec ${pythonEnv}/bin/llm "''${@}"
''; '';
in in {
{
age.secrets.llm-api-key = { age.secrets.llm-api-key = {
rekeyFile = ../../secrets/llm-api-key.env.age; rekeyFile = ../../secrets/llm-api-key.env.age;
mode = "0600"; mode = "0600";