Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
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
  • Loading branch information
thuvasooriya committed Dec 29, 2024
1 parent 713da7b commit 372bb76
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 19 deletions.
136 changes: 117 additions & 19 deletions modules/services/aerospace/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,42 @@
lib,
pkgs,
...
}:

let
}: let
cfg = config.services.aerospace;

format = pkgs.formats.toml { };
configFile = format.generate "aerospace.toml" cfg.settings;
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" { };
package = lib.mkPackageOption pkgs "aerospace" {};

settings = lib.mkOption {
type = submodule {
Expand All @@ -30,14 +51,14 @@ in
};
after-login-command = lib.mkOption {
type = listOf str;
default = [ ];
default = [];
description = "Do not use AeroSpace to run commands after login. (Managed by launchd instead)";
};
after-startup-command = lib.mkOption {
type = listOf str;
default = [ ];
default = [];
description = "Add commands that run after AeroSpace startup";
example = [ "layout tiles" ];
example = ["layout tiles"];
};
enable-normalization-flatten-containers = lib.mkOption {
type = bool;
Expand Down Expand Up @@ -72,23 +93,100 @@ in
description = "Default orientation for the root container.";
};
on-window-detected = lib.mkOption {
type = listOf str;
default = [ ];
description = "Commands to run every time a new window is detected.";
type = types.listOf (types.attrsOf types.anything);
default = [];
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 = [ ];
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" ];
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 = [ ];
default = [];
example = [
"/bin/bash"
"-c"
Expand All @@ -106,7 +204,7 @@ in
};
};
};
default = { };
default = {};
example = lib.literalExpression ''
{
gaps = {
Expand Down Expand Up @@ -140,16 +238,16 @@ in
message = "AeroSpace started at login is managed by home-manager and launchd instead of itself via this option.";
}
{
assertion = cfg.settings.after-login-command == [ ];
assertion = cfg.settings.after-login-command == [];
message = "AeroSpace will not run these commands as it does not start itself.";
}
];
environment.systemPackages = [ cfg.package ];
environment.systemPackages = [cfg.package];

launchd.user.agents.aerospace = {
command =
"${cfg.package}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace"
+ (lib.optionalString (cfg.settings != { }) " --config-path ${configFile}");
+ (lib.optionalString (cfg.settings != {}) " --config-path ${configFile}");
serviceConfig = {
KeepAlive = true;
RunAtLoad = true;
Expand Down
45 changes: 45 additions & 0 deletions tests/services-aerospace.nix
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,32 @@ in
alt-k = "focus up";
alt-l = "focus right";
};
on-window-detected = [
{
"if" = {
app-id = "Another.Cool.App";
during-aerospace-startup = false;
};
check-further-callbacks = false;
run = "move-node-to-workspace m";
}
{
"if".app-name-regex-substring = "finder|calendar";
run = "layout floating";
}
{
"if".workspace = "1";
run = "layout h_accordion";
}
];
workspace-to-monitor-force-assignment = {
"1" = 1;
"2" = "main";
"3" = "secondary";
"4" = "built-in";
"5" = "^built-in retina display$";
"6" = [ "secondary" "dell" ];
};
};

test = ''
Expand All @@ -43,5 +69,24 @@ in
grep 'alt-j = "focus down"' $conf
grep 'alt-k = "focus up"' $conf
grep 'alt-l = "focus right"' $conf
grep 'check-further-callbacks = false' $conf
grep 'run = "move-node-to-workspace m"' $conf
grep 'app-id = "Another.Cool.App"' $conf
grep 'during-aerospace-startup = false' $conf
grep 'run = "layout floating"' $conf
grep 'app-name-regex-substring = "finder|calendar"' $conf
(! grep 'window-title-regex-substring' $conf)
grep 'workspace = "1"' $conf
grep 'run = "layout h_accordion"' $conf
grep '1 = 1' $conf
grep '2 = "main"' $conf
grep '3 = "secondary"' $conf
grep '4 = "built-in"' $conf
grep '5 = "^built-in retina display$"' $conf
grep '6 = \["secondary", "dell"\]' $conf
'';
}

0 comments on commit 372bb76

Please sign in to comment.