From 0869e237007aa48f458c9d9ba9080280565a7160 Mon Sep 17 00:00:00 2001 From: Alex Rice Date: Mon, 13 Jul 2020 12:31:55 +0100 Subject: [PATCH] sway: set bar defaults to null Allows fields of bar to be nullable and omit them from the generated configuration if unset. Fixes #1361 PR #1386 --- doc/release-notes/rl-2009.adoc | 43 +++++++++ .../services/window-managers/i3-sway/i3.nix | 2 +- .../window-managers/i3-sway/lib/functions.nix | 69 +++++++++---- .../window-managers/i3-sway/lib/options.nix | 96 +++++++++++++++---- .../services/window-managers/i3-sway/sway.nix | 2 +- .../services/window-managers/sway/default.nix | 1 + .../window-managers/sway/sway-post-2003.nix | 35 +++++++ 7 files changed, 210 insertions(+), 38 deletions(-) create mode 100644 tests/modules/services/window-managers/sway/sway-post-2003.nix diff --git a/doc/release-notes/rl-2009.adoc b/doc/release-notes/rl-2009.adoc index 7740646a9..c1939ab5a 100644 --- a/doc/release-notes/rl-2009.adoc +++ b/doc/release-notes/rl-2009.adoc @@ -52,3 +52,46 @@ will automatically include these options, when necessary. _module.args.pkgsPath = ; + to your Home Manager configuration. + +* The options `wayland.windowManager.sway.config.bars` and `opt-xsession.windowManager.i3.config.bars` have been changed so that most of the suboptions are now nullable and default to `null`. The default for these two options has been changed to manually set the old defaults for each suboption. The overall effect is that if the `bars` options is not set, then the default remains the same. On the other hand, something like: ++ +-- +[source,nix] +---- +bars = [ { + command = "waybar"; +} ]; +---- +will now create the config: +.... +bar { + swaybar_command waybar +} +.... +instead of +.... +bar { + + font pango:monospace 8 + mode dock + hidden_state hide + position bottom + status_command /nix/store/h7s6i9q1z5fxrlyyw5ls8vqxhf5bcs5a-i3status-2.13/bin/i3status + swaybar_command waybar + workspace_buttons yes + strip_workspace_numbers no + tray_output primary + colors { + background #000000 + statusline #ffffff + separator #666666 + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } + +} +.... +-- diff --git a/modules/services/window-managers/i3-sway/i3.nix b/modules/services/window-managers/i3-sway/i3.nix index 540025055..f7124e6fd 100644 --- a/modules/services/window-managers/i3-sway/i3.nix +++ b/modules/services/window-managers/i3-sway/i3.nix @@ -7,7 +7,7 @@ let cfg = config.xsession.windowManager.i3; commonOptions = import ./lib/options.nix { - inherit lib cfg pkgs; + inherit config lib cfg pkgs; moduleName = "i3"; isGaps = cfg.package == pkgs.i3-gaps; }; diff --git a/modules/services/window-managers/i3-sway/lib/functions.nix b/modules/services/window-managers/i3-sway/lib/functions.nix index ea2938e6f..9391e6e92 100644 --- a/modules/services/window-managers/i3-sway/lib/functions.nix +++ b/modules/services/window-managers/i3-sway/lib/functions.nix @@ -41,31 +41,66 @@ rec { barStr = { id, fonts, mode, hiddenState, position, workspaceButtons , workspaceNumbers, command, statusCommand, colors, trayOutput, extraConfig - , ... }: '' + , ... }: + let colorsNotNull = lib.filterAttrs (n: v: v != null) colors != { }; + in '' bar { ${optionalString (id != null) "id ${id}"} - font pango:${concatStringsSep ", " fonts} - mode ${mode} - hidden_state ${hiddenState} - position ${position} + ${ + optionalString (fonts != [ ]) + "font pango:${concatStringsSep ", " fonts}" + } + ${optionalString (mode != null) "mode ${mode}"} + ${optionalString (hiddenState != null) "hidden_state ${hiddenState}"} + ${optionalString (position != null) "position ${position}"} ${ optionalString (statusCommand != null) "status_command ${statusCommand}" } ${moduleName}bar_command ${command} - workspace_buttons ${if workspaceButtons then "yes" else "no"} - strip_workspace_numbers ${if !workspaceNumbers then "yes" else "no"} - tray_output ${trayOutput} - colors { - background ${colors.background} - statusline ${colors.statusline} - separator ${colors.separator} - focused_workspace ${barColorSetStr colors.focusedWorkspace} - active_workspace ${barColorSetStr colors.activeWorkspace} - inactive_workspace ${barColorSetStr colors.inactiveWorkspace} - urgent_workspace ${barColorSetStr colors.urgentWorkspace} - binding_mode ${barColorSetStr colors.bindingMode} + ${ + optionalString (workspaceButtons != null) + "workspace_buttons ${if workspaceButtons then "yes" else "no"}" } + ${ + optionalString (workspaceNumbers != null) + "strip_workspace_numbers ${if !workspaceNumbers then "yes" else "no"}" + } + ${optionalString (trayOutput != null) "tray_output ${trayOutput}"} + ${optionalString colorsNotNull "colors {"} + ${ + optionalString (colors.background != null) + "background ${colors.background}" + } + ${ + optionalString (colors.statusline != null) + "statusline ${colors.statusline}" + } + ${ + optionalString (colors.separator != null) + "separator ${colors.separator}" + } + ${ + optionalString (colors.focusedWorkspace != null) + "focused_workspace ${barColorSetStr colors.focusedWorkspace}" + } + ${ + optionalString (colors.activeWorkspace != null) + "active_workspace ${barColorSetStr colors.activeWorkspace}" + } + ${ + optionalString (colors.inactiveWorkspace != null) + "inactive_workspace ${barColorSetStr colors.inactiveWorkspace}" + } + ${ + optionalString (colors.urgentWorkspace != null) + "urgent_workspace ${barColorSetStr colors.urgentWorkspace}" + } + ${ + optionalString (colors.bindingMode != null) + "binding_mode ${barColorSetStr colors.bindingMode}" + } + ${optionalString colorsNotNull "}"} ${extraConfig} } ''; diff --git a/modules/services/window-managers/i3-sway/lib/options.nix b/modules/services/window-managers/i3-sway/lib/options.nix index b5216f8ca..edfdcd4fe 100644 --- a/modules/services/window-managers/i3-sway/lib/options.nix +++ b/modules/services/window-managers/i3-sway/lib/options.nix @@ -1,4 +1,5 @@ -{ lib, moduleName, cfg, pkgs, capitalModuleName ? moduleName, isGaps ? true }: +{ config, lib, moduleName, cfg, pkgs, capitalModuleName ? moduleName +, isGaps ? true }: with lib; @@ -49,8 +50,23 @@ let }; barModule = types.submodule { - options = { - inherit fonts; + options = let + versionAtLeast2009 = versionAtLeast config.home.stateVersion "20.09"; + mkNullableOption = { type, default, ... }@args: + mkOption (args // optionalAttrs versionAtLeast2009 { + type = types.nullOr type; + default = null; + example = default; + } // { + defaultText = literalExample '' + ${ + if isString default then default else "See code" + } for state version < 20.09, + null for state version ≥ 20.09 + ''; + }); + in { + fonts = fonts // optionalAttrs versionAtLeast2009 { default = [ ]; }; extraConfig = mkOption { type = types.lines; @@ -68,31 +84,31 @@ let ''; }; - mode = mkOption { + mode = mkNullableOption { type = types.enum [ "dock" "hide" "invisible" ]; default = "dock"; description = "Bar visibility mode."; }; - hiddenState = mkOption { + hiddenState = mkNullableOption { type = types.enum [ "hide" "show" ]; default = "hide"; description = "The default bar mode when 'bar.mode' == 'hide'."; }; - position = mkOption { + position = mkNullableOption { type = types.enum [ "top" "bottom" ]; default = "bottom"; description = "The edge of the screen ${moduleName}bar should show up."; }; - workspaceButtons = mkOption { + workspaceButtons = mkNullableOption { type = types.bool; default = true; description = "Whether workspace buttons should be shown or not."; }; - workspaceNumbers = mkOption { + workspaceNumbers = mkNullableOption { type = types.bool; default = true; description = @@ -112,32 +128,34 @@ let statusCommand = mkOption { type = types.nullOr types.str; - default = "${pkgs.i3status}/bin/i3status"; + default = + if versionAtLeast2009 then null else "${pkgs.i3status}/bin/i3status"; + example = "i3status"; description = "Command that will be used to get status lines."; }; colors = mkOption { type = types.submodule { options = { - background = mkOption { + background = mkNullableOption { type = types.str; default = "#000000"; description = "Background color of the bar."; }; - statusline = mkOption { + statusline = mkNullableOption { type = types.str; default = "#ffffff"; description = "Text color to be used for the statusline."; }; - separator = mkOption { + separator = mkNullableOption { type = types.str; default = "#666666"; description = "Text color to be used for the separator."; }; - focusedWorkspace = mkOption { + focusedWorkspace = mkNullableOption { type = barColorSetModule; default = { border = "#4c7899"; @@ -149,7 +167,7 @@ let ''; }; - activeWorkspace = mkOption { + activeWorkspace = mkNullableOption { type = barColorSetModule; default = { border = "#333333"; @@ -161,7 +179,7 @@ let ''; }; - inactiveWorkspace = mkOption { + inactiveWorkspace = mkNullableOption { type = barColorSetModule; default = { border = "#333333"; @@ -174,7 +192,7 @@ let ''; }; - urgentWorkspace = mkOption { + urgentWorkspace = mkNullableOption { type = barColorSetModule; default = { border = "#2f343a"; @@ -187,7 +205,7 @@ let ''; }; - bindingMode = mkOption { + bindingMode = mkNullableOption { type = barColorSetModule; default = { border = "#2f343a"; @@ -210,7 +228,7 @@ let ''; }; - trayOutput = mkOption { + trayOutput = mkNullableOption { type = types.str; default = "primary"; description = "Where to output tray."; @@ -573,7 +591,47 @@ in { bars = mkOption { type = types.listOf barModule; - default = [ { } ]; + default = if versionAtLeast config.home.stateVersion "20.09" then [{ + mode = "dock"; + hiddenState = "hide"; + position = "bottom"; + workspaceButtons = true; + workspaceNumbers = true; + statusCommand = "${pkgs.i3status}/bin/i3status"; + fonts = [ "monospace 8" ]; + trayOutput = "primary"; + colors = { + background = "#000000"; + statusline = "#ffffff"; + separator = "#666666"; + focusedWorkspace = { + border = "#4c7899"; + background = "#285577"; + text = "#ffffff"; + }; + activeWorkspace = { + border = "#333333"; + background = "#5f676a"; + text = "#ffffff"; + }; + inactiveWorkspace = { + border = "#333333"; + background = "#222222"; + text = "#888888"; + }; + urgentWorkspace = { + border = "#2f343a"; + background = "#900000"; + text = "#ffffff"; + }; + bindingMode = { + border = "#2f343a"; + background = "#900000"; + text = "#ffffff"; + }; + }; + }] else + [ { } ]; description = '' ${capitalModuleName} bars settings blocks. Set to empty list to remove bars completely. ''; diff --git a/modules/services/window-managers/i3-sway/sway.nix b/modules/services/window-managers/i3-sway/sway.nix index 83c8afd6c..8f0ee6081 100644 --- a/modules/services/window-managers/i3-sway/sway.nix +++ b/modules/services/window-managers/i3-sway/sway.nix @@ -7,7 +7,7 @@ let cfg = config.wayland.windowManager.sway; commonOptions = import ./lib/options.nix { - inherit lib cfg pkgs; + inherit config lib cfg pkgs; moduleName = "sway"; capitalModuleName = "Sway"; }; diff --git a/tests/modules/services/window-managers/sway/default.nix b/tests/modules/services/window-managers/sway/default.nix index 6b545a26a..b9c0ab5e0 100644 --- a/tests/modules/services/window-managers/sway/default.nix +++ b/tests/modules/services/window-managers/sway/default.nix @@ -1,5 +1,6 @@ { sway-default = ./sway-default.nix; + sway-post-2003 = ./sway-post-2003.nix; sway-followmouse = ./sway-followmouse.nix; sway-followmouse-legacy = ./sway-followmouse-legacy.nix; } diff --git a/tests/modules/services/window-managers/sway/sway-post-2003.nix b/tests/modules/services/window-managers/sway/sway-post-2003.nix new file mode 100644 index 000000000..3eab6538e --- /dev/null +++ b/tests/modules/services/window-managers/sway/sway-post-2003.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + home.stateVersion = "20.09"; + + wayland.windowManager.sway = { + enable = true; + package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out" // { + outPath = "@sway"; + }; + # overriding findutils causes issues + config.menu = "${pkgs.dmenu}/bin/dmenu_run"; + }; + + nixpkgs.overlays = [ + (self: super: { + dummy-package = super.runCommandLocal "dummy-package" { } "mkdir $out"; + dmenu = self.dummy-package // { outPath = "@dmenu@"; }; + rxvt-unicode-unwrapped = self.dummy-package // { + outPath = "@rxvt-unicode-unwrapped@"; + }; + i3status = self.dummy-package // { outPath = "@i3status@"; }; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-default.conf} + ''; + }; +}