1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.xserver.desktopManager.gnome3;
7 gnome3 = config.environment.gnome3.packageSet;
8
9 # Remove packages of ys from xs, based on their names
10 removePackagesByName = xs: ys:
11 let
12 pkgName = drv: (builtins.parseDrvName drv.name).name;
13 ysNames = map pkgName ys;
14 res = (filter (x: !(builtins.elem (pkgName x) ysNames)) xs);
15 in
16 filter (x: !(builtins.elem (pkgName x) ysNames)) xs;
17
18 # Prioritize nautilus by default when opening directories
19 mimeAppsList = pkgs.writeTextFile {
20 name = "gnome-mimeapps";
21 destination = "/share/applications/mimeapps.list";
22 text = ''
23 [Default Applications]
24 inode/directory=nautilus.desktop;org.gnome.Nautilus.desktop
25 '';
26 };
27
28 nixos-gsettings-desktop-schemas = pkgs.runCommand "nixos-gsettings-desktop-schemas" {}
29 ''
30 mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
31 cp -rf ${gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
32
33 ${concatMapStrings (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n") cfg.extraGSettingsOverridePackages}
34
35 chmod -R a+w $out/share/gsettings-schemas/nixos-gsettings-overrides
36 cat - > $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
37 [org.gnome.desktop.background]
38 picture-uri='${pkgs.nixos-artwork.wallpapers.gnome-dark}/share/artwork/gnome/Gnome_Dark.png'
39
40 [org.gnome.desktop.screensaver]
41 picture-uri='${pkgs.nixos-artwork.wallpapers.gnome-dark}/share/artwork/gnome/Gnome_Dark.png'
42
43 ${cfg.extraGSettingsOverrides}
44 EOF
45
46 ${pkgs.glib.dev}/bin/glib-compile-schemas $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/
47 '';
48
49in {
50
51 options = {
52
53 services.xserver.desktopManager.gnome3 = {
54 enable = mkOption {
55 default = false;
56 description = "Enable Gnome 3 desktop manager.";
57 };
58
59 sessionPath = mkOption {
60 default = [];
61 example = literalExample "[ pkgs.gnome3.gpaste ]";
62 description = "Additional list of packages to be added to the session search path.
63 Useful for gnome shell extensions or gsettings-conditionated autostart.";
64 apply = list: list ++ [ gnome3.gnome_shell gnome3.gnome-shell-extensions ];
65 };
66
67 extraGSettingsOverrides = mkOption {
68 default = "";
69 type = types.lines;
70 description = "Additional gsettings overrides.";
71 };
72
73 extraGSettingsOverridePackages = mkOption {
74 default = [];
75 type = types.listOf types.path;
76 description = "List of packages for which gsettings are overridden.";
77 };
78
79 debug = mkEnableOption "gnome-session debug messages";
80 };
81
82 environment.gnome3.packageSet = mkOption {
83 default = null;
84 example = literalExample "pkgs.gnome3_22";
85 description = "Which GNOME 3 package set to use.";
86 apply = p: if p == null then pkgs.gnome3 else p;
87 };
88
89 environment.gnome3.excludePackages = mkOption {
90 default = [];
91 example = literalExample "[ pkgs.gnome3.totem ]";
92 type = types.listOf types.package;
93 description = "Which packages gnome should exclude from the default environment";
94 };
95
96 };
97
98 config = mkIf cfg.enable {
99
100 # Enable helpful DBus services.
101 security.polkit.enable = true;
102 services.udisks2.enable = true;
103 services.accounts-daemon.enable = true;
104 services.geoclue2.enable = mkDefault true;
105 services.gnome3.at-spi2-core.enable = true;
106 services.gnome3.evolution-data-server.enable = true;
107 services.gnome3.gnome-disks.enable = mkDefault true;
108 services.gnome3.gnome-documents.enable = mkDefault true;
109 services.gnome3.gnome-keyring.enable = true;
110 services.gnome3.gnome-online-accounts.enable = mkDefault true;
111 services.gnome3.gnome-terminal-server.enable = mkDefault true;
112 services.gnome3.gnome-user-share.enable = mkDefault true;
113 services.gnome3.gvfs.enable = true;
114 services.gnome3.seahorse.enable = mkDefault true;
115 services.gnome3.sushi.enable = mkDefault true;
116 services.gnome3.tracker.enable = mkDefault true;
117 hardware.pulseaudio.enable = mkDefault true;
118 services.telepathy.enable = mkDefault true;
119 networking.networkmanager.enable = mkDefault true;
120 services.upower.enable = config.powerManagement.enable;
121 services.dbus.packages = mkIf config.services.printing.enable [ pkgs.system-config-printer ];
122 services.colord.enable = mkDefault true;
123 services.packagekit.enable = mkDefault true;
124 hardware.bluetooth.enable = mkDefault true;
125 services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
126 services.udev.packages = [ pkgs.gnome3.gnome_settings_daemon ];
127 systemd.packages = [ pkgs.gnome3.vino ];
128
129 # If gnome3 is installed, build vim for gtk3 too.
130 nixpkgs.config.vim.gui = "gtk3";
131
132 fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];
133
134 services.xserver.desktopManager.session = singleton
135 { name = "gnome3";
136 bgSupport = true;
137 start = ''
138 # Set GTK_DATA_PREFIX so that GTK+ can find the themes
139 export GTK_DATA_PREFIX=${config.system.path}
140
141 # find theme engines
142 export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0
143
144 export XDG_MENU_PREFIX=gnome
145
146 ${concatMapStrings (p: ''
147 if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
148 export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
149 fi
150
151 if [ -d "${p}/lib/girepository-1.0" ]; then
152 export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
153 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
154 fi
155 '') cfg.sessionPath}
156
157 # Override default mimeapps
158 export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${mimeAppsList}/share
159
160 # Override gsettings-desktop-schema
161 export XDG_DATA_DIRS=${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS
162
163 # Let nautilus find extensions
164 export NAUTILUS_EXTENSION_DIR=${config.system.path}/lib/nautilus/extensions-3.0/
165
166 # Find the mouse
167 export XCURSOR_PATH=~/.icons:${config.system.path}/share/icons
168
169 # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
170 ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
171
172 ${gnome3.gnome_session}/bin/gnome-session ${optionalString cfg.debug "--debug"} &
173 waitPID=$!
174 '';
175 };
176
177 services.xserver.updateDbusEnvironment = true;
178
179 environment.variables.GIO_EXTRA_MODULES = [ "${lib.getLib gnome3.dconf}/lib/gio/modules"
180 "${gnome3.glib_networking.out}/lib/gio/modules"
181 "${gnome3.gvfs}/lib/gio/modules" ];
182 environment.systemPackages = gnome3.corePackages ++ cfg.sessionPath
183 ++ (removePackagesByName gnome3.optionalPackages config.environment.gnome3.excludePackages);
184
185 # Use the correct gnome3 packageSet
186 networking.networkmanager.basePackages =
187 { inherit (pkgs) networkmanager modemmanager wpa_supplicant;
188 inherit (gnome3) networkmanager_openvpn networkmanager_vpnc
189 networkmanager_openconnect networkmanager_fortisslvpn
190 networkmanager_pptp networkmanager_iodine
191 networkmanager_l2tp; };
192
193 # Needed for themes and backgrounds
194 environment.pathsToLink = [ "/share" ];
195
196 };
197
198
199}