home-manager/modules/services/window-managers/bspwm/default.nix

72 lines
2.2 KiB
Nix
Raw Normal View History

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.xsession.windowManager.bspwm;
bspwm = cfg.package;
camelToSnake = s:
builtins.replaceStrings lib.upperChars (map (c: "_${c}") lib.lowerChars) s;
formatConfig = n: v:
let
formatList = x:
if isList x
then throw "can not convert 2-dimensional lists to bspwm format"
else formatValue x;
formatValue = v:
if isBool v then (if v then "true" else "false")
else if isList v then concatMapStringsSep ", " formatList v
else if isString v then "${lib.strings.escapeShellArg v}"
else toString v;
in
"bspc config ${n} ${formatValue v}";
formatMonitors = n: v: "bspc monitor ${n} -d ${concatStringsSep " " v}";
formatRules = target: directiveOptions:
let
formatDirective = n: v:
if isBool v then (if v then "${camelToSnake n}=on" else "${camelToSnake n}=off")
else if (n == "desktop" || n == "node") then "${camelToSnake n}='${v}'"
else "${camelToSnake n}=${lib.strings.escapeShellArg v}";
directives = filterAttrs (n: v: v != null && !(lib.strings.hasPrefix "_" n)) directiveOptions;
directivesStr = builtins.concatStringsSep " " (mapAttrsToList formatDirective directives);
in
"bspc rule -a ${target} ${directivesStr}";
formatStartupPrograms = map (s: "${s} &");
in
{
options = import ./options.nix { inherit pkgs; inherit lib; };
config = mkIf cfg.enable {
home.packages = [ bspwm ];
xsession.windowManager.command =
let
configFile = pkgs.writeShellScript "bspwmrc" (
concatStringsSep "\n" (
(mapAttrsToList formatMonitors cfg.monitors)
++ (mapAttrsToList formatConfig cfg.settings)
++ (mapAttrsToList formatRules cfg.rules)
++ [ ''
# java gui fixes
export _JAVA_AWT_WM_NONREPARENTING=1
bspc rule -a sun-awt-X11-XDialogPeer state=floating
'' ]
++ [ cfg.extraConfig ]
++ (formatStartupPrograms cfg.startupPrograms)
)
);
configCmdOpt = optionalString (cfg.settings != null) "-c ${configFile}";
in
"${cfg.package}/bin/bspwm ${configCmdOpt}";
};
}