1# SPDX-License-Identifier: MIT
2# SPDX-FileCopyrightText: Lily Foster <lily@lily.flowers>
3# Portions of this code are adapted from nixos-cosmic
4# https://github.com/lilyinstarlight/nixos-cosmic
5
6{
7 config,
8 lib,
9 pkgs,
10 utils,
11 ...
12}:
13
14let
15 cfg = config.services.desktopManager.cosmic;
16 notExcluded = pkg: utils.disablePackageByName pkg config.environment.cosmic.excludePackages;
17 excludedCorePkgs = lib.lists.intersectLists corePkgs config.environment.cosmic.excludePackages;
18 # **ONLY ADD PACKAGES WITHOUT WHICH COSMIC CRASHES, NOTHING ELSE**
19 corePkgs =
20 with pkgs;
21 [
22 cosmic-applets
23 cosmic-applibrary
24 cosmic-bg
25 cosmic-comp
26 cosmic-files
27 config.services.displayManager.cosmic-greeter.package
28 cosmic-idle
29 cosmic-initial-setup
30 cosmic-launcher
31 cosmic-notifications
32 cosmic-osd
33 cosmic-panel
34 cosmic-session
35 cosmic-settings
36 cosmic-settings-daemon
37 cosmic-workspaces-epoch
38 ]
39 ++ lib.optionals cfg.xwayland.enable [
40 # Why would you want to enable XWayland but exclude the package
41 # providing XWayland support? Doesn't make sense. Add `xwayland` to the
42 # `corePkgs` list.
43 xwayland
44 ];
45in
46{
47 meta.maintainers = lib.teams.cosmic.members;
48
49 options = {
50 services.desktopManager.cosmic = {
51 enable = lib.mkEnableOption "COSMIC desktop environment";
52
53 showExcludedPkgsWarning = lib.mkEnableOption "the warning for excluding core packages" // {
54 default = true;
55 };
56
57 xwayland.enable = lib.mkEnableOption "Xwayland support for the COSMIC compositor" // {
58 default = true;
59 };
60 };
61
62 environment.cosmic.excludePackages = lib.mkOption {
63 description = "List of packages to exclude from the COSMIC environment.";
64 type = lib.types.listOf lib.types.package;
65 default = [ ];
66 example = lib.literalExpression "[ pkgs.cosmic-player ]";
67 };
68 };
69
70 config = lib.mkIf cfg.enable {
71 # Environment packages
72 environment.pathsToLink = [
73 "/share/backgrounds"
74 "/share/cosmic"
75 "/share/cosmic-layouts"
76 "/share/cosmic-themes"
77 ];
78 environment.systemPackages = utils.removePackagesByName (
79 corePkgs
80 ++ (
81 with pkgs;
82 [
83 adwaita-icon-theme
84 alsa-utils
85 cosmic-edit
86 cosmic-icons
87 cosmic-player
88 cosmic-randr
89 cosmic-screenshot
90 cosmic-term
91 cosmic-wallpapers
92 hicolor-icon-theme
93 playerctl
94 pop-icon-theme
95 pop-launcher
96 xdg-user-dirs
97 ]
98 ++ lib.optionals config.services.flatpak.enable [
99 # User may have Flatpaks enabled but might not want the `cosmic-store` package.
100 cosmic-store
101 ]
102 )
103 ) config.environment.cosmic.excludePackages;
104
105 # Distro-wide defaults for graphical sessions
106 services.graphical-desktop.enable = true;
107
108 xdg = {
109 # Required for cosmic-osd
110 sounds.enable = true;
111 icons.fallbackCursorThemes = lib.mkDefault [ "Cosmic" ];
112
113 portal = {
114 enable = true;
115 extraPortals = with pkgs; [
116 xdg-desktop-portal-cosmic
117 xdg-desktop-portal-gtk
118 ];
119 configPackages = lib.mkDefault [ pkgs.xdg-desktop-portal-cosmic ];
120 };
121 };
122
123 systemd = {
124 packages = [ pkgs.cosmic-session ];
125 user.targets = {
126 # TODO: remove when upstream has XDG autostart support
127 cosmic-session = {
128 wants = [ "xdg-desktop-autostart.target" ];
129 before = [ "xdg-desktop-autostart.target" ];
130 };
131 };
132 };
133
134 fonts.packages = with pkgs; [
135 fira
136 noto-fonts
137 open-sans
138 ];
139
140 # Required options for the COSMIC DE
141 environment.sessionVariables.X11_BASE_RULES_XML = "${config.services.xserver.xkb.dir}/rules/base.xml";
142 environment.sessionVariables.X11_EXTRA_RULES_XML = "${config.services.xserver.xkb.dir}/rules/base.extras.xml";
143 programs.dconf.enable = true;
144 programs.dconf.packages = [ pkgs.cosmic-session ];
145 security.polkit.enable = true;
146 security.rtkit.enable = true;
147 services.accounts-daemon.enable = true;
148 services.displayManager.sessionPackages = [ pkgs.cosmic-session ];
149 services.libinput.enable = true;
150 services.upower.enable = true;
151 # Required for screen locker
152 security.pam.services.cosmic-greeter = { };
153
154 # geoclue2 stuff
155 services.geoclue2.enable = true;
156 # We _do_ use the demo agent in the `cosmic-settings-daemon` package,
157 # but this option also creates a systemd service that conflicts with the
158 # `cosmic-settings-daemon` package's geoclue2 agent. Therefore, disable it.
159 services.geoclue2.enableDemoAgent = false;
160 # As mentioned above, we do use the demo agent. And it needs to be
161 # whitelisted, otherwise it doesn't run.
162 services.geoclue2.whitelistedAgents = [ "geoclue-demo-agent" ]; # whitelist our own geoclue2 agent o
163
164 # Good to have defaults
165 hardware.bluetooth.enable = lib.mkDefault true;
166 networking.networkmanager.enable = lib.mkDefault true;
167 services.acpid.enable = lib.mkDefault true;
168 services.avahi.enable = lib.mkDefault true;
169 services.gnome.gnome-keyring.enable = lib.mkDefault true;
170 services.gvfs.enable = lib.mkDefault true;
171 services.orca.enable = lib.mkDefault (notExcluded pkgs.orca);
172 services.power-profiles-daemon.enable = lib.mkDefault (
173 !config.hardware.system76.power-daemon.enable
174 );
175
176 warnings = lib.optionals (cfg.showExcludedPkgsWarning && excludedCorePkgs != [ ]) [
177 ''
178 The `environment.cosmic.excludePackages` option was used to exclude some
179 packages from the environment which also includes some packages that the
180 maintainers of the COSMIC DE deem necessary for the COSMIC DE to start
181 and initialize. Excluding said packages creates a high probability that
182 the COSMIC DE will fail to initialize properly, or completely. This is an
183 unsupported use case. If this was not intentional, please assign an empty
184 list to the `environment.cosmic.excludePackages` option. If you want to
185 exclude non-essential packages, please look at the NixOS module for the
186 COSMIC DE and look for the essential packages in the `corePkgs` list.
187
188 You can stop this warning from appearing by setting the option
189 `services.desktopManager.cosmic.showExcludedPkgsWarning` to `false`.
190 ''
191 ];
192 };
193}