From a3dd580adc46628dd0c970037b6c87cff1251af5 Mon Sep 17 00:00:00 2001 From: Vincent Gatine Date: Sun, 12 Apr 2020 15:42:43 +0200 Subject: [PATCH] kanshi: add service PR #1142 --- .github/CODEOWNERS | 3 + modules/misc/news.nix | 8 + modules/modules.nix | 1 + modules/services/kanshi.nix | 194 ++++++++++++++++++ tests/default.nix | 1 + .../services/kanshi/basic-configuration.conf | 14 ++ .../services/kanshi/basic-configuration.nix | 51 +++++ tests/modules/services/kanshi/default.nix | 1 + 8 files changed, 273 insertions(+) create mode 100644 modules/services/kanshi.nix create mode 100644 tests/modules/services/kanshi/basic-configuration.conf create mode 100644 tests/modules/services/kanshi/basic-configuration.nix create mode 100644 tests/modules/services/kanshi/default.nix diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3f37aec0..bf1be1a2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -137,6 +137,9 @@ /modules/services/imapnotify.nix @nickhu +/modules/services/kanshi.nix @nurelin +/tests/modules/services/kanshi @nurelin + /modules/services/kdeconnect.nix @adisbladis /modules/services/keepassx.nix @rycee diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 4ec6fc2d..94ce35bd 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1627,6 +1627,14 @@ in A new module is available: 'programs.waybar' ''; } + + { + time = "2020-08-14T22:44:20+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.kanshi' + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 41877c5e..1744b4fd 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -140,6 +140,7 @@ let (loadModule ./services/grobi.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/hound.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; }) + (loadModule ./services/kanshi.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/kbfs.nix { }) (loadModule ./services/kdeconnect.nix { }) (loadModule ./services/keepassx.nix { }) diff --git a/modules/services/kanshi.nix b/modules/services/kanshi.nix new file mode 100644 index 00000000..e54b83aa --- /dev/null +++ b/modules/services/kanshi.nix @@ -0,0 +1,194 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.kanshi; + + outputModule = types.submodule { + options = { + + criteria = mkOption { + type = types.str; + description = '' + The criteria can either be an output name, an output description or "*". + The latter can be used to match any output. + + On + + sway + 1 + , + output names and descriptions can be obtained via + swaymsg -t get_outputs. + ''; + }; + + status = mkOption { + type = types.nullOr (types.enum [ "enable" "disable" ]); + default = null; + description = '' + Enables or disables the specified output. + ''; + }; + + mode = mkOption { + type = types.nullOr types.str; + default = null; + example = "1920x1080@60Hz"; + description = '' + <width>x<height>[@<rate>[Hz]] + + Configures the specified output to use the specified mode. + Modes are a combination of width and height (in pixels) and + a refresh rate (in Hz) that your display can be configured to use. + ''; + }; + + position = mkOption { + type = types.nullOr types.str; + default = null; + example = "1600,0"; + description = '' + <x>,<y> + + Places the output at the specified position in the global coordinates + space. + ''; + }; + + scale = mkOption { + type = types.nullOr types.float; + default = null; + example = 2; + description = '' + Scales the output by the specified scale factor. + ''; + }; + + transform = mkOption { + type = types.nullOr (types.enum [ + "normal" + "90" + "180" + "270" + "flipped" + "flipped-90" + "flipped-180" + "flipped-270" + ]); + default = null; + description = '' + Sets the output transform. + ''; + }; + }; + }; + + outputStr = { criteria, status, mode, position, scale, transform, ... }: + ''output "${criteria}"'' + optionalString (status != null) " ${status}" + + optionalString (mode != null) " mode ${mode}" + + optionalString (position != null) " position ${position}" + + optionalString (scale != null) " scale ${toString scale}" + + optionalString (transform != null) " transform ${transform}"; + + profileModule = types.submodule { + options = { + outputs = mkOption { + type = types.listOf outputModule; + default = [ ]; + description = '' + Outputs configuration. + ''; + }; + + exec = mkOption { + type = types.nullOr types.str; + default = null; + example = + "\${pkg.sway}/bin/swaymsg workspace 1, move workspace to eDP-1"; + description = '' + Command executed after the profile is succesfully applied. + ''; + }; + }; + }; + + profileStr = name: + { outputs, exec, ... }: + '' + profile ${name} { + ${concatStringsSep "\n " (map outputStr outputs)} + '' + optionalString (exec != null) " ${exec}" + '' + } + ''; +in { + + meta.maintainers = [ maintainers.nurelin ]; + + options.services.kanshi = { + enable = mkEnableOption + "kanshi, a Wayland daemon that automatically configures outputs"; + + package = mkOption { + type = types.package; + default = pkgs.kanshi; + defaultText = literalExample "pkgs.kanshi"; + description = '' + kanshi derivation to use. + ''; + }; + + profiles = mkOption { + type = types.attrsOf profileModule; + default = { }; + description = '' + List of profiles. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration lines to append to the kanshi + configuration file. + ''; + }; + + systemdTarget = mkOption { + type = types.str; + default = "sway-session.target"; + description = '' + Systemd target to bind to. + ''; + }; + }; + + config = mkIf cfg.enable { + + xdg.configFile."kanshi/config".text = '' + ${concatStringsSep "\n" (mapAttrsToList profileStr cfg.profiles)} + ${cfg.extraConfig} + ''; + + systemd.user.services.kanshi = { + Unit = { + Description = "Dynamic output configuration"; + Documentation = "man:kanshi(1)"; + PartOf = cfg.systemdTarget; + Requires = cfg.systemdTarget; + After = cfg.systemdTarget; + }; + + Service = { + Type = "simple"; + ExecStart = "${cfg.package}/bin/kanshi"; + Restart = "always"; + }; + + Install = { WantedBy = [ cfg.systemdTarget ]; }; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 939a50e2..3aa0c544 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -83,6 +83,7 @@ import nmt { ./modules/services/lieer ./modules/programs/rofi ./modules/programs/waybar + ./modules/services/kanshi ./modules/services/polybar ./modules/services/sxhkd ./modules/services/fluidsynth diff --git a/tests/modules/services/kanshi/basic-configuration.conf b/tests/modules/services/kanshi/basic-configuration.conf new file mode 100644 index 00000000..905a539d --- /dev/null +++ b/tests/modules/services/kanshi/basic-configuration.conf @@ -0,0 +1,14 @@ +profile desktop { + output "eDP-1" disable + output "Iiyama North America PLE2483H-DP" enable position 0,0 + output "Iiyama North America PLE2483H-DP 1158765348486" enable mode 1920x1080 position 1920,0 scale 2.100000 transform flipped-270 +} + +profile nomad { + output "eDP-1" enable +} + +profile test { + output "*" enable +} + diff --git a/tests/modules/services/kanshi/basic-configuration.nix b/tests/modules/services/kanshi/basic-configuration.nix new file mode 100644 index 00000000..08a2c167 --- /dev/null +++ b/tests/modules/services/kanshi/basic-configuration.nix @@ -0,0 +1,51 @@ +{ config, pkgs, ... }: { + config = { + services.kanshi = { + enable = true; + package = pkgs.writeScriptBin "dummy-kanshi" ""; + profiles = { + nomad = { + outputs = [{ + criteria = "eDP-1"; + status = "enable"; + }]; + }; + desktop = { + outputs = [ + { + criteria = "eDP-1"; + status = "disable"; + } + { + criteria = "Iiyama North America PLE2483H-DP"; + status = "enable"; + position = "0,0"; + } + { + criteria = "Iiyama North America PLE2483H-DP 1158765348486"; + status = "enable"; + position = "1920,0"; + scale = 2.1; + mode = "1920x1080"; + transform = "flipped-270"; + } + ]; + }; + }; + extraConfig = '' + profile test { + output "*" enable + } + ''; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/kanshi.service + assertFileExists $serviceFile + + assertFileExists home-files/.config/kanshi/config + assertFileContent home-files/.config/kanshi/config \ + ${./basic-configuration.conf} + ''; + }; +} diff --git a/tests/modules/services/kanshi/default.nix b/tests/modules/services/kanshi/default.nix new file mode 100644 index 00000000..cb6b2a6b --- /dev/null +++ b/tests/modules/services/kanshi/default.nix @@ -0,0 +1 @@ +{ kanshi-basic-configuration = ./basic-configuration.nix; }