1{
2 config,
3 lib,
4 pkgs,
5 utils,
6 ...
7}:
8let
9 cfg = config.services.desktopManager.plasma6;
10
11 inherit (pkgs) kdePackages;
12 inherit (lib)
13 literalExpression
14 mkDefault
15 mkIf
16 mkOption
17 mkPackageOption
18 types
19 ;
20
21 activationScript = ''
22 # will be rebuilt automatically
23 rm -fv "$HOME/.cache/ksycoca"*
24 '';
25in
26{
27 options = {
28 services.desktopManager.plasma6 = {
29 enable = mkOption {
30 type = types.bool;
31 default = false;
32 description = "Enable the Plasma 6 (KDE 6) desktop environment.";
33 };
34
35 enableQt5Integration = mkOption {
36 type = types.bool;
37 default = true;
38 description = "Enable Qt 5 integration (theming, etc). Disable for a pure Qt 6 system.";
39 };
40
41 notoPackage = mkPackageOption pkgs "Noto fonts - used for UI by default" {
42 default = [ "noto-fonts" ];
43 example = "noto-fonts-lgc-plus";
44 };
45 };
46
47 environment.plasma6.excludePackages = mkOption {
48 description = "List of default packages to exclude from the configuration";
49 type = types.listOf types.package;
50 default = [ ];
51 example = literalExpression "[ pkgs.kdePackages.elisa ]";
52 };
53 };
54
55 imports = [
56 (lib.mkRenamedOptionModule
57 [ "services" "xserver" "desktopManager" "plasma6" "enable" ]
58 [ "services" "desktopManager" "plasma6" "enable" ]
59 )
60 (lib.mkRenamedOptionModule
61 [ "services" "xserver" "desktopManager" "plasma6" "enableQt5Integration" ]
62 [ "services" "desktopManager" "plasma6" "enableQt5Integration" ]
63 )
64 (lib.mkRenamedOptionModule
65 [ "services" "xserver" "desktopManager" "plasma6" "notoPackage" ]
66 [ "services" "desktopManager" "plasma6" "notoPackage" ]
67 )
68 ];
69
70 config = mkIf cfg.enable {
71 assertions = [
72 {
73 assertion = cfg.enable -> !config.services.xserver.desktopManager.plasma5.enable;
74 message = "Cannot enable plasma5 and plasma6 at the same time!";
75 }
76 ];
77
78 qt.enable = true;
79 programs.xwayland.enable = true;
80 environment.systemPackages =
81 with kdePackages;
82 let
83 requiredPackages = [
84 qtwayland # Hack? To make everything run on Wayland
85 qtsvg # Needed to render SVG icons
86
87 # Frameworks with globally loadable bits
88 frameworkintegration # provides Qt plugin
89 kauth # provides helper service
90 kcoreaddons # provides extra mime type info
91 kded # provides helper service
92 kfilemetadata # provides Qt plugins
93 kguiaddons # provides geo URL handlers
94 kiconthemes # provides Qt plugins
95 kimageformats # provides Qt plugins
96 qtimageformats # provides optional image formats such as .webp and .avif
97 kio # provides helper service + a bunch of other stuff
98 kio-admin # managing files as admin
99 kio-extras # stuff for MTP, AFC, etc
100 kio-fuse # fuse interface for KIO
101 kpackage # provides kpackagetool tool
102 kservice # provides kbuildsycoca6 tool
103 kunifiedpush # provides a background service and a KCM
104 kwallet # provides helper service
105 kwallet-pam # provides helper service
106 kwalletmanager # provides KCMs and stuff
107 plasma-activities # provides plasma-activities-cli tool
108 solid # provides solid-hardware6 tool
109 phonon-vlc # provides Phonon plugin
110
111 # Core Plasma parts
112 kwin
113 kscreen
114 libkscreen
115 kscreenlocker
116 kactivitymanagerd
117 kde-cli-tools
118 kglobalacceld # keyboard shortcut daemon
119 kwrited # wall message proxy, not to be confused with kwrite
120 baloo # system indexer
121 milou # search engine atop baloo
122 kdegraphics-thumbnailers # pdf etc thumbnailer
123 polkit-kde-agent-1 # polkit auth ui
124 plasma-desktop
125 plasma-workspace
126 drkonqi # crash handler
127 kde-inotify-survey # warns the user on low inotifywatch limits
128
129 # Application integration
130 libplasma # provides Kirigami platform theme
131 plasma-integration # provides Qt platform theme
132 kde-gtk-config # syncs KDE settings to GTK
133
134 # Artwork + themes
135 breeze
136 breeze-icons
137 breeze-gtk
138 ocean-sound-theme
139 plasma-workspace-wallpapers
140 pkgs.hicolor-icon-theme # fallback icons
141 qqc2-breeze-style
142 qqc2-desktop-style
143
144 # misc Plasma extras
145 kdeplasma-addons
146 pkgs.xdg-user-dirs # recommended upstream
147
148 # Plasma utilities
149 kmenuedit
150 kinfocenter
151 plasma-systemmonitor
152 ksystemstats
153 libksysguard
154 systemsettings
155 kcmutils
156 ];
157 optionalPackages =
158 [
159 plasma-browser-integration
160 konsole
161 (lib.getBin qttools) # Expose qdbus in PATH
162 ark
163 elisa
164 gwenview
165 okular
166 kate
167 khelpcenter
168 dolphin
169 baloo-widgets # baloo information in Dolphin
170 dolphin-plugins
171 spectacle
172 ffmpegthumbs
173 krdp
174 xwaylandvideobridge # exposes Wayland windows to X11 screen capture
175 ]
176 ++ lib.optionals config.services.flatpak.enable [
177 # Since PackageKit Nix support is not there yet,
178 # only install discover if flatpak is enabled.
179 discover
180 ];
181 in
182 requiredPackages
183 ++ utils.removePackagesByName optionalPackages config.environment.plasma6.excludePackages
184 ++ lib.optionals config.services.desktopManager.plasma6.enableQt5Integration [
185 breeze.qt5
186 plasma-integration.qt5
187 pkgs.plasma5Packages.kwayland-integration
188 (
189 # Only symlink the KIO plugins, so we don't accidentally pull any services
190 # like KCMs or kcookiejar
191 let
192 kioPluginPath = "${pkgs.plasma5Packages.qtbase.qtPluginPrefix}/kf5/kio";
193 inherit (pkgs.plasma5Packages) kio;
194 in
195 pkgs.runCommand "kio5-plugins-only" { } ''
196 mkdir -p $out/${kioPluginPath}
197 ln -s ${kio}/${kioPluginPath}/* $out/${kioPluginPath}
198 ''
199 )
200 kio-extras-kf5
201 ]
202 # Optional and hardware support features
203 ++ lib.optionals config.hardware.bluetooth.enable [
204 bluedevil
205 bluez-qt
206 pkgs.openobex
207 pkgs.obexftp
208 ]
209 ++ lib.optional config.networking.networkmanager.enable plasma-nm
210 ++ lib.optional config.services.pulseaudio.enable plasma-pa
211 ++ lib.optional config.services.pipewire.pulse.enable plasma-pa
212 ++ lib.optional config.powerManagement.enable powerdevil
213 ++ lib.optional config.services.printing.enable print-manager
214 ++ lib.optional config.services.colord.enable colord-kde
215 ++ lib.optional config.services.hardware.bolt.enable plasma-thunderbolt
216 ++ lib.optional config.services.samba.enable kdenetwork-filesharing
217 ++ lib.optional config.services.xserver.wacom.enable wacomtablet
218 ++ lib.optional config.services.flatpak.enable flatpak-kcm;
219
220 environment.pathsToLink = [
221 # FIXME: modules should link subdirs of `/share` rather than relying on this
222 "/share"
223 "/libexec" # for drkonqi
224 ];
225
226 environment.etc."X11/xkb".source = config.services.xserver.xkb.dir;
227
228 # Add ~/.config/kdedefaults to XDG_CONFIG_DIRS for shells, since Plasma sets that.
229 # FIXME: maybe we should append to XDG_CONFIG_DIRS in /etc/set-environment instead?
230 environment.sessionVariables.XDG_CONFIG_DIRS = [ "$HOME/.config/kdedefaults" ];
231
232 # Needed for things that depend on other store.kde.org packages to install correctly,
233 # notably Plasma look-and-feel packages (a.k.a. Global Themes)
234 #
235 # FIXME: this is annoyingly impure and should really be fixed at source level somehow,
236 # but kpackage is a library so we can't just wrap the one thing invoking it and be done.
237 # This also means things won't work for people not on Plasma, but at least this way it
238 # works for SOME people.
239 environment.sessionVariables.KPACKAGE_DEP_RESOLVERS_PATH = "${kdePackages.frameworkintegration.out}/libexec/kf6/kpackagehandlers";
240
241 # Enable GTK applications to load SVG icons
242 programs.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
243
244 fonts.packages = [
245 cfg.notoPackage
246 pkgs.hack-font
247 ];
248 fonts.fontconfig.defaultFonts = {
249 monospace = [
250 "Hack"
251 "Noto Sans Mono"
252 ];
253 sansSerif = [ "Noto Sans" ];
254 serif = [ "Noto Serif" ];
255 };
256
257 programs.gnupg.agent.pinentryPackage = mkDefault pkgs.pinentry-qt;
258 programs.kde-pim.enable = mkDefault true;
259 programs.ssh.askPassword = mkDefault "${kdePackages.ksshaskpass.out}/bin/ksshaskpass";
260
261 # Enable helpful DBus services.
262 services.accounts-daemon.enable = true;
263 # when changing an account picture the accounts-daemon reads a temporary file containing the image which systemsettings5 may place under /tmp
264 systemd.services.accounts-daemon.serviceConfig.PrivateTmp = false;
265
266 services.power-profiles-daemon.enable = mkDefault true;
267 services.system-config-printer.enable = mkIf config.services.printing.enable (mkDefault true);
268 services.udisks2.enable = true;
269 services.upower.enable = config.powerManagement.enable;
270 services.libinput.enable = mkDefault true;
271
272 # Extra UDEV rules used by Solid
273 services.udev.packages = [
274 # libmtp has "bin", "dev", "out" outputs. UDEV rules file is in "out".
275 pkgs.libmtp.out
276 pkgs.media-player-info
277 ];
278
279 # Set up Dr. Konqi as crash handler
280 systemd.packages = [ kdePackages.drkonqi ];
281 systemd.services."drkonqi-coredump-processor@".wantedBy = [ "systemd-coredump@.service" ];
282
283 xdg.icons.enable = true;
284 xdg.icons.fallbackCursorThemes = mkDefault [ "breeze_cursors" ];
285
286 xdg.portal.enable = true;
287 xdg.portal.extraPortals = [
288 kdePackages.kwallet
289 kdePackages.xdg-desktop-portal-kde
290 pkgs.xdg-desktop-portal-gtk
291 ];
292 xdg.portal.configPackages = mkDefault [ kdePackages.plasma-workspace ];
293 services.pipewire.enable = mkDefault true;
294
295 # Enable screen reader by default
296 services.orca.enable = mkDefault true;
297
298 services.displayManager = {
299 sessionPackages = [ kdePackages.plasma-workspace ];
300 defaultSession = mkDefault "plasma";
301 };
302 services.displayManager.sddm = {
303 package = kdePackages.sddm;
304 theme = mkDefault "breeze";
305 wayland = mkDefault {
306 enable = true;
307 compositor = "kwin";
308 };
309 extraPackages = with kdePackages; [
310 breeze-icons
311 kirigami
312 libplasma
313 plasma5support
314 qtsvg
315 qtvirtualkeyboard
316 ];
317 };
318
319 security.pam.services = {
320 login.kwallet = {
321 enable = true;
322 package = kdePackages.kwallet-pam;
323 };
324 kde = {
325 allowNullPassword = true;
326 kwallet = {
327 enable = true;
328 package = kdePackages.kwallet-pam;
329 };
330 };
331 kde-fingerprint = lib.mkIf config.services.fprintd.enable { fprintAuth = true; };
332 kde-smartcard = lib.mkIf config.security.pam.p11.enable { p11Auth = true; };
333 };
334
335 security.wrappers = {
336 kwin_wayland = {
337 owner = "root";
338 group = "root";
339 capabilities = "cap_sys_nice+ep";
340 source = "${lib.getBin pkgs.kdePackages.kwin}/bin/kwin_wayland";
341 };
342 };
343
344 programs.dconf.enable = true;
345
346 programs.firefox.nativeMessagingHosts.packages = [ kdePackages.plasma-browser-integration ];
347
348 programs.chromium = {
349 enablePlasmaBrowserIntegration = true;
350 plasmaBrowserIntegrationPackage = pkgs.kdePackages.plasma-browser-integration;
351 };
352
353 programs.kdeconnect.package = kdePackages.kdeconnect-kde;
354 programs.partition-manager.package = kdePackages.partitionmanager;
355
356 # FIXME: ugly hack. See #292632 for details.
357 system.userActivationScripts.rebuildSycoca = activationScript;
358 systemd.user.services.nixos-rebuild-sycoca = {
359 description = "Rebuild KDE system configuration cache";
360 wantedBy = [ "graphical-session-pre.target" ];
361 serviceConfig.Type = "oneshot";
362 script = activationScript;
363 };
364 };
365}