diff --git a/doc/release-notes/rl-2003.adoc b/doc/release-notes/rl-2003.adoc
index 5ca3cdd7..bc94b15c 100644
--- a/doc/release-notes/rl-2003.adoc
+++ b/doc/release-notes/rl-2003.adoc
@@ -69,6 +69,11 @@ use
home-manager.users.jane = { config.config = "foo"; };
----
+* The `services.compton` module has been deprecated and instead the
+new module `services.picom` should be used. This is because Nixpkgs no
+longer packages compton, and instead packages the (mostly) compatible
+fork called picom.
+
[[sec-release-20.03-state-version-changes]]
=== State Version Changes
diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 8495e956..82bb057b 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -1415,6 +1415,34 @@ in
A new module is available: 'services.keynav'.
'';
}
+
+ {
+ time = "2020-03-24T22:17:20+00:00";
+ condition = config.services.compton.enable;
+ message = ''
+ The 'services.compton' module has been deprecated and
+ instead the new module 'services.picom' should be used. This
+ is because Nixpkgs no longer packages compton, and instead
+ packages the (mostly) compatible fork called picom.
+
+ The 'services.compton' and 'services.picom' modules have a
+ few differences:
+
+ - 'services.picom' has a new 'experimentalBackends'
+ option.
+
+ - 'vSync' is now a boolean value on 'services.picom', as
+ opposed to the string in 'services.compton'.
+
+ Migrating to the new picom service is simple - just change
+ all references to 'services.compton' to 'services.picom',
+ and adhere to the above changes.
+
+ The deprecated 'services.compton' will eventually be removed
+ in the future. Please update your configurations to use
+ 'services.picom' as soon as possible.
+ '';
+ }
];
};
}
diff --git a/modules/modules.nix b/modules/modules.nix
index d46a7d30..b714f7d2 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -141,6 +141,7 @@ let
(loadModule ./services/parcellite.nix { })
(loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; })
(loadModule ./services/pasystray.nix { })
+ (loadModule ./services/picom.nix { })
(loadModule ./services/polybar.nix { })
(loadModule ./services/random-background.nix { })
(loadModule ./services/redshift.nix { })
diff --git a/modules/services/compton.nix b/modules/services/compton.nix
index 3a67c7cb..0b8e7232 100644
--- a/modules/services/compton.nix
+++ b/modules/services/compton.nix
@@ -1,301 +1,43 @@
{ config, lib, pkgs, ... }:
-with lib;
-with builtins;
+with lib; {
+ imports = let
+ old = n: [ "services" "compton" n ];
+ new = n: [ "services" "picom" n ];
+ in [
+ (mkRenamedOptionModule (old "activeOpacity") (new "activeOpacity"))
+ (mkRenamedOptionModule (old "backend") (new "backend"))
+ (mkRenamedOptionModule (old "blur") (new "blur"))
+ (mkRenamedOptionModule (old "blurExclude") (new "blurExclude"))
+ (mkRenamedOptionModule (old "extraOptions") (new "extraOptions"))
+ (mkRenamedOptionModule (old "fade") (new "fade"))
+ (mkRenamedOptionModule (old "fadeDelta") (new "fadeDelta"))
+ (mkRenamedOptionModule (old "fadeExclude") (new "fadeExclude"))
+ (mkRenamedOptionModule (old "fadeSteps") (new "fadeSteps"))
+ (mkRenamedOptionModule (old "inactiveDim") (new "inactiveDim"))
+ (mkRenamedOptionModule (old "inactiveOpacity") (new "inactiveOpacity"))
+ (mkRenamedOptionModule (old "menuOpacity") (new "menuOpacity"))
+ (mkRenamedOptionModule (old "noDNDShadow") (new "noDNDShadow"))
+ (mkRenamedOptionModule (old "noDockShadow") (new "noDockShadow"))
+ (mkRenamedOptionModule (old "opacityRule") (new "opacityRule"))
+ (mkRenamedOptionModule (old "package") (new "package"))
+ (mkRenamedOptionModule (old "refreshRate") (new "refreshRate"))
+ (mkRenamedOptionModule (old "shadow") (new "shadow"))
+ (mkRenamedOptionModule (old "shadowExclude") (new "shadowExclude"))
+ (mkRenamedOptionModule (old "shadowOffsets") (new "shadowOffsets"))
+ (mkRenamedOptionModule (old "shadowOpacity") (new "shadowOpacity"))
+ (mkChangedOptionModule (old "vSync") (new "vSync") (v: v != "none"))
+ ];
-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};
- no-dock-shadow = ${toJSON cfg.noDockShadow};
- no-dnd-shadow = ${toJSON cfg.noDNDShadow};
- '' + optionalString cfg.blur ''
-
- # blur
- blur-background = true;
- blur-background-exclude = ${toJSON cfg.blurExclude};
- '' + ''
-
- # opacity
- active-opacity = ${cfg.activeOpacity};
- inactive-opacity = ${cfg.inactiveOpacity};
- inactive-dim = ${cfg.inactiveDim};
- menu-opacity = ${cfg.menuOpacity};
- opacity-rule = ${toJSON cfg.opacityRule};
-
- # other options
- backend = ${toJSON cfg.backend};
- vsync = ${toJSON cfg.vSync};
- refresh-rate = ${toString cfg.refreshRate};
- '' + cfg.extraOptions);
-
-in {
-
- options.services.compton = {
- enable = mkEnableOption "Compton X11 compositor";
-
- blur = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Enable background blur on transparent windows.
- '';
- };
-
- blurExclude = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "class_g = 'slop'" "class_i = 'polybar'" ];
- description = ''
- List of windows to exclude background blur.
- See the
-
- compton
- 1
-
- man page for more examples.
- '';
- };
-
- fade = mkOption {
- type = types.bool;
- default = false;
- 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 conditions of windows that should not be faded.
- See the
-
- compton
- 1
-
- man page for more examples.
- '';
- };
-
- shadow = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Draw window shadows.
- '';
- };
-
- shadowOffsets = mkOption {
- type = types.listOf types.int;
- default = [ (-15) (-15) ];
- example = [ (-10) (-15) ];
- description = ''
- Horizontal and vertical offsets 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 conditions of windows that should have no shadow.
- See the
-
- compton
- 1
-
- man page for more examples.
- '';
- };
-
- noDockShadow = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Avoid shadow on docks.
- '';
- };
-
- noDNDShadow = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Avoid shadow on drag-and-drop windows.
- '';
- };
-
- activeOpacity = mkOption {
- type = types.str;
- default = "1.0";
- example = "0.8";
- description = ''
- Opacity of active windows.
- '';
- };
-
- inactiveDim = mkOption {
- type = types.str;
- default = "0.0";
- example = "0.2";
- description = ''
- Dim inactive 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.
- '';
- };
-
- opacityRule = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "87:class_i ?= 'scratchpad'" "91:class_i ?= 'xterm'" ];
- description = ''
- List of opacity rules.
- See the
-
- compton
- 1
-
- man page for more examples.
- '';
- };
-
- 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 the
-
- compton
- 1
-
- man page for 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;
- defaultText = literalExample "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.
- '';
- };
+ options.services.compton.enable = mkEnableOption "Compton X11 compositor" // {
+ visible = false;
};
- config = mkIf cfg.enable {
- home.packages = [ cfg.package ];
+ config = mkIf config.services.compton.enable {
+ warnings = [
+ "Obsolete option `services.compton.enable' is used. It was renamed to `services.picom.enable'."
+ ];
- systemd.user.services.compton = {
- Unit = {
- Description = "Compton X11 compositor";
- After = [ "graphical-session-pre.target" ];
- PartOf = [ "graphical-session.target" ];
- };
-
- Install = { WantedBy = [ "graphical-session.target" ]; };
-
- Service = {
- ExecStart = "${cfg.package}/bin/compton --config ${configFile}";
- Restart = "always";
- RestartSec = 3;
- } // optionalAttrs (cfg.backend == "glx") {
- # Temporarily fixes corrupt colours with Mesa 18.
- Environment = [ "allow_rgb10_configs=false" ];
- };
- };
+ services.picom.enable = true;
};
}
diff --git a/modules/services/picom.nix b/modules/services/picom.nix
new file mode 100644
index 00000000..4c4da8de
--- /dev/null
+++ b/modules/services/picom.nix
@@ -0,0 +1,311 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+with builtins;
+
+let
+
+ cfg = config.services.picom;
+
+ configFile = pkgs.writeText "picom.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};
+ '' + optionalString cfg.blur ''
+
+ # blur
+ blur-background = true;
+ blur-background-exclude = ${toJSON cfg.blurExclude};
+ '' + ''
+
+ # opacity
+ active-opacity = ${cfg.activeOpacity};
+ inactive-opacity = ${cfg.inactiveOpacity};
+ inactive-dim = ${cfg.inactiveDim};
+ opacity-rule = ${toJSON cfg.opacityRule};
+
+ wintypes:
+ {
+ dock = { shadow = ${toJSON (!cfg.noDockShadow)}; };
+ dnd = { shadow = ${toJSON (!cfg.noDNDShadow)}; };
+ popup_menu = { opacity = ${cfg.menuOpacity}; };
+ dropdown_menu = { opacity = ${cfg.menuOpacity}; };
+ };
+
+ # other options
+ backend = ${toJSON cfg.backend};
+ vsync = ${toJSON cfg.vSync};
+ refresh-rate = ${toString cfg.refreshRate};
+ '' + cfg.extraOptions);
+
+in {
+
+ options.services.picom = {
+ enable = mkEnableOption "Picom X11 compositor";
+
+ blur = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable background blur on transparent windows.
+ '';
+ };
+
+ blurExclude = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "class_g = 'slop'" "class_i = 'polybar'" ];
+ description = ''
+ List of windows to exclude background blur.
+ See the
+
+ picom
+ 1
+
+ man page for more examples.
+ '';
+ };
+
+ experimentalBackends = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to use the new experimental backends.
+ '';
+ };
+
+ fade = mkOption {
+ type = types.bool;
+ default = false;
+ 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 conditions of windows that should not be faded.
+ See the
+
+ picom
+ 1
+
+ man page for more examples.
+ '';
+ };
+
+ shadow = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Draw window shadows.
+ '';
+ };
+
+ shadowOffsets = mkOption {
+ type = types.listOf types.int;
+ default = [ (-15) (-15) ];
+ example = [ (-10) (-15) ];
+ description = ''
+ Horizontal and vertical offsets 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 conditions of windows that should have no shadow.
+ See the
+
+ picom
+ 1
+
+ man page for more examples.
+ '';
+ };
+
+ noDockShadow = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Avoid shadow on docks.
+ '';
+ };
+
+ noDNDShadow = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Avoid shadow on drag-and-drop windows.
+ '';
+ };
+
+ activeOpacity = mkOption {
+ type = types.str;
+ default = "1.0";
+ example = "0.8";
+ description = ''
+ Opacity of active windows.
+ '';
+ };
+
+ inactiveDim = mkOption {
+ type = types.str;
+ default = "0.0";
+ example = "0.2";
+ description = ''
+ Dim inactive 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.
+ '';
+ };
+
+ opacityRule = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "87:class_i ?= 'scratchpad'" "91:class_i ?= 'xterm'" ];
+ description = ''
+ List of opacity rules.
+ See the
+
+ picom
+ 1
+
+ man page for more examples.
+ '';
+ };
+
+ backend = mkOption {
+ type = types.str;
+ default = "glx";
+ description = ''
+ Backend to use: glx or xrender.
+ '';
+ };
+
+ vSync = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable vertical synchronization.
+ '';
+ };
+
+ refreshRate = mkOption {
+ type = types.int;
+ default = 0;
+ example = 60;
+ description = ''
+ Screen refresh rate (0 = automatically detect).
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.picom;
+ defaultText = literalExample "pkgs.picom";
+ example = literalExample "pkgs.picom";
+ description = ''
+ picom derivation to use.
+ '';
+ };
+
+ extraOptions = mkOption {
+ type = types.str;
+ default = "";
+ example = ''
+ unredir-if-possible = true;
+ dbe = true;
+ '';
+ description = ''
+ Additional Picom configuration.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ home.packages = [ cfg.package ];
+
+ systemd.user.services.picom = {
+ Unit = {
+ Description = "Picom X11 compositor";
+ After = [ "graphical-session-pre.target" ];
+ PartOf = [ "graphical-session.target" ];
+ };
+
+ Install = { WantedBy = [ "graphical-session.target" ]; };
+
+ Service = let
+ experimentalBackendsFlag =
+ if cfg.experimentalBackends then " --experimental-backends" else "";
+ in {
+ ExecStart = "${cfg.package}/bin/picom --config ${configFile}"
+ + experimentalBackendsFlag;
+ Restart = "always";
+ RestartSec = 3;
+ } // optionalAttrs (cfg.backend == "glx") {
+ # Temporarily fixes corrupt colours with Mesa 18.
+ Environment = [ "allow_rgb10_configs=false" ];
+ };
+ };
+ };
+}