diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 667d013e2104..709639919864 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -477,6 +477,7 @@
./services/web-servers/winstone.nix
./services/web-servers/zope2.nix
./services/x11/colord.nix
+ ./services/x11/compton.nix
./services/x11/unclutter.nix
./services/x11/desktop-managers/default.nix
./services/x11/display-managers/auto.nix
diff --git a/nixos/modules/services/x11/compton.nix b/nixos/modules/services/x11/compton.nix
new file mode 100644
index 000000000000..bda4eec01026
--- /dev/null
+++ b/nixos/modules/services/x11/compton.nix
@@ -0,0 +1,225 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+with builtins;
+
+let
+
+ cfg = config.services.compton;
+
+ 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};
+
+ # 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;
+ example = true;
+ description = ''
+ Whether of not to enable Compton as the X.org composite manager.
+ '';
+ };
+
+ fade = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Fade windows in and out.
+ '';
+ };
+
+ fadeDelta = mkOption {
+ type = types.int;
+ default = 10;
+ example = 5;
+ description = ''
+ Time between fade animation step (in ms).
+ '';
+ };
+
+ fadeSteps = mkOption {
+ type = types.listOf types.str;
+ default = [ "0.028" "0.03" ];
+ example = [ "0.04" "0.04" ];
+ description = ''
+ Opacity change between fade steps (in and out).
+ '';
+ };
+
+ fadeExclude = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [
+ "window_type *= 'menu'"
+ "name ~= 'Firefox$'"
+ "focused = 1"
+ ];
+ description = ''
+ List of condition of windows that should have no shadow.
+ See compton(1) man page for more examples.
+ '';
+ };
+
+ shadow = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Draw window shadows.
+ '';
+ };
+
+ shadowOffsets = mkOption {
+ type = types.listOf types.int;
+ default = [ (-15) (-15) ];
+ example = [ (-10) (-15) ];
+ description = ''
+ Left and right offset for shadows (in pixels).
+ '';
+ };
+
+ shadowOpacity = mkOption {
+ type = types.str;
+ default = "0.75";
+ example = "0.8";
+ description = ''
+ Window shadows opacity (number in range 0 - 1).
+ '';
+ };
+
+ shadowExclude = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [
+ "window_type *= 'menu'"
+ "name ~= 'Firefox$'"
+ "focused = 1"
+ ];
+ description = ''
+ List of condition of windows that should have no shadow.
+ See compton(1) man page for more examples.
+ '';
+ };
+
+ activeOpacity = mkOption {
+ type = types.str;
+ default = "1.0";
+ example = "0.8";
+ description = ''
+ Opacity of active windows.
+ '';
+ };
+
+ inactiveOpacity = mkOption {
+ type = types.str;
+ default = "1.0";
+ example = "0.8";
+ description = ''
+ Opacity of inactive windows.
+ '';
+ };
+
+ menuOpacity = mkOption {
+ type = types.str;
+ default = "1.0";
+ example = "0.8";
+ description = ''
+ Opacity of dropdown and popup menu.
+ '';
+ };
+
+ backend = mkOption {
+ type = types.str;
+ default = "glx";
+ description = ''
+ Backend to use: glx or xrender.
+ '';
+ };
+
+ vSync = mkOption {
+ type = types.str;
+ default = "none";
+ example = "opengl-swc";
+ description = ''
+ Enable vertical synchronization using the specified method.
+ See compton(1) man page available methods.
+ '';
+ };
+
+ refreshRate = mkOption {
+ type = types.int;
+ default = 0;
+ example = 60;
+ description = ''
+ Screen refresh rate (0 = automatically detect).
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.compton;
+ example = literalExample "pkgs.compton";
+ description = ''
+ Compton derivation to use.
+ '';
+ };
+
+ extraOptions = mkOption {
+ type = types.str;
+ 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 = [ "default.target" ];
+ serviceConfig = {
+ ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
+ RestartSec = 3;
+ Restart = "always";
+ };
+ environment.DISPLAY = ":0";
+ };
+
+ environment.systemPackages = [ cfg.package ];
+ };
+
+}