mirror of
https://github.com/LnL7/nix-darwin.git
synced 2025-03-06 08:47:00 +00:00
trying to fix #1142 testing requested changes adding workspace to monitor force assignment remove formatting tests pass proper tests undo formatting tests for on-window-detected and workspace-to-monitor-force-assignment testing submodules cleanup n if fiz checking final toml null field aerospace callback issue custom null filter for submodule list check for no presense of window-regex and if.workspace config check aerospace: add workspace-to-monitor-force-assignment option and fix on-window-detected type #1208 trying to fix #1142 testing requested changes adding workspace to monitor force assignment remove formatting tests pass proper tests undo formatting tests for on-window-detected and workspace-to-monitor-force-assignment testing submodules cleanup n if fiz checking final toml null field aerospace callback issue custom null filter for submodule list check for no presense of window-regex and if.workspace config check error formatting mishap space left small fix formatting mishaps
259 lines
9.3 KiB
Nix
259 lines
9.3 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.aerospace;
|
|
|
|
format = pkgs.formats.toml { };
|
|
filterAttrsRecursive = pred: set:
|
|
lib.listToAttrs (
|
|
lib.concatMap (
|
|
name: let
|
|
v = set.${name};
|
|
in
|
|
if pred v
|
|
then [
|
|
(lib.nameValuePair name (
|
|
if lib.isAttrs v
|
|
then filterAttrsRecursive pred v
|
|
else if lib.isList v
|
|
then
|
|
(map (i:
|
|
if lib.isAttrs i
|
|
then filterAttrsRecursive pred i
|
|
else i) (lib.filter pred v))
|
|
else v
|
|
))
|
|
]
|
|
else []
|
|
) (lib.attrNames set)
|
|
);
|
|
filterNulls = filterAttrsRecursive (v: v != null);
|
|
configFile = format.generate "aerospace.toml" (filterNulls cfg.settings);
|
|
in
|
|
|
|
{
|
|
options = {
|
|
services.aerospace = with lib.types; {
|
|
enable = lib.mkEnableOption "AeroSpace window manager";
|
|
|
|
package = lib.mkPackageOption pkgs "aerospace" { };
|
|
|
|
settings = lib.mkOption {
|
|
type = submodule {
|
|
freeformType = format.type;
|
|
options = {
|
|
start-at-login = lib.mkOption {
|
|
type = bool;
|
|
default = false;
|
|
description = "Do not start AeroSpace at login. (Managed by launchd instead)";
|
|
};
|
|
after-login-command = lib.mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
description = "Do not use AeroSpace to run commands after login. (Managed by launchd instead)";
|
|
};
|
|
after-startup-command = lib.mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
description = "Add commands that run after AeroSpace startup";
|
|
example = [ "layout tiles" ];
|
|
};
|
|
enable-normalization-flatten-containers = lib.mkOption {
|
|
type = bool;
|
|
default = true;
|
|
description = "Containers that have only one child are \"flattened\".";
|
|
};
|
|
enable-normalization-opposite-orientation-for-nested-containers = lib.mkOption {
|
|
type = bool;
|
|
default = true;
|
|
description = "Containers that nest into each other must have opposite orientations.";
|
|
};
|
|
accordion-padding = lib.mkOption {
|
|
type = int;
|
|
default = 30;
|
|
description = "Padding between windows in an accordion container.";
|
|
};
|
|
default-root-container-layout = lib.mkOption {
|
|
type = enum [
|
|
"tiles"
|
|
"accordion"
|
|
];
|
|
default = "tiles";
|
|
description = "Default layout for the root container.";
|
|
};
|
|
default-root-container-orientation = lib.mkOption {
|
|
type = enum [
|
|
"horizontal"
|
|
"vertical"
|
|
"auto"
|
|
];
|
|
default = "auto";
|
|
description = "Default orientation for the root container.";
|
|
};
|
|
on-window-detected = lib.mkOption {
|
|
type = listOf (submodule {
|
|
options = {
|
|
"if" = lib.mkOption {
|
|
type = submodule {
|
|
options = {
|
|
app-id = lib.mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
description = "The application ID to match (optional).";
|
|
};
|
|
workspace = lib.mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
description = "The workspace name to match (optional).";
|
|
};
|
|
window-title-regex-substring = lib.mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
description = "Substring to match in the window title (optional).";
|
|
};
|
|
app-name-regex-substring = lib.mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
description = "Regex substring to match the app name (optional).";
|
|
};
|
|
during-aerospace-startup = lib.mkOption {
|
|
type = nullOr bool;
|
|
default = null;
|
|
description = "Whether to match during aerospace startup (optional).";
|
|
};
|
|
};
|
|
};
|
|
default = { };
|
|
description = "Conditions for detecting a window.";
|
|
};
|
|
check-further-callbacks = lib.mkOption {
|
|
type = nullOr bool;
|
|
default = null;
|
|
description = "Whether to check further callbacks after this rule (optional).";
|
|
};
|
|
run = lib.mkOption {
|
|
type = oneOf [str (listOf str)];
|
|
example = ["move-node-to-workspace m" "resize-node"];
|
|
description = "Commands to execute when the conditions match (required).";
|
|
};
|
|
};
|
|
});
|
|
default = [ ];
|
|
example = [
|
|
{
|
|
"if" = {
|
|
app-id = "Another.Cool.App";
|
|
workspace = "cool-workspace";
|
|
window-title-regex-substring = "Title";
|
|
app-name-regex-substring = "CoolApp";
|
|
during-aerospace-startup = false;
|
|
};
|
|
check-further-callbacks = false;
|
|
run = ["move-node-to-workspace m" "resize-node"];
|
|
}
|
|
];
|
|
description = "Commands to run every time a new window is detected with optional conditions.";
|
|
};
|
|
workspace-to-monitor-force-assignment = lib.mkOption {
|
|
type = attrsOf (oneOf [int str (listOf str)]);
|
|
default = { };
|
|
description = ''
|
|
Map workspaces to specific monitors.
|
|
Left-hand side is the workspace name, and right-hand side is the monitor pattern.
|
|
'';
|
|
example = {
|
|
"1" = 1; # First monitor from left to right.
|
|
"2" = "main"; # Main monitor.
|
|
"3" = "secondary"; # Secondary monitor (non-main).
|
|
"4" = "built-in"; # Built-in display.
|
|
"5" = "^built-in retina display$"; # Regex for the built-in retina display.
|
|
"6" = ["secondary" "dell"]; # Match first pattern in the list.
|
|
};
|
|
};
|
|
on-focus-changed = lib.mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
description = "Commands to run every time focused window or workspace changes.";
|
|
};
|
|
on-focused-monitor-changed = lib.mkOption {
|
|
type = listOf str;
|
|
default = [ "move-mouse monitor-lazy-center" ];
|
|
description = "Commands to run every time focused monitor changes.";
|
|
};
|
|
exec-on-workspace-change = lib.mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
example = [
|
|
"/bin/bash"
|
|
"-c"
|
|
"sketchybar --trigger aerospace_workspace_change FOCUSED=$AEROSPACE_FOCUSED_WORKSPACE"
|
|
];
|
|
description = "Commands to run every time workspace changes.";
|
|
};
|
|
key-mapping.preset = lib.mkOption {
|
|
type = enum [
|
|
"qwerty"
|
|
"dvorak"
|
|
];
|
|
default = "qwerty";
|
|
description = "Keymapping preset.";
|
|
};
|
|
};
|
|
};
|
|
default = { };
|
|
example = lib.literalExpression ''
|
|
{
|
|
gaps = {
|
|
outer.left = 8;
|
|
outer.bottom = 8;
|
|
outer.top = 8;
|
|
outer.right = 8;
|
|
};
|
|
mode.main.binding = {
|
|
alt-h = "focus left";
|
|
alt-j = "focus down";
|
|
alt-k = "focus up";
|
|
alt-l = "focus right";
|
|
};
|
|
}
|
|
'';
|
|
description = ''
|
|
AeroSpace configuration, see
|
|
<link xlink:href="https://nikitabobko.github.io/AeroSpace/guide#configuring-aerospace"/>
|
|
for supported values.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
config = (
|
|
lib.mkIf (cfg.enable) {
|
|
assertions = [
|
|
{
|
|
assertion = !cfg.settings.start-at-login;
|
|
message = "AeroSpace started at login is managed by home-manager and launchd instead of itself via this option.";
|
|
}
|
|
{
|
|
assertion = cfg.settings.after-login-command == [ ];
|
|
message = "AeroSpace will not run these commands as it does not start itself.";
|
|
}
|
|
];
|
|
environment.systemPackages = [ cfg.package ];
|
|
|
|
launchd.user.agents.aerospace = {
|
|
command =
|
|
"${cfg.package}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace"
|
|
+ (lib.optionalString (cfg.settings != { }) " --config-path ${configFile}");
|
|
serviceConfig = {
|
|
KeepAlive = true;
|
|
RunAtLoad = true;
|
|
};
|
|
};
|
|
}
|
|
);
|
|
}
|