Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

services/yabai: cleanup and add errorLogFile/outLogFile #1231

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 68 additions & 41 deletions modules/services/yabai/default.nix
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
{ config, lib, pkgs, ... }:

with lib;

{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkOption types;

cfg = config.services.yabai;

toYabaiConfig = opts:
concatStringsSep "\n" (mapAttrsToList
(p: v: "yabai -m config ${p} ${toString v}")
opts);
toYabaiConfig =
opts:
lib.concatStringsSep "\n" (lib.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 != "") ("\n" + cfg.extraConfig + "\n"))}";
configFile =
lib.mkIf (cfg.config != { } || cfg.extraConfig != "")
"${pkgs.writeScript "yabairc" (
(if (cfg.config != { }) then "${toYabaiConfig cfg.config}" else "")
+ lib.optionalString (cfg.extraConfig != "") ("\n" + cfg.extraConfig + "\n")
)}";
in

{
options = with types; {
services.yabai.enable = mkOption {
type = bool;
options.services.yabai = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the yabai window manager.";
};

services.yabai.package = mkOption {
type = path;
package = mkOption {
type = types.path;
default = pkgs.yabai;
description = "The yabai package to use.";
};

services.yabai.enableScriptingAddition = mkOption {
type = bool;
enableScriptingAddition = mkOption {
type = types.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;
config = mkOption {
type = types.attrs;
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
focus_follows_mouse = "autoraise";
mouse_follows_focus = "off";
Expand All @@ -62,41 +64,66 @@ in
'';
};

services.yabai.extraConfig = mkOption {
type = lines;
extraConfig = mkOption {
type = types.lines;
default = "";
example = literalExpression ''
example = lib.literalExpression ''
yabai -m rule --add app='System Preferences' manage=off
'';
description = "Extra arbitrary configuration to append to the configuration file";
};

errorLogFile = mkOption {
type = types.path;
default = "/var/tmp/yabai.error.log";
example = "/Users/khaneliman/Library/Logs/yabai.log";
description = "Path to the yabai error log file";
};

outLogFile = mkOption {
type = types.path;
default = "/var/tmp/yabai.out.log";
example = "/Users/khaneliman/Library/Logs/yabai.log";
description = "Path to the yabai stdout log file";
};
Comment on lines +76 to +88
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you picked /var/tmp over /tmp or /var/log? Upstream just puts them in /tmp, but /var/log (like you did for the scripting additions) also makes sense to me

Copy link
Contributor Author

@khaneliman khaneliman Dec 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User agents dont have access to /var/log but the global daemon does. It would probably be nice to use ~/Library/Logs/ but I believe I couldn't use ~ when testing before.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. What about /tmp instead of /var/tmp? I don't really care either way, I've just never seen /var/tmp used before and didn't actually know that existed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/tmp could be purged on reboots, /var/tmp wouldn't be. So depends on what you think the default behavior should be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack sorry something is up with my notifications so I missed this. My personal preference is /tmp because it's what upstream appears to use, I think it's more visible, and I think it's fine if these logs don't persist across a reboot.

That said, I don't have permissions to merge this, so we could leave it up to @Enzime

};

config = mkMerge [
(mkIf (cfg.enable) {
config = lib.mkMerge [
(lib.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}";
serviceConfig = {
ProgramArguments =
[ "${cfg.package}/bin/yabai" ]
++ lib.optionals (cfg.config != { } || cfg.extraConfig != "") [
"-c"
configFile
];
KeepAlive = true;
RunAtLoad = true;
EnvironmentVariables = {
PATH = "${cfg.package}/bin:${config.environment.systemPath}";
};
StandardOutPath = cfg.outLogFile;
StandardErrorPath = cfg.errorLogFile;
};
};
})

# TODO: [@cmacrae] Handle removal of yabai scripting additions
(mkIf (cfg.enableScriptingAddition) {
(lib.mkIf (cfg.enableScriptingAddition) {
launchd.daemons.yabai-sa = {
script = "${cfg.package}/bin/yabai --load-sa";
serviceConfig.RunAtLoad = true;
serviceConfig.KeepAlive.SuccessfulExit = false;
serviceConfig = {
RunAtLoad = true;
KeepAlive.SuccessfulExit = false;
StandardOutPath = "/var/log/yabai-sa.out.log";
StandardErrorPath = "/var/log/yabai-sa.err.log";
khaneliman marked this conversation as resolved.
Show resolved Hide resolved
};
};

environment.etc."sudoers.d/yabai".source = pkgs.runCommand "sudoers-yabai" {} ''
environment.etc."sudoers.d/yabai".source = pkgs.runCommand "sudoers-yabai" { } ''
YABAI_BIN="${cfg.package}/bin/yabai"
SHASUM=$(sha256sum "$YABAI_BIN" | cut -d' ' -f1)
cat <<EOF >"$out"
Expand Down