From 7ef533e8d1fb6ece563232b326fc5b5d5c2f9257 Mon Sep 17 00:00:00 2001 From: cmacrae Date: Wed, 6 May 2020 17:21:46 +0100 Subject: [PATCH] module: add yabai service --- modules/module-list.nix | 1 + modules/services/yabai/default.nix | 103 +++++++++++++++++++++++++++++ release.nix | 1 + tests/services-yabai.nix | 27 ++++++++ 4 files changed, 132 insertions(+) create mode 100644 modules/services/yabai/default.nix create mode 100644 tests/services-yabai.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index ae5cf69..bbe8e67 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -53,6 +53,7 @@ ./services/skhd ./services/synapse-bt.nix ./services/synergy + ./services/yabai ./programs/bash ./programs/fish.nix ./programs/gnupg.nix diff --git a/modules/services/yabai/default.nix b/modules/services/yabai/default.nix new file mode 100644 index 0000000..9318ff9 --- /dev/null +++ b/modules/services/yabai/default.nix @@ -0,0 +1,103 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.yabai; + + toYabaiConfig = opts: + concatStringsSep "\n" (mapAttrsToList + (p: v: "yabai -m config ${p} ${toString v}") opts); + + configFile = mkIf (cfg.config != {} || cfg.extraConfig != "") + "${pkgs.writeScript "yabairc" ( + (if (cfg.config != {}) + then "${toYabaiConfig cfg.config}" + else "") + + optionalString (cfg.extraConfig != "") cfg.extraConfig)}"; +in + +{ + options = with types; { + services.yabai.enable = mkOption { + type = bool; + default = false; + description = "Whether to enable the yabai window manager."; + }; + + services.yabai.package = mkOption { + type = path; + description = "The yabai package to use."; + }; + + services.yabai.enableScriptingAddition = mkOption { + type = bool; + default = false; + description = '' + Whether to enable yabai's scripting-addition. + SIP must be disabled for this to work. + ''; + }; + + services.yabai.config = mkOption { + type = attrs; + default = {}; + example = literalExample '' + { + focus_follows_mouse = "autoraise"; + mouse_follows_focus = "off"; + window_placement = "second_child"; + window_opacity = "off"; + top_padding = 36; + bottom_padding = 10; + left_padding = 10; + right_padding = 10; + window_gap = 10; + } + ''; + description = '' + Key/Value pairs to pass to yabai's 'config' domain, via the configuration file. + ''; + }; + + services.yabai.extraConfig = mkOption { + type = str; + default = ""; + example = literalExample '' + yabai -m rule --add app='System Preferences' manage=off + ''; + description = "Extra arbitrary configuration to append to the configuration file"; + }; + }; + + config = mkMerge [ + (mkIf (cfg.enable) { + environment.systemPackages = [ cfg.package ]; + + launchd.user.agents.yabai = { + serviceConfig.ProgramArguments = [ "${cfg.package}/bin/yabai" ] + ++ optionals (cfg.config != {} || cfg.extraConfig != "") [ "-c" configFile ]; + + serviceConfig.KeepAlive = true; + serviceConfig.RunAtLoad = true; + serviceConfig.EnvironmentVariables = { + PATH = "${cfg.package}/bin:${config.environment.systemPath}"; + }; + }; + }) + + # TODO: [@cmacrae] Handle removal of yabai scripting additions + (mkIf (cfg.enableScriptingAddition) { + launchd.daemons.yabai-sa = { + script = '' + if [ ! $(${cfg.package}/bin/yabai --check-sa) ]; then + ${cfg.package}/bin/yabai --install-sa + fi + ''; + + serviceConfig.RunAtLoad = true; + serviceConfig.KeepAlive.SuccessfulExit = false; + }; + }) + ]; +} diff --git a/release.nix b/release.nix index 9ffa6c3..4f006ac 100644 --- a/release.nix +++ b/release.nix @@ -123,6 +123,7 @@ let tests.services-skhd = makeTest ./tests/services-skhd.nix; tests.services-synapse-bt = makeTest ./tests/services-synapse-bt.nix; tests.services-synergy = makeTest ./tests/services-synergy.nix; + tests.services-yabai = makeTest ./tests/services-yabai.nix; tests.system-defaults-write = makeTest ./tests/system-defaults-write.nix; tests.system-environment = makeTest ./tests/system-environment.nix; tests.system-keyboard-mapping = makeTest ./tests/system-keyboard-mapping.nix; diff --git a/tests/services-yabai.nix b/tests/services-yabai.nix new file mode 100644 index 0000000..876ba38 --- /dev/null +++ b/tests/services-yabai.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + yabai = pkgs.runCommand "yabai-0.0.0" {} "mkdir $out"; +in + +{ + services.yabai.enable = true; + services.yabai.package = yabai; + services.yabai.config = { focus_follows_mouse = "autoraise"; }; + services.yabai.extraConfig = "yabai -m rule --add app='System Preferences' manage=off"; + + test = '' + echo >&2 "checking yabai service in ~/Library/LaunchAgents" + grep "org.nixos.yabai" ${config.out}/user/Library/LaunchAgents/org.nixos.yabai.plist + grep "${yabai}/bin/yabai" ${config.out}/user/Library/LaunchAgents/org.nixos.yabai.plist + + conf=`sed -En '/-c<\/string>/{n; s/\s+?<\/?string>//g; p;}' \ + ${config.out}/user/Library/LaunchAgents/org.nixos.yabai.plist` + + echo >&2 "checking config in $conf" + grep "yabai -m config focus_follows_mouse autoraise" $conf + grep "yabai -m rule --add app='System Preferences' manage=off" $conf + ''; +}