python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / x11 / picom.nix
blobd42cf1d7412fe0422280101643921506d85ef77a
1 { config, lib, options, pkgs, ... }:
3 with lib;
5 let
7   cfg = config.services.picom;
8   opt = options.services.picom;
10   pairOf = x: with types;
11     addCheck (listOf x) (y: length y == 2)
12     // { description = "pair of ${x.description}"; };
14   mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
16   # Basically a tinkered lib.generators.mkKeyValueDefault
17   # It either serializes a top-level definition "key: { values };"
18   # or an expression "key = { values };"
19   mkAttrsString = top:
20     mapAttrsToList (k: v:
21       let sep = if (top && isAttrs v) then ":" else "=";
22       in "${escape [ sep ] k}${sep}${mkValueString v};");
24   # This serializes a Nix expression to the libconfig format.
25   mkValueString = v:
26          if types.bool.check  v then boolToString v
27     else if types.int.check   v then toString v
28     else if types.float.check v then toString v
29     else if types.str.check   v then "\"${escape [ "\"" ] v}\""
30     else if builtins.isList   v then "[ ${concatMapStringsSep " , " mkValueString v} ]"
31     else if types.attrs.check v then "{ ${concatStringsSep " " (mkAttrsString false v) } }"
32     else throw ''
33                  invalid expression used in option services.picom.settings:
34                  ${v}
35                '';
37   toConf = attrs: concatStringsSep "\n" (mkAttrsString true cfg.settings);
39   configFile = pkgs.writeText "picom.conf" (toConf cfg.settings);
41 in {
43   imports = [
44     (mkAliasOptionModule [ "services" "compton" ] [ "services" "picom" ])
45     (mkRemovedOptionModule [ "services" "picom" "refreshRate" ] ''
46       This option corresponds to `refresh-rate`, which has been unused
47       since picom v6 and was subsequently removed by upstream.
48       See https://github.com/yshui/picom/commit/bcbc410
49     '')
50   ];
52   options.services.picom = {
53     enable = mkOption {
54       type = types.bool;
55       default = false;
56       description = lib.mdDoc ''
57         Whether or not to enable Picom as the X.org composite manager.
58       '';
59     };
61     experimentalBackends = mkOption {
62       type = types.bool;
63       default = false;
64       description = lib.mdDoc ''
65         Whether to use the unstable new reimplementation of the backends.
66       '';
67     };
69     fade = mkOption {
70       type = types.bool;
71       default = false;
72       description = lib.mdDoc ''
73         Fade windows in and out.
74       '';
75     };
77     fadeDelta = mkOption {
78       type = types.ints.positive;
79       default = 10;
80       example = 5;
81       description = lib.mdDoc ''
82         Time between fade animation step (in ms).
83       '';
84     };
86     fadeSteps = mkOption {
87       type = pairOf (types.numbers.between 0.01 1);
88       default = [ 0.028 0.03 ];
89       example = [ 0.04 0.04 ];
90       description = lib.mdDoc ''
91         Opacity change between fade steps (in and out).
92       '';
93     };
95     fadeExclude = mkOption {
96       type = types.listOf types.str;
97       default = [];
98       example = [
99         "window_type *= 'menu'"
100         "name ~= 'Firefox$'"
101         "focused = 1"
102       ];
103       description = lib.mdDoc ''
104         List of conditions of windows that should not be faded.
105         See `picom(1)` man page for more examples.
106       '';
107     };
109     shadow = mkOption {
110       type = types.bool;
111       default = false;
112       description = lib.mdDoc ''
113         Draw window shadows.
114       '';
115     };
117     shadowOffsets = mkOption {
118       type = pairOf types.int;
119       default = [ (-15) (-15) ];
120       example = [ (-10) (-15) ];
121       description = lib.mdDoc ''
122         Left and right offset for shadows (in pixels).
123       '';
124     };
126     shadowOpacity = mkOption {
127       type = types.numbers.between 0 1;
128       default = 0.75;
129       example = 0.8;
130       description = lib.mdDoc ''
131         Window shadows opacity.
132       '';
133     };
135     shadowExclude = mkOption {
136       type = types.listOf types.str;
137       default = [];
138       example = [
139         "window_type *= 'menu'"
140         "name ~= 'Firefox$'"
141         "focused = 1"
142       ];
143       description = lib.mdDoc ''
144         List of conditions of windows that should have no shadow.
145         See `picom(1)` man page for more examples.
146       '';
147     };
149     activeOpacity = mkOption {
150       type = types.numbers.between 0 1;
151       default = 1.0;
152       example = 0.8;
153       description = lib.mdDoc ''
154         Opacity of active windows.
155       '';
156     };
158     inactiveOpacity = mkOption {
159       type = types.numbers.between 0.1 1;
160       default = 1.0;
161       example = 0.8;
162       description = lib.mdDoc ''
163         Opacity of inactive windows.
164       '';
165     };
167     menuOpacity = mkOption {
168       type = types.numbers.between 0 1;
169       default = 1.0;
170       example = 0.8;
171       description = lib.mdDoc ''
172         Opacity of dropdown and popup menu.
173       '';
174     };
176     wintypes = mkOption {
177       type = types.attrs;
178       default = {
179         popup_menu = { opacity = cfg.menuOpacity; };
180         dropdown_menu = { opacity = cfg.menuOpacity; };
181       };
182       defaultText = literalExpression ''
183         {
184           popup_menu = { opacity = config.${opt.menuOpacity}; };
185           dropdown_menu = { opacity = config.${opt.menuOpacity}; };
186         }
187       '';
188       example = {};
189       description = lib.mdDoc ''
190         Rules for specific window types.
191       '';
192     };
194     opacityRules = mkOption {
195       type = types.listOf types.str;
196       default = [];
197       example = [
198         "95:class_g = 'URxvt' && !_NET_WM_STATE@:32a"
199         "0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
200       ];
201       description = lib.mdDoc ''
202         Rules that control the opacity of windows, in format PERCENT:PATTERN.
203       '';
204     };
206     backend = mkOption {
207       type = types.enum [ "glx" "xrender" "xr_glx_hybrid" ];
208       default = "xrender";
209       description = lib.mdDoc ''
210         Backend to use: `glx`, `xrender` or `xr_glx_hybrid`.
211       '';
212     };
214     vSync = mkOption {
215       type = with types; either bool
216         (enum [ "none" "drm" "opengl" "opengl-oml" "opengl-swc" "opengl-mswc" ]);
217       default = false;
218       apply = x:
219         let
220           res = x != "none";
221           msg = "The type of services.picom.vSync has changed to bool:"
222                 + " interpreting ${x} as ${boolToString res}";
223         in
224           if isBool x then x
225           else warn msg res;
227       description = lib.mdDoc ''
228         Enable vertical synchronization. Chooses the best method
229         (drm, opengl, opengl-oml, opengl-swc, opengl-mswc) automatically.
230         The bool value should be used, the others are just for backwards compatibility.
231       '';
232     };
234     settings = with types;
235     let
236       scalar = oneOf [ bool int float str ]
237         // { description = "scalar types"; };
239       libConfig = oneOf [ scalar (listOf libConfig) (attrsOf libConfig) ]
240         // { description = "libconfig type"; };
242       topLevel = attrsOf libConfig
243         // { description = ''
244                libconfig configuration. The format consists of an attributes
245                set (called a group) of settings. Each setting can be a scalar type
246                (boolean, integer, floating point number or string), a list of
247                scalars or a group itself
248              '';
249            };
251     in mkOption {
252       type = topLevel;
253       default = { };
254       example = literalExpression ''
255         blur =
256           { method = "gaussian";
257             size = 10;
258             deviation = 5.0;
259           };
260       '';
261       description = lib.mdDoc ''
262         Picom settings. Use this option to configure Picom settings not exposed
263         in a NixOS option or to bypass one.  For the available options see the
264         CONFIGURATION FILES section at `picom(1)`.
265       '';
266     };
267   };
269   config = mkIf cfg.enable {
270     services.picom.settings = mkDefaultAttrs {
271       # fading
272       fading           = cfg.fade;
273       fade-delta       = cfg.fadeDelta;
274       fade-in-step     = elemAt cfg.fadeSteps 0;
275       fade-out-step    = elemAt cfg.fadeSteps 1;
276       fade-exclude     = cfg.fadeExclude;
278       # shadows
279       shadow           = cfg.shadow;
280       shadow-offset-x  = elemAt cfg.shadowOffsets 0;
281       shadow-offset-y  = elemAt cfg.shadowOffsets 1;
282       shadow-opacity   = cfg.shadowOpacity;
283       shadow-exclude   = cfg.shadowExclude;
285       # opacity
286       active-opacity   = cfg.activeOpacity;
287       inactive-opacity = cfg.inactiveOpacity;
289       wintypes         = cfg.wintypes;
291       opacity-rule     = cfg.opacityRules;
293       # other options
294       backend          = cfg.backend;
295       vsync            = cfg.vSync;
296     };
298     systemd.user.services.picom = {
299       description = "Picom composite manager";
300       wantedBy = [ "graphical-session.target" ];
301       partOf = [ "graphical-session.target" ];
303       # Temporarily fixes corrupt colours with Mesa 18
304       environment = mkIf (cfg.backend == "glx") {
305         allow_rgb10_configs = "false";
306       };
308       serviceConfig = {
309         ExecStart = "${pkgs.picom}/bin/picom --config ${configFile}"
310           + (optionalString cfg.experimentalBackends " --experimental-backends");
311         RestartSec = 3;
312         Restart = "always";
313       };
314     };
316     environment.systemPackages = [ pkgs.picom ];
317   };
319   meta.maintainers = with lib.maintainers; [ rnhmjoj ];