diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9ffb82ed..6526b820 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -87,6 +87,9 @@ /modules/programs/foot.nix @plabadens /tests/modules/programs/foot @plabadens +/modules/services/fusuma.nix @iosmanthus +/tests/modules/services/fusuma @iosmanthus + /modules/programs/gh.nix @Gerschtli @berbiche /tests/modules/programs/gh @Gerschtli @berbiche diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 37486e84..6986f2ec 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -61,6 +61,12 @@ github = "olmokramer"; githubId = 3612514; }; + iosmanthus = { + name = "iosmanthus"; + email = "myosmanthustree@gmail.com"; + github = "iosmanthus"; + githubId = 16307070; + }; kalhauge = { name = "Christian Gram Kalhauge"; email = "kalhauge@users.noreply.github.com"; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index d45b2c32..44b09f01 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -2456,6 +2456,14 @@ in A new module is available: 'programs.pubs'. ''; } + + { + time = "2022-03-13T20:59:38+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.fusuma'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index ff8fd622..81b75db4 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -187,6 +187,7 @@ let ./services/flameshot.nix ./services/fluidsynth.nix ./services/fnott.nix + ./services/fusuma.nix ./services/getmail.nix ./services/git-sync.nix ./services/gnome-keyring.nix diff --git a/modules/services/fusuma.nix b/modules/services/fusuma.nix new file mode 100644 index 00000000..3a853b51 --- /dev/null +++ b/modules/services/fusuma.nix @@ -0,0 +1,138 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.fusuma; + + yamlFormat = pkgs.formats.yaml { }; + + configJson = pkgs.writeText "config.json" (builtins.toJSON cfg.settings); + + configYamlRaw = pkgs.runCommand "config.yaml.raw" { } '' + ${pkgs.remarshal}/bin/json2yaml -i ${configJson} -o $out; + ''; + + # convert keys into literal numbers where necessary, + # fusuma does not support string type finger count. + strToInt = pkgs.writers.writePython3 "str2int" { + libraries = [ pkgs.python3Packages.pyyaml ]; + } '' + import yaml + from yaml import FullLoader + + + def str2int(config): + if type(config) is not dict: + return + + for key in list(config): + if type(config[key]) is dict and key.isdigit(): + t = config[key] + del config[key] + config[int(key)] = t + else: + str2int(config[key]) + + + if __name__ == '__main__': + path = "${configYamlRaw}" + with open(path) as f: + config = yaml.load(f, Loader=FullLoader) + str2int(config) + print(yaml.dump(config)) + ''; + + configYaml = pkgs.stdenv.mkDerivation { + name = "config.yaml"; + buildCommand = '' + ${strToInt} > $out + ''; + }; + + makeBinPath = packages: + foldl (a: b: if a == "" then b else "${a}:${b}") "" + (map (pkg: "${pkg}/bin") packages); + +in { + meta.maintainers = [ hm.maintainers.iosmanthus ]; + + options.services.fusuma = { + enable = mkEnableOption + "the fusuma systemd service to automatically enable touchpad gesture"; + + package = mkOption { + type = types.package; + default = pkgs.fusuma; + defaultText = literalExpression "pkgs.fusuma"; + description = "Package providing fusuma."; + }; + + settings = mkOption { + type = yamlFormat.type; + example = literalExpression '' + { + enable = true; + extraPackages = with pkgs;[ xdotool ]; + config = { + threshold = { + swipe = 0.1; + }; + interval = { + swipe = 0.7; + }; + swipe = { + "3" = { + left = { + # GNOME: Switch to left workspace + command = "xdotool key ctrl+alt+Right"; + }; + }; + }; + }; + }; + ''; + description = '' + YAML config that will override the default fusuma configuration. + ''; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = with pkgs; [ coreutils ]; + defaultText = literalExpression "pkgs.coreutils"; + example = literalExpression '' + with pkgs; [ coreutils xdotool ]; + ''; + description = '' + Extra packages needs to bring to the scope of fusuma service. + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.fusuma" pkgs + lib.platforms.linux) + ]; + + xdg.configFile."fusuma/config.yaml".source = configYaml; + + systemd.user.services.fusuma = { + Unit = { + Description = "Fusuma services"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Environment = with pkgs; "PATH=${makeBinPath cfg.extraPackages}"; + ExecStart = + "${cfg.package}/bin/fusuma -c ${config.xdg.configHome}/fusuma/config.yaml"; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index c3bd09f7..a6acb8e2 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -144,6 +144,7 @@ import nmt { ./modules/services/flameshot ./modules/services/fluidsynth ./modules/services/fnott + ./modules/services/fusuma ./modules/services/git-sync ./modules/services/gpg-agent ./modules/services/gromit-mpx diff --git a/tests/modules/services/fusuma/default.nix b/tests/modules/services/fusuma/default.nix new file mode 100644 index 00000000..74024b8b --- /dev/null +++ b/tests/modules/services/fusuma/default.nix @@ -0,0 +1,4 @@ +{ + fusuma-example-settings = ./settings.nix; + fusuma-systemd-user-service = ./service.nix; +} diff --git a/tests/modules/services/fusuma/expected-service.service b/tests/modules/services/fusuma/expected-service.service new file mode 100644 index 00000000..a86627f4 --- /dev/null +++ b/tests/modules/services/fusuma/expected-service.service @@ -0,0 +1,11 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +Environment=PATH=@coreutils@/bin:@xdotool@/bin +ExecStart=@fusuma@/bin/fusuma -c /home/hm-user/.config/fusuma/config.yaml + +[Unit] +After=graphical-session-pre.target +Description=Fusuma services +PartOf=graphical-session.target diff --git a/tests/modules/services/fusuma/expected-settings.yaml b/tests/modules/services/fusuma/expected-settings.yaml new file mode 100644 index 00000000..b02be48a --- /dev/null +++ b/tests/modules/services/fusuma/expected-settings.yaml @@ -0,0 +1,12 @@ +interval: + swipe: 7 +swipe: + 3: + left: + command: xdotool key ctrl+alt+Right + 4: + left: + command: xdotool key ctrl+shift+alt+Right +threshold: + swipe: 1 + diff --git a/tests/modules/services/fusuma/service.nix b/tests/modules/services/fusuma/service.nix new file mode 100644 index 00000000..d02a75f5 --- /dev/null +++ b/tests/modules/services/fusuma/service.nix @@ -0,0 +1,19 @@ +{ config, ... }: + +{ + services.fusuma = { + enable = true; + package = config.lib.test.mkStubPackage { outPath = "@fusuma@"; }; + extraPackages = [ + (config.lib.test.mkStubPackage { outPath = "@coreutils@"; }) + (config.lib.test.mkStubPackage { outPath = "@xdotool@"; }) + ]; + settings = { }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/systemd/user/fusuma.service \ + ${./expected-service.service} + ''; +} diff --git a/tests/modules/services/fusuma/settings.nix b/tests/modules/services/fusuma/settings.nix new file mode 100644 index 00000000..18fb34b3 --- /dev/null +++ b/tests/modules/services/fusuma/settings.nix @@ -0,0 +1,23 @@ +{ config, ... }: + +{ + services.fusuma = { + enable = true; + extraPackages = [ (config.lib.test.mkStubPackage { }) ]; + + settings = { + threshold = { swipe = 1; }; + interval = { swipe = 7; }; + swipe = { + "3" = { left = { command = "xdotool key ctrl+alt+Right"; }; }; + "4" = { left = { command = "xdotool key ctrl+shift+alt+Right"; }; }; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/fusuma/config.yaml \ + ${./expected-settings.yaml} + ''; +}