python312Packages.shiv: 1.0.7 -> 1.0.8 (#364744)
[NixPkgs.git] / nixos / modules / services / x11 / desktop-managers / gnome.nix
blobc3a3465f3a456723beb08bf9e7be0f6e74a41cda
2   config,
3   lib,
4   pkgs,
5   utils,
6   ...
7 }:
9 let
10   inherit (lib)
11     mkOption
12     types
13     mkDefault
14     mkEnableOption
15     literalExpression
16     ;
18   cfg = config.services.xserver.desktopManager.gnome;
19   serviceCfg = config.services.gnome;
21   # Prioritize nautilus by default when opening directories
22   mimeAppsList = pkgs.writeTextFile {
23     name = "gnome-mimeapps";
24     destination = "/share/applications/mimeapps.list";
25     text = ''
26       [Default Applications]
27       inode/directory=nautilus.desktop;org.gnome.Nautilus.desktop
28     '';
29   };
31   defaultFavoriteAppsOverride = ''
32     [org.gnome.shell]
33     favorite-apps=[ 'org.gnome.Epiphany.desktop', 'org.gnome.Geary.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop' ]
34   '';
36   nixos-background-light = pkgs.nixos-artwork.wallpapers.simple-blue;
37   nixos-background-dark = pkgs.nixos-artwork.wallpapers.simple-dark-gray;
39   # TODO: Having https://github.com/NixOS/nixpkgs/issues/54150 would supersede this
40   nixos-gsettings-desktop-schemas = pkgs.gnome.nixos-gsettings-overrides.override {
41     inherit (cfg) extraGSettingsOverrides extraGSettingsOverridePackages favoriteAppsOverride;
42     inherit flashbackEnabled nixos-background-dark nixos-background-light;
43   };
45   nixos-background-info = pkgs.writeTextFile rec {
46     name = "nixos-background-info";
47     text = ''
48       <?xml version="1.0"?>
49       <!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
50       <wallpapers>
51         <wallpaper deleted="false">
52           <name>Blobs</name>
53           <filename>${nixos-background-light.gnomeFilePath}</filename>
54           <filename-dark>${nixos-background-dark.gnomeFilePath}</filename-dark>
55           <options>zoom</options>
56           <shade_type>solid</shade_type>
57           <pcolor>#3a4ba0</pcolor>
58           <scolor>#2f302f</scolor>
59         </wallpaper>
60       </wallpapers>
61     '';
62     destination = "/share/gnome-background-properties/nixos.xml";
63   };
65   flashbackEnabled = cfg.flashback.enableMetacity || lib.length cfg.flashback.customSessions > 0;
66   flashbackWms =
67     lib.optional cfg.flashback.enableMetacity {
68       wmName = "metacity";
69       wmLabel = "Metacity";
70       wmCommand = "${pkgs.metacity}/bin/metacity";
71       enableGnomePanel = true;
72     }
73     ++ cfg.flashback.customSessions;
75   notExcluded =
76     pkg: mkDefault (utils.disablePackageByName pkg config.environment.gnome.excludePackages);
82   meta = {
83     doc = ./gnome.md;
84     maintainers = lib.teams.gnome.members;
85   };
87   options = {
89     services.gnome = {
90       core-os-services.enable = mkEnableOption "essential services for GNOME3";
91       core-shell.enable = mkEnableOption "GNOME Shell services";
92       core-utilities.enable = mkEnableOption "GNOME core utilities";
93       core-developer-tools.enable = mkEnableOption "GNOME core developer tools";
94       games.enable = mkEnableOption "GNOME games";
95     };
97     services.xserver.desktopManager.gnome = {
98       enable = mkOption {
99         type = types.bool;
100         default = false;
101         description = "Enable GNOME desktop manager.";
102       };
104       sessionPath = mkOption {
105         default = [ ];
106         type = types.listOf types.package;
107         example = literalExpression "[ pkgs.gpaste ]";
108         description = ''
109           Additional list of packages to be added to the session search path.
110           Useful for GNOME Shell extensions or GSettings-conditional autostart.
112           Note that this should be a last resort; patching the package is preferred (see GPaste).
113         '';
114       };
116       favoriteAppsOverride = mkOption {
117         internal = true; # this is messy
118         default = defaultFavoriteAppsOverride;
119         type = types.lines;
120         example = literalExpression ''
121           '''
122             [org.gnome.shell]
123             favorite-apps=[ 'firefox.desktop', 'org.gnome.Calendar.desktop' ]
124           '''
125         '';
126         description = "List of desktop files to put as favorite apps into pkgs.gnome-shell. These need to be installed somehow globally.";
127       };
129       extraGSettingsOverrides = mkOption {
130         default = "";
131         type = types.lines;
132         description = "Additional gsettings overrides.";
133       };
135       extraGSettingsOverridePackages = mkOption {
136         default = [ ];
137         type = types.listOf types.path;
138         description = "List of packages for which gsettings are overridden.";
139       };
141       debug = mkEnableOption "pkgs.gnome-session debug messages";
143       flashback = {
144         enableMetacity = mkEnableOption "the standard GNOME Flashback session with Metacity";
146         customSessions = mkOption {
147           type = types.listOf (
148             types.submodule {
149               options = {
150                 wmName = mkOption {
151                   type = types.strMatching "[a-zA-Z0-9_-]+";
152                   description = "A unique identifier for the window manager.";
153                   example = "xmonad";
154                 };
156                 wmLabel = mkOption {
157                   type = types.str;
158                   description = "The name of the window manager to show in the session chooser.";
159                   example = "XMonad";
160                 };
162                 wmCommand = mkOption {
163                   type = types.str;
164                   description = "The executable of the window manager to use.";
165                   example = literalExpression ''"''${pkgs.haskellPackages.xmonad}/bin/xmonad"'';
166                 };
168                 enableGnomePanel = mkOption {
169                   type = types.bool;
170                   default = true;
171                   example = false;
172                   description = "Whether to enable the GNOME panel in this session.";
173                 };
174               };
175             }
176           );
177           default = [ ];
178           description = "Other GNOME Flashback sessions to enable.";
179         };
181         panelModulePackages = mkOption {
182           default = [ pkgs.gnome-applets ];
183           defaultText = literalExpression "[ pkgs.gnome-applets ]";
184           type = types.listOf types.package;
185           description = ''
186             Packages containing modules that should be made available to `pkgs.gnome-panel` (usually for applets).
188             If you're packaging something to use here, please install the modules in `$out/lib/gnome-panel/modules`.
189           '';
190         };
191       };
192     };
194     environment.gnome.excludePackages = mkOption {
195       default = [ ];
196       example = literalExpression "[ pkgs.totem ]";
197       type = types.listOf types.package;
198       description = "Which packages gnome should exclude from the default environment";
199     };
201   };
203   config = lib.mkMerge [
204     (lib.mkIf (cfg.enable || flashbackEnabled) {
205       # Seed our configuration into nixos-generate-config
206       system.nixos-generate-config.desktopConfiguration = [
207         ''
208           # Enable the GNOME Desktop Environment.
209           services.xserver.displayManager.gdm.enable = true;
210           services.xserver.desktopManager.gnome.enable = true;
211         ''
212       ];
214       services.gnome.core-os-services.enable = true;
215       services.gnome.core-shell.enable = true;
216       services.gnome.core-utilities.enable = mkDefault true;
218       services.displayManager.sessionPackages = [ pkgs.gnome-session.sessions ];
220       environment.extraInit = ''
221         ${lib.concatMapStrings (p: ''
222           if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
223             export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
224           fi
226           if [ -d "${p}/lib/girepository-1.0" ]; then
227             export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
228             export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
229           fi
230         '') cfg.sessionPath}
231       '';
233       environment.systemPackages = cfg.sessionPath;
235       environment.sessionVariables.GNOME_SESSION_DEBUG = lib.mkIf cfg.debug "1";
237       # Override GSettings schemas
238       environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
239     })
241     (lib.mkIf flashbackEnabled {
242       services.displayManager.sessionPackages =
243         let
244           wmNames = map (wm: wm.wmName) flashbackWms;
245           namesAreUnique = lib.unique wmNames == wmNames;
246         in
247         assert (lib.assertMsg namesAreUnique "Flashback WM names must be unique.");
248         map (
249           wm:
250           pkgs.gnome-flashback.mkSessionForWm {
251             inherit (wm) wmName wmLabel wmCommand;
252           }
253         ) flashbackWms;
255       security.pam.services.gnome-flashback = {
256         enableGnomeKeyring = true;
257       };
259       systemd.packages = [
260         pkgs.gnome-flashback
261       ] ++ map pkgs.gnome-flashback.mkSystemdTargetForWm flashbackWms;
263       environment.systemPackages =
264         [
265           pkgs.gnome-flashback
266           (pkgs.gnome-panel-with-modules.override {
267             panelModulePackages = cfg.flashback.panelModulePackages;
268           })
269         ]
270         # For /share/applications/${wmName}.desktop
271         ++ (map (
272           wm: pkgs.gnome-flashback.mkWmApplication { inherit (wm) wmName wmLabel wmCommand; }
273         ) flashbackWms)
274         # For /share/pkgs.gnome-session/sessions/gnome-flashback-${wmName}.session
275         ++ (map (
276           wm: pkgs.gnome-flashback.mkGnomeSession { inherit (wm) wmName wmLabel enableGnomePanel; }
277         ) flashbackWms);
278     })
280     (lib.mkIf serviceCfg.core-os-services.enable {
281       hardware.bluetooth.enable = mkDefault true;
282       programs.dconf.enable = true;
283       security.polkit.enable = true;
284       services.accounts-daemon.enable = true;
285       services.dleyna-renderer.enable = mkDefault true;
286       services.dleyna-server.enable = mkDefault true;
287       services.power-profiles-daemon.enable = mkDefault true;
288       services.gnome.at-spi2-core.enable = true;
289       services.gnome.evolution-data-server.enable = true;
290       services.gnome.gnome-keyring.enable = true;
291       services.gnome.gnome-online-accounts.enable = mkDefault true;
292       services.gnome.localsearch.enable = mkDefault true;
293       services.gnome.tinysparql.enable = mkDefault true;
294       services.hardware.bolt.enable = mkDefault true;
295       # TODO: Enable once #177946 is resolved
296       # services.packagekit.enable = mkDefault true;
297       services.udisks2.enable = true;
298       services.upower.enable = config.powerManagement.enable;
299       services.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
301       # Explicitly enabled since GNOME will be severely broken without these.
302       xdg.mime.enable = true;
303       xdg.icons.enable = true;
305       xdg.portal.enable = true;
306       xdg.portal.extraPortals = [
307         pkgs.xdg-desktop-portal-gnome
308         pkgs.xdg-desktop-portal-gtk
309       ];
310       xdg.portal.configPackages = mkDefault [ pkgs.gnome-session ];
312       networking.networkmanager.enable = mkDefault true;
314       services.xserver.updateDbusEnvironment = true;
316       # gnome has a custom alert theme but it still
317       # inherits from the freedesktop theme.
318       environment.systemPackages = with pkgs; [
319         sound-theme-freedesktop
320       ];
322       # Needed for themes and backgrounds
323       environment.pathsToLink = [
324         "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
325       ];
326     })
328     (lib.mkIf serviceCfg.core-shell.enable {
329       services.xserver.desktopManager.gnome.sessionPath =
330         let
331           mandatoryPackages = [
332             pkgs.gnome-shell
333           ];
334           optionalPackages = [
335             pkgs.gnome-shell-extensions
336           ];
337         in
338         mandatoryPackages
339         ++ utils.removePackagesByName optionalPackages config.environment.gnome.excludePackages;
341       services.colord.enable = mkDefault true;
342       services.gnome.glib-networking.enable = true;
343       services.gnome.gnome-browser-connector.enable = mkDefault true;
344       services.gnome.gnome-initial-setup.enable = mkDefault true;
345       services.gnome.gnome-remote-desktop.enable = mkDefault true;
346       services.gnome.gnome-settings-daemon.enable = true;
347       services.gnome.gnome-user-share.enable = mkDefault true;
348       services.gnome.rygel.enable = mkDefault true;
349       services.gvfs.enable = true;
350       services.system-config-printer.enable = (lib.mkIf config.services.printing.enable (mkDefault true));
352       systemd.packages = [
353         pkgs.gnome-session
354         pkgs.gnome-shell
355       ];
357       services.udev.packages = [
358         # Force enable KMS modifiers for devices that require them.
359         # https://gitlab.gnome.org/GNOME/pkgs.mutter/-/merge_requests/1443
360         pkgs.mutter
361       ];
363       services.avahi.enable = mkDefault true;
365       services.geoclue2.enable = mkDefault true;
366       services.geoclue2.enableDemoAgent = false; # GNOME has its own geoclue agent
368       services.geoclue2.appConfig.gnome-datetime-panel = {
369         isAllowed = true;
370         isSystem = true;
371       };
372       services.geoclue2.appConfig.gnome-color-panel = {
373         isAllowed = true;
374         isSystem = true;
375       };
376       services.geoclue2.appConfig."org.gnome.Shell" = {
377         isAllowed = true;
378         isSystem = true;
379       };
381       services.orca.enable = notExcluded pkgs.orca;
383       fonts.packages = with pkgs; [
384         cantarell-fonts
385         dejavu_fonts
386         source-code-pro # Default monospace font in 3.32
387         source-sans
388       ];
390       # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/gnome-3-38/elements/core/meta-gnome-core-shell.bst
391       environment.systemPackages =
392         let
393           mandatoryPackages = [
394             pkgs.gnome-shell
395           ];
396           optionalPackages = [
397             pkgs.adwaita-icon-theme
398             nixos-background-info
399             pkgs.gnome-backgrounds
400             pkgs.gnome-bluetooth
401             pkgs.gnome-color-manager
402             pkgs.gnome-control-center
403             pkgs.gnome-shell-extensions
404             pkgs.gnome-tour # GNOME Shell detects the .desktop file on first log-in.
405             pkgs.gnome-user-docs
406             pkgs.glib # for gsettings program
407             pkgs.gnome-menus
408             pkgs.gtk3.out # for gtk-launch program
409             pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
410             pkgs.xdg-user-dirs-gtk # Used to create the default bookmarks
411           ];
412         in
413         mandatoryPackages
414         ++ utils.removePackagesByName optionalPackages config.environment.gnome.excludePackages;
415     })
417     # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/gnome-45/elements/core/meta-gnome-core-utilities.bst
418     (lib.mkIf serviceCfg.core-utilities.enable {
419       environment.systemPackages = utils.removePackagesByName (
420         [
421           pkgs.baobab
422           pkgs.epiphany
423           pkgs.gnome-text-editor
424           pkgs.gnome-calculator
425           pkgs.gnome-calendar
426           pkgs.gnome-characters
427           pkgs.gnome-clocks
428           pkgs.gnome-console
429           pkgs.gnome-contacts
430           pkgs.gnome-font-viewer
431           pkgs.gnome-logs
432           pkgs.gnome-maps
433           pkgs.gnome-music
434           pkgs.gnome-system-monitor
435           pkgs.gnome-weather
436           pkgs.loupe
437           pkgs.nautilus
438           pkgs.gnome-connections
439           pkgs.simple-scan
440           pkgs.snapshot
441           pkgs.totem
442           pkgs.yelp
443         ]
444         ++ lib.optionals config.services.flatpak.enable [
445           # Since PackageKit Nix support is not there yet,
446           # only install gnome-software if flatpak is enabled.
447           pkgs.gnome-software
448         ]
449       ) config.environment.gnome.excludePackages;
451       # Enable default program modules
452       # Since some of these have a corresponding package, we only
453       # enable that program module if the package hasn't been excluded
454       # through `environment.gnome.excludePackages`
455       programs.evince.enable = notExcluded pkgs.evince;
456       programs.file-roller.enable = notExcluded pkgs.file-roller;
457       programs.geary.enable = notExcluded pkgs.geary;
458       programs.gnome-disks.enable = notExcluded pkgs.gnome-disk-utility;
459       programs.seahorse.enable = notExcluded pkgs.seahorse;
460       services.gnome.sushi.enable = notExcluded pkgs.sushi;
462       # VTE shell integration for gnome-console
463       programs.bash.vteIntegration = mkDefault true;
464       programs.zsh.vteIntegration = mkDefault true;
466       # Let nautilus find extensions
467       # TODO: Create nautilus-with-extensions package
468       environment.sessionVariables.NAUTILUS_4_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-4";
470       # Override default mimeapps for nautilus
471       environment.sessionVariables.XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
473       environment.pathsToLink = [
474         "/share/nautilus-python/extensions"
475       ];
476     })
478     (lib.mkIf serviceCfg.games.enable {
479       environment.systemPackages = utils.removePackagesByName [
480         pkgs.aisleriot
481         pkgs.atomix
482         pkgs.five-or-more
483         pkgs.four-in-a-row
484         pkgs.gnome-2048
485         pkgs.gnome-chess
486         pkgs.gnome-klotski
487         pkgs.gnome-mahjongg
488         pkgs.gnome-mines
489         pkgs.gnome-nibbles
490         pkgs.gnome-robots
491         pkgs.gnome-sudoku
492         pkgs.gnome-taquin
493         pkgs.gnome-tetravex
494         pkgs.hitori
495         pkgs.iagno
496         pkgs.lightsoff
497         pkgs.quadrapassel
498         pkgs.swell-foop
499         pkgs.tali
500       ] config.environment.gnome.excludePackages;
501     })
503     # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/3.38.0/elements/core/meta-gnome-core-developer-tools.bst
504     (lib.mkIf serviceCfg.core-developer-tools.enable {
505       environment.systemPackages = utils.removePackagesByName [
506         pkgs.dconf-editor
507         pkgs.devhelp
508         pkgs.gnome-builder
509         # boxes would make sense in this option, however
510         # it doesn't function well enough to be included
511         # in default configurations.
512         # https://github.com/NixOS/nixpkgs/issues/60908
513         # pkgs.gnome-boxes
514       ] config.environment.gnome.excludePackages;
516       services.sysprof.enable = notExcluded pkgs.sysprof;
517     })
518   ];