commit
dc9c88a451
3 changed files with 117 additions and 85 deletions
|
@ -16,11 +16,11 @@
|
||||||
effects, some example settings:
|
effects, some example settings:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-services.picom.enable">services.picom</link> = {
|
<link linkend="opt-services.picom.enable">services.picom</link> = {
|
||||||
<link linkend="opt-services.picom.enable">enable</link> = true;
|
<link linkend="opt-services.picom.enable">enable</link> = true;
|
||||||
<link linkend="opt-services.picom.fade">fade</link> = true;
|
<link linkend="opt-services.picom.fade">fade</link> = true;
|
||||||
<link linkend="opt-services.picom.inactiveOpacity">inactiveOpacity</link> = "0.9";
|
<link linkend="opt-services.picom.inactiveOpacity">inactiveOpacity</link> = 0.9;
|
||||||
<link linkend="opt-services.picom.shadow">shadow</link> = true;
|
<link linkend="opt-services.picom.shadow">shadow</link> = true;
|
||||||
<link linkend="opt-services.picom.fadeDelta">fadeDelta</link> = 4;
|
<link linkend="opt-services.picom.fadeDelta">fadeDelta</link> = 4;
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -317,6 +317,15 @@ php.override {
|
||||||
<manvolnum>5</manvolnum></citerefentry> for details.
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
In the <literal>picom</literal> module, several options that accepted
|
||||||
|
floating point numbers encoded as strings (for example
|
||||||
|
<xref linkend="opt-services.picom.activeOpacity"/>) have been changed
|
||||||
|
to the (relatively) new native <literal>float</literal> type. To migrate
|
||||||
|
your configuration simply remove the quotes around the numbers.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,48 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
with builtins;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.services.picom;
|
cfg = config.services.picom;
|
||||||
|
|
||||||
pairOf = x: with types; addCheck (listOf x) (y: length y == 2);
|
pairOf = x: with types;
|
||||||
|
addCheck (listOf x) (y: length y == 2)
|
||||||
|
// { description = "pair of ${x.description}"; };
|
||||||
|
|
||||||
floatBetween = a: b: with lib; with types;
|
floatBetween = a: b: with types;
|
||||||
addCheck str (x: versionAtLeast x a && versionOlder x b);
|
let
|
||||||
|
# toString prints floats with hardcoded high precision
|
||||||
|
floatToString = f: builtins.toJSON f;
|
||||||
|
in
|
||||||
|
addCheck float (x: x <= b && x >= a)
|
||||||
|
// { description = "a floating point number in " +
|
||||||
|
"range [${floatToString a}, ${floatToString b}]"; };
|
||||||
|
|
||||||
toConf = attrs: concatStringsSep "\n"
|
mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
|
||||||
(mapAttrsToList
|
|
||||||
(k: v: let
|
# Basically a tinkered lib.generators.mkKeyValueDefault
|
||||||
sep = if isAttrs v then ":" else "=";
|
# It either serializes a top-level definition "key: { values };"
|
||||||
# Basically a tinkered lib.generators.mkKeyValueDefault
|
# or an expression "key = { values };"
|
||||||
mkValueString = v:
|
mkAttrsString = top:
|
||||||
if isBool v then boolToString v
|
mapAttrsToList (k: v:
|
||||||
else if isInt v then toString v
|
let sep = if (top && isAttrs v) then ":" else "=";
|
||||||
else if isFloat v then toString v
|
in "${escape [ sep ] k}${sep}${mkValueString v};");
|
||||||
else if isString v then ''"${escape [ ''"'' ] v}"''
|
|
||||||
else if isList v then "[ "
|
# This serializes a Nix expression to the libconfig format.
|
||||||
+ concatMapStringsSep " , " mkValueString v
|
mkValueString = v:
|
||||||
+ " ]"
|
if types.bool.check v then boolToString v
|
||||||
else if isAttrs v then "{ "
|
else if types.int.check v then toString v
|
||||||
+ concatStringsSep " "
|
else if types.float.check v then toString v
|
||||||
(mapAttrsToList
|
else if types.str.check v then "\"${escape [ "\"" ] v}\""
|
||||||
(key: value: "${toString key}=${mkValueString value};")
|
else if builtins.isList v then "[ ${concatMapStringsSep " , " mkValueString v} ]"
|
||||||
v)
|
else if types.attrs.check v then "{ ${concatStringsSep " " (mkAttrsString false v) } }"
|
||||||
+ " }"
|
else throw ''
|
||||||
else abort "picom.mkValueString: unexpected type (v = ${v})";
|
invalid expression used in option services.picom.settings:
|
||||||
in "${escape [ sep ] k}${sep}${mkValueString v};")
|
${v}
|
||||||
attrs);
|
'';
|
||||||
|
|
||||||
|
toConf = attrs: concatStringsSep "\n" (mkAttrsString true cfg.settings);
|
||||||
|
|
||||||
configFile = pkgs.writeText "picom.conf" (toConf cfg.settings);
|
configFile = pkgs.writeText "picom.conf" (toConf cfg.settings);
|
||||||
|
|
||||||
|
@ -61,7 +70,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
fadeDelta = mkOption {
|
fadeDelta = mkOption {
|
||||||
type = types.addCheck types.int (x: x > 0);
|
type = types.ints.positive;
|
||||||
default = 10;
|
default = 10;
|
||||||
example = 5;
|
example = 5;
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -70,12 +79,11 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
fadeSteps = mkOption {
|
fadeSteps = mkOption {
|
||||||
type = pairOf (floatBetween "0.01" "1.01");
|
type = pairOf (floatBetween 0.01 1);
|
||||||
default = [ "0.028" "0.03" ];
|
default = [ 0.028 0.03 ];
|
||||||
example = [ "0.04" "0.04" ];
|
example = [ 0.04 0.04 ];
|
||||||
description = ''
|
description = ''
|
||||||
Opacity change between fade steps (in and out).
|
Opacity change between fade steps (in and out).
|
||||||
(numbers in range 0.01 - 1.0)
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,11 +119,11 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
shadowOpacity = mkOption {
|
shadowOpacity = mkOption {
|
||||||
type = floatBetween "0.0" "1.01";
|
type = floatBetween 0 1;
|
||||||
default = "0.75";
|
default = 0.75;
|
||||||
example = "0.8";
|
example = 0.8;
|
||||||
description = ''
|
description = ''
|
||||||
Window shadows opacity (number in range 0.0 - 1.0).
|
Window shadows opacity.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,29 +142,29 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
activeOpacity = mkOption {
|
activeOpacity = mkOption {
|
||||||
type = floatBetween "0.0" "1.01";
|
type = floatBetween 0 1;
|
||||||
default = "1.0";
|
default = 1.0;
|
||||||
example = "0.8";
|
example = 0.8;
|
||||||
description = ''
|
description = ''
|
||||||
Opacity of active windows (number in range 0.0 - 1.0).
|
Opacity of active windows.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
inactiveOpacity = mkOption {
|
inactiveOpacity = mkOption {
|
||||||
type = floatBetween "0.1" "1.01";
|
type = floatBetween 0.1 1;
|
||||||
default = "1.0";
|
default = 1.0;
|
||||||
example = "0.8";
|
example = 0.8;
|
||||||
description = ''
|
description = ''
|
||||||
Opacity of inactive windows (number in range 0.1 - 1.0).
|
Opacity of inactive windows.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
menuOpacity = mkOption {
|
menuOpacity = mkOption {
|
||||||
type = floatBetween "0.0" "1.01";
|
type = floatBetween 0 1;
|
||||||
default = "1.0";
|
default = 1.0;
|
||||||
example = "0.8";
|
example = 0.8;
|
||||||
description = ''
|
description = ''
|
||||||
Opacity of dropdown and popup menu (number in range 0.0 - 1.0).
|
Opacity of dropdown and popup menu.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -210,7 +218,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
refreshRate = mkOption {
|
refreshRate = mkOption {
|
||||||
type = types.addCheck types.int (x: x >= 0);
|
type = types.ints.unsigned;
|
||||||
default = 0;
|
default = 0;
|
||||||
example = 60;
|
example = 60;
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -218,54 +226,69 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = let
|
settings = with types;
|
||||||
configTypes = with types; oneOf [ bool int float str ];
|
let
|
||||||
# types.loaOf converts lists to sets
|
scalar = oneOf [ bool int float str ]
|
||||||
loaOf = t: with types; either (listOf t) (attrsOf t);
|
// { description = "scalar types"; };
|
||||||
|
|
||||||
|
libConfig = oneOf [ scalar (listOf libConfig) (attrsOf libConfig) ]
|
||||||
|
// { description = "libconfig type"; };
|
||||||
|
|
||||||
|
topLevel = attrsOf libConfig
|
||||||
|
// { description = ''
|
||||||
|
libconfig configuration. The format consists of an attributes
|
||||||
|
set (called a group) of settings. Each setting can be a scalar type
|
||||||
|
(boolean, integer, floating point number or string), a list of
|
||||||
|
scalars or a group itself
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
in mkOption {
|
in mkOption {
|
||||||
type = loaOf (types.either configTypes (loaOf (types.either configTypes (loaOf configTypes))));
|
type = topLevel;
|
||||||
default = {};
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
blur =
|
||||||
|
{ method = "gaussian";
|
||||||
|
size = 10;
|
||||||
|
deviation = 5.0;
|
||||||
|
};
|
||||||
|
'';
|
||||||
description = ''
|
description = ''
|
||||||
Additional Picom configuration.
|
Picom settings. Use this option to configure Picom settings not exposed
|
||||||
|
in a NixOS option or to bypass one. For the available options see the
|
||||||
|
CONFIGURATION FILES section at <literal>picom(1)</literal>.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.picom.settings = let
|
services.picom.settings = mkDefaultAttrs {
|
||||||
# Hard conversion to float, literally lib.toInt but toFloat
|
|
||||||
toFloat = str: let
|
|
||||||
may_be_float = builtins.fromJSON str;
|
|
||||||
in if builtins.isFloat may_be_float
|
|
||||||
then may_be_float
|
|
||||||
else throw "Could not convert ${str} to float.";
|
|
||||||
in {
|
|
||||||
# fading
|
# fading
|
||||||
fading = mkDefault cfg.fade;
|
fading = cfg.fade;
|
||||||
fade-delta = mkDefault cfg.fadeDelta;
|
fade-delta = cfg.fadeDelta;
|
||||||
fade-in-step = mkDefault (toFloat (elemAt cfg.fadeSteps 0));
|
fade-in-step = elemAt cfg.fadeSteps 0;
|
||||||
fade-out-step = mkDefault (toFloat (elemAt cfg.fadeSteps 1));
|
fade-out-step = elemAt cfg.fadeSteps 1;
|
||||||
fade-exclude = mkDefault cfg.fadeExclude;
|
fade-exclude = cfg.fadeExclude;
|
||||||
|
|
||||||
# shadows
|
# shadows
|
||||||
shadow = mkDefault cfg.shadow;
|
shadow = cfg.shadow;
|
||||||
shadow-offset-x = mkDefault (elemAt cfg.shadowOffsets 0);
|
shadow-offset-x = elemAt cfg.shadowOffsets 0;
|
||||||
shadow-offset-y = mkDefault (elemAt cfg.shadowOffsets 1);
|
shadow-offset-y = elemAt cfg.shadowOffsets 1;
|
||||||
shadow-opacity = mkDefault (toFloat cfg.shadowOpacity);
|
shadow-opacity = cfg.shadowOpacity;
|
||||||
shadow-exclude = mkDefault cfg.shadowExclude;
|
shadow-exclude = cfg.shadowExclude;
|
||||||
|
|
||||||
# opacity
|
# opacity
|
||||||
active-opacity = mkDefault (toFloat cfg.activeOpacity);
|
active-opacity = cfg.activeOpacity;
|
||||||
inactive-opacity = mkDefault (toFloat cfg.inactiveOpacity);
|
inactive-opacity = cfg.inactiveOpacity;
|
||||||
|
|
||||||
wintypes = mkDefault cfg.wintypes;
|
wintypes = cfg.wintypes;
|
||||||
|
|
||||||
opacity-rule = mkDefault cfg.opacityRules;
|
opacity-rule = cfg.opacityRules;
|
||||||
|
|
||||||
# other options
|
# other options
|
||||||
backend = mkDefault cfg.backend;
|
backend = cfg.backend;
|
||||||
vsync = mkDefault cfg.vSync;
|
vsync = cfg.vSync;
|
||||||
refresh-rate = mkDefault cfg.refreshRate;
|
refresh-rate = cfg.refreshRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.user.services.picom = {
|
systemd.user.services.picom = {
|
||||||
|
|
Loading…
Reference in a new issue