.files/nix/configurations/vanadium/nixos/display.nix
Léana 江 ebf8468807
tree-wide: format with nixfmt
Another saturday another useless formatter change.
It's my dotfiles, after all

alejandra doesn't handle c-style inline comments well.
2025-11-08 10:15:58 +08:00

195 lines
6.7 KiB
Nix

{
pkgs,
lib,
...
}:
{
imports = [
#
# builtin screen
#
{
me.extraGroups = [ "video" ];
programs.light.enable = true;
}
#
# external screen
#
{
me.extraGroups = [ "i2c" ];
hardware.i2c.enable = true;
environment.systemPackages = [ pkgs.ddcutil ];
boot.kernelModules = [ "i2c-dev" ];
}
];
#
# Auto setup external screen
#
services.autorandr = {
enable = true;
hooks.postswitch = {
"10_xmobar" = "${lib.getExe' pkgs.toybox "pkill"} xmobar"; # make sure there are no duplicated xmobar
"20_xmonad" = "${lib.getExe pkgs.haskellPackages.xmonad} --restart"; # make sure feh keeps up
};
profiles =
let
singleton = k: v: { ${k} = v; };
fingerprints = {
built-in = singleton "eDP-1" "00ffffffffffff0009e5ca0b000000002f200104a51c137803de50a3544c99260f505400000001010101010101010101010101010101115cd01881e02d50302036001dbe1000001aa749d01881e02d50302036001dbe1000001a000000fe00424f452043510a202020202020000000fe004e4531333546424d2d4e34310a0073";
amethyst =
device:
singleton device "00ffffffffffff0006b35b27010101012c210103803c22782a29d5ad4f44a7240f5054bfef00714f81809500d1c0d1e8d1fc01010101565e00a0a0a029503020350055502100001a000000fd0030901edf3c000a202020202020000000fc005647323741514c33410a202020000000ff0052414c4d51533139373533370a0111020347f14a90030204014061603f1f230907078301000067030c002000384468d85dc401788003026d1a000002013090f00069096909e305ff01e6060701696900e2006ae20fc0eae70070a0a067500820980455502100001a6fc200a0a0a055503020350055502100001a5aa000a0a0a046503020350055502100001a0000bc";
orchid =
device:
singleton device "00ffffffffffff0004699a24642900002416010380341d782a2ac5a4564f9e280f5054b7ef00714f814081809500b300d1c081c08100023a801871382d40582c450009252100001e000000ff0043394c4d54463031303539360a000000fd00324b185311000a202020202020000000fc00415355532056533234370a20200173020322714f0102031112130414050e0f1d1e1f10230917078301000065030c0010008c0ad08a20e02d10103e9600092521000018011d007251d01e206e28550009252100001e011d00bc52d01e20b828554009252100001e8c0ad090204031200c4055000925210000180000000000000000000000000000000000000000005d";
};
devices = rec {
built-in = "eDP-1";
# Run `xrandr` to see the max number
extern = map (portNumber: "DP-${toString portNumber}") (lib.range 1 8);
all = [ built-in ] ++ extern;
};
switches = {
setDPI =
{ dpi }:
singleton "10_xrdb-dpi" "${lib.getExe pkgs.xorg.xrdb} -merge ${pkgs.writeText "xrdb-dpi-config" ''
Xcursor.size: 64
Xft.dpi: ${toString dpi}
''}";
# Is scoped to an output device, no need to be called on built-in display
setSoftwareBrightness =
{
device, # obtain with `xrandr`
brightness, # [0..1]
}:
singleton "10_xrandr_brightness" ''
${lib.getExe pkgs.xorg.xrandr} --output ${device} --brightness ${toString brightness}
'';
# Is scoped to an output device, no need to be called on built-in display
setDDCBrightness =
{
modelName, # obtain with `ddcutil detect`
brightness, # [0..1]
}:
singleton "10_ddc_brightness" ''
${lib.getExe pkgs.ddcutil} --model ${modelName} setvcp 10 ${
toString (builtins.floor (brightness * 100))
}
'';
setDDCContrast =
{
modelName, # obtain with `ddcutil detect`
contrast, # [0..1]
}:
singleton "10_ddc_contrast" ''
${lib.getExe pkgs.ddcutil} --model ${modelName} setvcp 12 ${
toString (builtins.floor (contrast * 100))
}
'';
};
# Note: the "position" field corresponds to the "pos" field outputted by autorandr
# To get the current config, run `xrandr --auto` and then `autorandr --config`
configs = {
allOff = lib.genAttrs devices.all (_: {
enable = lib.mkDefault false;
});
enableBuiltin = {
eDP-1 = {
enable = true;
crtc = 0;
mode = "2256x1504";
rate = "60.00";
primary = true;
};
};
enableAmethyst = name: {
${name} = {
enable = true;
primary = true;
crtc = 1;
mode = "2560x1440";
rate = "59.95";
};
};
enableOrchid = name: {
${name} = {
enable = true;
primary = true;
crtc = 1;
mode = "1920x1080";
rate = "60.00";
};
};
};
frameworkBuiltin = {
fingerprint = fingerprints.built-in;
config = lib.mkMerge [
configs.allOff
configs.enableBuiltin
];
hooks.postswitch = switches.setDPI { dpi = 150; };
};
mkAmethyst = name: {
fingerprint = lib.mkMerge [
fingerprints.built-in
(fingerprints.amethyst name)
];
config = lib.mkMerge [
configs.allOff
(configs.enableAmethyst name)
];
hooks.postswitch = lib.mkMerge [
(switches.setDPI { dpi = 110; })
(switches.setSoftwareBrightness {
device = name;
brightness = 1;
})
(switches.setDDCBrightness {
modelName = "VG27AQL3A";
brightness = 0;
})
(switches.setDDCContrast {
modelName = "VG27AQL3A";
contrast = 0.5;
})
];
};
mkOrchid = name: {
fingerprint = lib.mkMerge [
fingerprints.built-in
(fingerprints.orchid name)
];
config = lib.mkMerge [
configs.allOff
(configs.enableOrchid name)
];
# seems like this display doesn't support DDC
hooks.postswitch = lib.mkMerge [
(switches.setDPI { dpi = 100; })
(switches.setSoftwareBrightness {
device = name;
brightness = 0.5;
})
];
};
in
lib.mkMerge [
{ default = frameworkBuiltin; }
(lib.genAttrs' devices.extern (name: lib.nameValuePair "amethyst-${name}" (mkAmethyst name)))
(lib.genAttrs' devices.extern (name: lib.nameValuePair "orchid-${name}" (mkOrchid name)))
];
};
}