nixpkgs/nixos/modules/services/x11/compton.nix
Tmplt df41d53f9d nixos/compton: fix corrupt colours with Mesa 18 on AMD
On AMD hardware with Mesa 18, compton renders some colours incorrectly
when using the glx backend. This patch sets an environmental variable
for compton so colours are rendered correctly.

Topical bug: <https://bugs.freedesktop.org/show_bug.cgi?id=104597>
2018-10-19 01:10:11 +02:00

258 lines
6.4 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
with builtins;
let
cfg = config.services.compton;
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"
(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};
menu-opacity = ${cfg.menuOpacity};
opacity-rule = [
${opacityRules}
];
# other options
backend = ${toJSON cfg.backend};
vsync = ${toJSON cfg.vSync};
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 {
type = types.addCheck types.int (x: x > 0);
default = 10;
example = 5;
description = ''
Time between fade animation step (in ms).
'';
};
fadeSteps = mkOption {
type = pairOf (floatBetween "0.01" "1.01");
default = [ "0.028" "0.03" ];
example = [ "0.04" "0.04" ];
description = ''
Opacity change between fade steps (in and out).
(numbers in range 0.01 - 1.0)
'';
};
fadeExclude = mkOption {
type = types.listOf types.str;
default = [];
example = [
"window_type *= 'menu'"
"name ~= 'Firefox$'"
"focused = 1"
];
description = ''
List of conditions of windows that should not be faded.
See <literal>compton(1)</literal> man page for more examples.
'';
};
shadow = mkOption {
type = types.bool;
default = false;
description = ''
Draw window shadows.
'';
};
shadowOffsets = mkOption {
type = pairOf types.int;
default = [ (-15) (-15) ];
example = [ (-10) (-15) ];
description = ''
Left and right offset for shadows (in pixels).
'';
};
shadowOpacity = mkOption {
type = floatBetween "0.0" "1.01";
default = "0.75";
example = "0.8";
description = ''
Window shadows opacity (number in range 0.0 - 1.0).
'';
};
shadowExclude = mkOption {
type = types.listOf types.str;
default = [];
example = [
"window_type *= 'menu'"
"name ~= 'Firefox$'"
"focused = 1"
];
description = ''
List of conditions of windows that should have no shadow.
See <literal>compton(1)</literal> man page for more examples.
'';
};
activeOpacity = mkOption {
type = floatBetween "0.0" "1.01";
default = "1.0";
example = "0.8";
description = ''
Opacity of active windows (number in range 0.0 - 1.0).
'';
};
inactiveOpacity = mkOption {
type = floatBetween "0.1" "1.01";
default = "1.0";
example = "0.8";
description = ''
Opacity of inactive windows (number in range 0.1 - 1.0).
'';
};
menuOpacity = mkOption {
type = floatBetween "0.0" "1.01";
default = "1.0";
example = "0.8";
description = ''
Opacity of dropdown and popup menu (number in range 0.0 - 1.0).
'';
};
opacityRules = mkOption {
type = types.listOf types.str;
default = [];
example = [
"95:class_g = 'URxvt' && !_NET_WM_STATE@:32a"
"0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
];
description = ''
Rules that control the opacity of windows, in format PERCENT:PATTERN.
'';
};
backend = mkOption {
type = types.enum [ "glx" "xrender" "xr_glx_hybrid" ];
default = "xrender";
description = ''
Backend to use: <literal>glx</literal>, <literal>xrender</literal> or <literal>xr_glx_hybrid</literal>.
'';
};
vSync = mkOption {
type = types.enum [
"none" "drm" "opengl"
"opengl-oml" "opengl-swc" "opengl-mswc"
];
default = "none";
example = "opengl-swc";
description = ''
Enable vertical synchronization using the specified method.
See <literal>compton(1)</literal> man page an explanation.
'';
};
refreshRate = mkOption {
type = types.addCheck types.int (x: x >= 0);
default = 0;
example = 60;
description = ''
Screen refresh rate (0 = automatically detect).
'';
};
package = mkOption {
type = types.package;
default = pkgs.compton;
defaultText = "pkgs.compton";
example = literalExample "pkgs.compton";
description = ''
Compton derivation to use.
'';
};
extraOptions = mkOption {
type = types.lines;
default = "";
example = ''
unredir-if-possible = true;
dbe = true;
'';
description = ''
Additional Compton configuration.
'';
};
};
config = mkIf cfg.enable {
systemd.user.services.compton = {
description = "Compton composite manager";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
# Temporarily fixes corrupt colours with Mesa 18
environment = mkIf (cfg.backend == "glx") {
allow_rgb10_configs = "false";
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
RestartSec = 3;
Restart = "always";
};
};
environment.systemPackages = [ cfg.package ];
};
}