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