2016-07-17 02:25:38 +02:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
with builtins;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.services.compton;
|
|
|
|
|
2017-10-16 23:52:42 +02:00
|
|
|
floatBetween = a: b: with lib; with types;
|
|
|
|
addCheck str (x: versionAtLeast x a && versionOlder x b);
|
|
|
|
|
|
|
|
pairOf = x: with types; addCheck (listOf x) (y: lib.length y == 2);
|
|
|
|
|
|
|
|
opacityRules = optionalString (length cfg.opacityRules != 0)
|
|
|
|
(concatMapStringsSep ",\n" (rule: ''"${rule}"'') cfg.opacityRules);
|
|
|
|
|
|
|
|
configFile = pkgs.writeText "compton.conf"
|
2016-07-17 02:25:38 +02:00
|
|
|
(optionalString cfg.fade ''
|
|
|
|
# fading
|
|
|
|
fading = true;
|
|
|
|
fade-delta = ${toString cfg.fadeDelta};
|
|
|
|
fade-in-step = ${elemAt cfg.fadeSteps 0};
|
|
|
|
fade-out-step = ${elemAt cfg.fadeSteps 1};
|
|
|
|
fade-exclude = ${toJSON cfg.fadeExclude};
|
|
|
|
'' +
|
|
|
|
optionalString cfg.shadow ''
|
|
|
|
|
|
|
|
# shadows
|
|
|
|
shadow = true;
|
|
|
|
shadow-offset-x = ${toString (elemAt cfg.shadowOffsets 0)};
|
|
|
|
shadow-offset-y = ${toString (elemAt cfg.shadowOffsets 1)};
|
|
|
|
shadow-opacity = ${cfg.shadowOpacity};
|
|
|
|
shadow-exclude = ${toJSON cfg.shadowExclude};
|
|
|
|
'' + ''
|
|
|
|
|
|
|
|
# opacity
|
|
|
|
active-opacity = ${cfg.activeOpacity};
|
|
|
|
inactive-opacity = ${cfg.inactiveOpacity};
|
2019-05-28 13:37:14 +02:00
|
|
|
|
|
|
|
wintypes:
|
|
|
|
{
|
|
|
|
popup_menu = { opacity = ${cfg.menuOpacity}; }
|
|
|
|
dropdown_menu = { opacity = ${cfg.menuOpacity}; }
|
|
|
|
};
|
2017-10-12 16:07:52 +02:00
|
|
|
|
2017-10-16 23:52:42 +02:00
|
|
|
opacity-rule = [
|
|
|
|
${opacityRules}
|
|
|
|
];
|
2017-10-12 16:07:52 +02:00
|
|
|
|
2016-07-17 02:25:38 +02:00
|
|
|
# other options
|
|
|
|
backend = ${toJSON cfg.backend};
|
2019-05-28 13:37:14 +02:00
|
|
|
vsync = ${lib.boolToString cfg.vSync};
|
2016-07-17 02:25:38 +02:00
|
|
|
refresh-rate = ${toString cfg.refreshRate};
|
|
|
|
'' + cfg.extraOptions);
|
|
|
|
|
|
|
|
in {
|
|
|
|
|
|
|
|
options.services.compton = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether of not to enable Compton as the X.org composite manager.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
fade = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Fade windows in and out.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
fadeDelta = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = types.addCheck types.int (x: x > 0);
|
2016-07-17 02:25:38 +02:00
|
|
|
default = 10;
|
|
|
|
example = 5;
|
|
|
|
description = ''
|
|
|
|
Time between fade animation step (in ms).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
fadeSteps = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = pairOf (floatBetween "0.01" "1.01");
|
2016-07-17 02:25:38 +02:00
|
|
|
default = [ "0.028" "0.03" ];
|
|
|
|
example = [ "0.04" "0.04" ];
|
|
|
|
description = ''
|
|
|
|
Opacity change between fade steps (in and out).
|
2017-10-16 23:52:42 +02:00
|
|
|
(numbers in range 0.01 - 1.0)
|
2016-07-17 02:25:38 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
fadeExclude = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [];
|
|
|
|
example = [
|
|
|
|
"window_type *= 'menu'"
|
|
|
|
"name ~= 'Firefox$'"
|
|
|
|
"focused = 1"
|
|
|
|
];
|
|
|
|
description = ''
|
2017-04-08 06:04:55 +02:00
|
|
|
List of conditions of windows that should not be faded.
|
2016-07-17 02:25:38 +02:00
|
|
|
See <literal>compton(1)</literal> man page for more examples.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
shadow = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Draw window shadows.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
shadowOffsets = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = pairOf types.int;
|
2016-07-17 02:25:38 +02:00
|
|
|
default = [ (-15) (-15) ];
|
|
|
|
example = [ (-10) (-15) ];
|
|
|
|
description = ''
|
|
|
|
Left and right offset for shadows (in pixels).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
shadowOpacity = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = floatBetween "0.0" "1.01";
|
2016-07-17 02:25:38 +02:00
|
|
|
default = "0.75";
|
|
|
|
example = "0.8";
|
|
|
|
description = ''
|
2017-10-16 23:52:42 +02:00
|
|
|
Window shadows opacity (number in range 0.0 - 1.0).
|
2016-07-17 02:25:38 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
shadowExclude = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [];
|
|
|
|
example = [
|
|
|
|
"window_type *= 'menu'"
|
|
|
|
"name ~= 'Firefox$'"
|
|
|
|
"focused = 1"
|
|
|
|
];
|
|
|
|
description = ''
|
2017-04-08 06:04:55 +02:00
|
|
|
List of conditions of windows that should have no shadow.
|
2016-07-17 02:25:38 +02:00
|
|
|
See <literal>compton(1)</literal> man page for more examples.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
activeOpacity = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = floatBetween "0.0" "1.01";
|
2016-07-17 02:25:38 +02:00
|
|
|
default = "1.0";
|
|
|
|
example = "0.8";
|
|
|
|
description = ''
|
2017-10-16 23:52:42 +02:00
|
|
|
Opacity of active windows (number in range 0.0 - 1.0).
|
2016-07-17 02:25:38 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
inactiveOpacity = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = floatBetween "0.1" "1.01";
|
2016-07-17 02:25:38 +02:00
|
|
|
default = "1.0";
|
|
|
|
example = "0.8";
|
|
|
|
description = ''
|
2017-10-16 23:52:42 +02:00
|
|
|
Opacity of inactive windows (number in range 0.1 - 1.0).
|
2016-07-17 02:25:38 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
menuOpacity = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = floatBetween "0.0" "1.01";
|
2016-07-17 02:25:38 +02:00
|
|
|
default = "1.0";
|
|
|
|
example = "0.8";
|
|
|
|
description = ''
|
2017-10-16 23:52:42 +02:00
|
|
|
Opacity of dropdown and popup menu (number in range 0.0 - 1.0).
|
2016-07-17 02:25:38 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2017-10-12 16:07:52 +02:00
|
|
|
opacityRules = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = [];
|
2017-10-16 23:52:42 +02:00
|
|
|
example = [
|
|
|
|
"95:class_g = 'URxvt' && !_NET_WM_STATE@:32a"
|
|
|
|
"0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
|
|
|
|
];
|
2017-10-12 16:07:52 +02:00
|
|
|
description = ''
|
2017-10-16 23:52:42 +02:00
|
|
|
Rules that control the opacity of windows, in format PERCENT:PATTERN.
|
2017-10-12 16:07:52 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2016-07-17 02:25:38 +02:00
|
|
|
backend = mkOption {
|
2017-11-28 14:02:48 +01:00
|
|
|
type = types.enum [ "glx" "xrender" "xr_glx_hybrid" ];
|
2017-10-16 23:54:10 +02:00
|
|
|
default = "xrender";
|
2016-07-17 02:25:38 +02:00
|
|
|
description = ''
|
2017-11-28 14:02:48 +01:00
|
|
|
Backend to use: <literal>glx</literal>, <literal>xrender</literal> or <literal>xr_glx_hybrid</literal>.
|
2016-07-17 02:25:38 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
vSync = mkOption {
|
2019-05-28 13:37:14 +02:00
|
|
|
type = with types; either bool
|
|
|
|
(enum [ "none" "drm" "opengl" "opengl-oml" "opengl-swc" "opengl-mswc" ]);
|
|
|
|
default = false;
|
|
|
|
apply = x:
|
|
|
|
let
|
|
|
|
res = x != "none";
|
|
|
|
msg = "The type of services.compton.vSync has changed to bool:"
|
|
|
|
+ " interpreting ${x} as ${lib.boolToString res}";
|
|
|
|
in
|
|
|
|
if isBool x then x
|
|
|
|
else warn msg res;
|
|
|
|
|
|
|
|
description = ''
|
|
|
|
Enable vertical synchronization. Chooses the best method
|
|
|
|
(drm, opengl, opengl-oml, opengl-swc, opengl-mswc) automatically.
|
|
|
|
The bool value should be used, the others are just for backwards compatibility.
|
2017-10-16 23:52:42 +02:00
|
|
|
'';
|
2016-07-17 02:25:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
refreshRate = mkOption {
|
2017-10-16 23:52:42 +02:00
|
|
|
type = types.addCheck types.int (x: x >= 0);
|
2016-07-17 02:25:38 +02:00
|
|
|
default = 0;
|
|
|
|
example = 60;
|
|
|
|
description = ''
|
|
|
|
Screen refresh rate (0 = automatically detect).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
default = pkgs.compton;
|
2016-11-21 16:26:03 +01:00
|
|
|
defaultText = "pkgs.compton";
|
2016-07-17 02:25:38 +02:00
|
|
|
example = literalExample "pkgs.compton";
|
|
|
|
description = ''
|
|
|
|
Compton derivation to use.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraOptions = mkOption {
|
2017-10-27 12:29:18 +02:00
|
|
|
type = types.lines;
|
2016-07-17 02:25:38 +02:00
|
|
|
default = "";
|
|
|
|
example = ''
|
|
|
|
unredir-if-possible = true;
|
|
|
|
dbe = true;
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Additional Compton configuration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
systemd.user.services.compton = {
|
|
|
|
description = "Compton composite manager";
|
2017-05-25 19:33:13 +02:00
|
|
|
wantedBy = [ "graphical-session.target" ];
|
|
|
|
partOf = [ "graphical-session.target" ];
|
2018-10-19 00:57:35 +02:00
|
|
|
|
|
|
|
# Temporarily fixes corrupt colours with Mesa 18
|
|
|
|
environment = mkIf (cfg.backend == "glx") {
|
|
|
|
allow_rgb10_configs = "false";
|
|
|
|
};
|
|
|
|
|
2016-07-17 02:25:38 +02:00
|
|
|
serviceConfig = {
|
|
|
|
ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
|
|
|
|
RestartSec = 3;
|
|
|
|
Restart = "always";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
environment.systemPackages = [ cfg.package ];
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|