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}