2018-08-28 15:46:24 +02:00
|
|
|
{ pkgs, lib }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
2022-07-07 05:36:20 +02:00
|
|
|
primitive = with types; oneOf [ bool int float str ];
|
|
|
|
|
2018-08-28 15:46:24 +02:00
|
|
|
rule = types.submodule {
|
2022-07-07 05:36:20 +02:00
|
|
|
freeformType = with types; attrsOf primitive;
|
|
|
|
|
2018-08-28 15:46:24 +02:00
|
|
|
options = {
|
|
|
|
monitor = mkOption {
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The monitor where the rule should be applied.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = "HDMI-0";
|
|
|
|
};
|
|
|
|
|
|
|
|
desktop = mkOption {
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The desktop where the rule should be applied.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = "^8";
|
|
|
|
};
|
|
|
|
|
|
|
|
node = mkOption {
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The node where the rule should be applied.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = "1";
|
|
|
|
};
|
|
|
|
|
|
|
|
state = mkOption {
|
2020-02-02 00:39:17 +01:00
|
|
|
type = types.nullOr
|
|
|
|
(types.enum [ "tiled" "pseudo_tiled" "floating" "fullscreen" ]);
|
2018-08-28 15:46:24 +02:00
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The state in which a new window should spawn.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = "floating";
|
|
|
|
};
|
|
|
|
|
|
|
|
layer = mkOption {
|
|
|
|
type = types.nullOr (types.enum [ "below" "normal" "above" ]);
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The layer where a new window should spawn.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = "above";
|
|
|
|
};
|
|
|
|
|
|
|
|
splitDir = mkOption {
|
|
|
|
type = types.nullOr (types.enum [ "north" "west" "south" "east" ]);
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The direction where the container is going to be split.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = "south";
|
|
|
|
};
|
|
|
|
|
|
|
|
splitRatio = mkOption {
|
|
|
|
type = types.nullOr types.float;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2018-08-28 15:46:24 +02:00
|
|
|
The ratio between the new window and the previous existing window in
|
|
|
|
the desktop.
|
|
|
|
'';
|
|
|
|
example = 0.65;
|
|
|
|
};
|
|
|
|
|
|
|
|
hidden = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Whether the node should occupy any space.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
sticky = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Whether the node should stay on the focused desktop.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
private = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2018-08-28 15:46:24 +02:00
|
|
|
Whether the node should stay in the same tiling position and size.
|
|
|
|
'';
|
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
locked = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
Whether the node should ignore {command}`node --close`
|
2018-08-28 15:46:24 +02:00
|
|
|
messages.
|
|
|
|
'';
|
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
marked = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Whether the node will be marked for deferred actions.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
center = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2018-08-28 15:46:24 +02:00
|
|
|
Whether the node will be put in the center, in floating mode.
|
|
|
|
'';
|
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
follow = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Whether focus should follow the node when it is moved.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
manage = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2018-08-28 15:46:24 +02:00
|
|
|
Whether the window should be managed by bspwm. If false, the window
|
|
|
|
will be ignored by bspwm entirely. This is useful for overlay apps,
|
|
|
|
e.g. screenshot tools.
|
|
|
|
'';
|
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
focus = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Whether the node should gain focus on creation.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
border = mkOption {
|
|
|
|
type = types.nullOr types.bool;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Whether the node should have border.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = true;
|
|
|
|
};
|
2022-07-07 05:36:20 +02:00
|
|
|
|
|
|
|
rectangle = mkOption {
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The node's geometry, in the format `WxH+X+Y`.";
|
2022-07-07 05:36:20 +02:00
|
|
|
example = "800x600+32+32";
|
|
|
|
};
|
2018-08-28 15:46:24 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-02-02 00:39:17 +01:00
|
|
|
in {
|
2018-08-28 15:46:24 +02:00
|
|
|
xsession.windowManager.bspwm = {
|
2023-07-02 01:45:18 +02:00
|
|
|
enable = mkEnableOption "bspwm window manager";
|
2018-08-28 15:46:24 +02:00
|
|
|
|
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
default = pkgs.bspwm;
|
2021-10-09 11:14:08 +02:00
|
|
|
defaultText = literalExpression "pkgs.bspwm";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The bspwm package to use.";
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression "pkgs.bspwm-unstable";
|
2018-08-28 15:46:24 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
settings = mkOption {
|
2022-07-07 05:36:20 +02:00
|
|
|
type = with types; attrsOf (either primitive (listOf primitive));
|
2020-02-02 00:39:17 +01:00
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "General settings given to `bspc config`.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = {
|
|
|
|
"border_width" = 2;
|
|
|
|
"split_ratio" = 0.52;
|
|
|
|
"gapless_monocle" = true;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
2023-07-02 01:45:18 +02:00
|
|
|
description =
|
2021-06-20 00:40:17 +02:00
|
|
|
"Additional shell commands to be run at the end of the config file.";
|
2018-08-28 15:46:24 +02:00
|
|
|
example = ''
|
|
|
|
bspc subscribe all > ~/bspc-report.log &
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2022-08-27 06:09:46 +02:00
|
|
|
extraConfigEarly = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
2023-07-02 01:45:18 +02:00
|
|
|
description =
|
2022-08-27 06:09:46 +02:00
|
|
|
"Like extraConfig, except commands are run at the start of the config file.";
|
|
|
|
};
|
|
|
|
|
2018-08-28 15:46:24 +02:00
|
|
|
monitors = mkOption {
|
|
|
|
type = types.attrsOf (types.listOf types.str);
|
2020-02-02 00:39:17 +01:00
|
|
|
default = { };
|
2021-06-20 00:40:17 +02:00
|
|
|
description =
|
2023-07-02 01:45:18 +02:00
|
|
|
"Specifies the names of desktops to create on each monitor.";
|
2020-02-02 00:39:17 +01:00
|
|
|
example = { "HDMI-0" = [ "web" "terminal" "III" "IV" ]; };
|
2018-08-28 15:46:24 +02:00
|
|
|
};
|
|
|
|
|
2022-03-18 03:56:56 +01:00
|
|
|
alwaysResetDesktops = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
If set to `true`, desktops configured in {option}`monitors` will be reset
|
2022-03-18 03:56:56 +01:00
|
|
|
every time the config is run.
|
|
|
|
|
2023-07-01 01:30:13 +02:00
|
|
|
If set to `false`, desktops will only be configured the first time the config is run.
|
2022-03-18 03:56:56 +01:00
|
|
|
This is useful if you want to dynamically add desktops and you don't want them to be destroyed if you
|
2023-07-01 01:30:13 +02:00
|
|
|
re-run `bspwmrc`.
|
2022-03-18 03:56:56 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2018-08-28 15:46:24 +02:00
|
|
|
rules = mkOption {
|
|
|
|
type = types.attrsOf rule;
|
2020-02-02 00:39:17 +01:00
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description =
|
2021-06-20 00:40:17 +02:00
|
|
|
"Rule configuration. The keys of the attribute set are the targets of the rules.";
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2018-08-28 15:46:24 +02:00
|
|
|
{
|
|
|
|
"Gimp" = {
|
|
|
|
desktop = "^8";
|
|
|
|
state = "floating";
|
|
|
|
follow = true;
|
|
|
|
};
|
|
|
|
"Kupfer.py" = {
|
|
|
|
focus = true;
|
|
|
|
};
|
|
|
|
"Screenkey" = {
|
|
|
|
manage = false;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
startupPrograms = mkOption {
|
|
|
|
type = types.listOf types.str;
|
2020-02-02 00:39:17 +01:00
|
|
|
default = [ ];
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Programs to be executed during startup.";
|
2020-02-02 00:39:17 +01:00
|
|
|
example = [ "numlockx on" "tilda" ];
|
2018-08-28 15:46:24 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|