{ 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" = "pkill xmobar"; # make sure there are no duplicated xmobar "20_xmonad" = "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" "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" '' 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" '' ddcutil --model ${modelName} setvcp 10 ${toString (builtins.floor (brightness * 100))} ''; setDDCContrast = { modelName, # obtain with `ddcutil detect` contrast, # [0..1] }: singleton "10_ddc_contrast" '' 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) ]; hooks.postswitch = lib.mkMerge [ (switches.setDPI {dpi = 100;}) (switches.setSoftwareBrightness { device = name; brightness = 1; }) # # seems like this display doesn't support DDC # (switches.setDDCBrightness { # modelName = "VG27AQL3A"; # brightness = 0; # }) # (switches.setDDCContrast { # modelName = "VG27AQL3A"; # contrast = 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))) ]; }; }