1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7
8let
9 cfg = config.services.desktopManager.lomiri;
10in
11{
12 options.services.desktopManager.lomiri = {
13 enable = lib.mkEnableOption ''
14 the Lomiri graphical shell (formerly known as Unity8)
15 '';
16
17 basics = lib.mkOption {
18 internal = true;
19 description = ''
20 Enable basic things for getting Lomiri working.
21 '';
22 type = lib.types.bool;
23 default = config.services.xserver.displayManager.lightdm.greeters.lomiri.enable || cfg.enable;
24 };
25 };
26
27 config = lib.mkMerge [
28 # Basics for getting Lomiri to work
29 (lib.mkIf cfg.basics {
30 environment = {
31 # To override the default keyboard layout in Lomiri
32 etc.${pkgs.lomiri.lomiri.passthru.etcLayoutsFile}.text =
33 lib.strings.replaceStrings
34 [ "," ]
35 [
36 "\n"
37 ]
38 config.services.xserver.xkb.layout;
39
40 pathsToLink = [
41 # Data
42 "/share/locale" # TODO LUITK hardcoded default locale path, fix individual apps to not rely on it
43 "/share/wallpapers"
44 ];
45
46 systemPackages = with pkgs.lomiri; [
47 lomiri-wallpapers # default + additional wallpaper
48 suru-icon-theme # basic indicator icons
49 ];
50 };
51
52 # Override GSettings defaults
53 programs.dconf = {
54 enable = true;
55 profiles.user.databases = [
56 {
57 settings = {
58 "com/lomiri/shell/launcher" = {
59 logo-picture-uri = "file://${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake-white.svg";
60 home-button-background-color = "#5277C3";
61 };
62 };
63 lockAll = true;
64 }
65 ];
66 };
67
68 fonts.packages = with pkgs; [
69 ubuntu-classic # Ubuntu is default font
70 ];
71
72 # Xwayland is partly hardcoded in Mir so it can't really be fully turned off, and it must be on PATH for X11 apps *and Lomiri's web browser* to work.
73 # Until Mir/Lomiri can be properly used without it, force it on so everything behaves as expected.
74 programs.xwayland.enable = lib.mkForce true;
75
76 services.ayatana-indicators = {
77 enable = true;
78 packages = (
79 with pkgs;
80 [
81 ayatana-indicator-session # Controls for shutting down etc
82 ]
83 ++ (with lomiri; [
84 lomiri-indicator-datetime # Clock
85 ])
86 );
87 };
88 })
89
90 # Full Lomiri DE
91 (lib.mkIf cfg.enable {
92 # We need the basic setup as well
93 services.desktopManager.lomiri.basics = true;
94
95 environment = {
96 systemPackages =
97 (with pkgs; [
98 glib # XDG MIME-related tools identify it as GNOME, add gio for MIME identification to work
99 libayatana-common
100 ubports-click
101 ])
102 ++ (with pkgs.lomiri; [
103 hfd-service
104 libusermetrics
105 lomiri
106 lomiri-calculator-app
107 lomiri-calendar-app
108 lomiri-camera-app
109 lomiri-clock-app
110 lomiri-content-hub
111 lomiri-docviewer-app
112 lomiri-download-manager
113 lomiri-filemanager-app
114 lomiri-gallery-app
115 lomiri-history-service
116 lomiri-mediaplayer-app
117 lomiri-music-app
118 lomiri-polkit-agent
119 lomiri-schemas # exposes some required dbus interfaces
120 lomiri-session # wrappers to properly launch the session
121 lomiri-sounds
122 lomiri-system-settings
123 lomiri-telephony-service
124 lomiri-terminal-app
125 lomiri-thumbnailer
126 lomiri-url-dispatcher
127 mediascanner2 # TODO possibly needs to be kicked off by graphical-session.target
128 # Qt5 qtwebengine is not secure: https://github.com/NixOS/nixpkgs/pull/435067
129 # morph-browser
130 # Adding another browser that is known-working until Morph Browser can migrate to Qt6
131 pkgs.epiphany
132 qtmir # not having its desktop file for Xwayland available causes any X11 application to crash the session
133 teleports
134 ]);
135 };
136
137 hardware = {
138 bluetooth.enable = lib.mkDefault true;
139 };
140
141 networking.networkmanager.enable = lib.mkDefault true;
142
143 systemd.packages = with pkgs.lomiri; [
144 hfd-service
145 lomiri-download-manager
146 ];
147
148 services.dbus.packages = with pkgs.lomiri; [
149 hfd-service
150 libusermetrics
151 lomiri-download-manager
152 ];
153
154 services.accounts-daemon.enable = true;
155 services.udisks2.enable = true;
156 services.upower.enable = true;
157 services.geoclue2.enable = true;
158 services.telepathy.enable = true;
159
160 services.ayatana-indicators = {
161 enable = true;
162 packages =
163 (
164 with pkgs;
165 [
166 ayatana-indicator-display
167 ayatana-indicator-messages
168 ayatana-indicator-power
169 ]
170 ++ lib.optionals config.hardware.bluetooth.enable [ ayatana-indicator-bluetooth ]
171 ++ lib.optionals (config.services.pulseaudio.enable || config.services.pipewire.pulse.enable) [
172 ayatana-indicator-sound
173 ]
174 )
175 ++ (
176 with pkgs.lomiri;
177 [ lomiri-telephony-service ]
178 ++ lib.optionals config.networking.networkmanager.enable [ lomiri-indicator-network ]
179 );
180 };
181
182 services.gnome.evolution-data-server = {
183 enable = true;
184 plugins = with pkgs; [
185 # TODO: lomiri.address-book-service
186 ];
187 };
188
189 services.displayManager = {
190 defaultSession = lib.mkDefault "lomiri";
191 sessionPackages = with pkgs.lomiri; [ lomiri-session ];
192 };
193
194 services.xserver = {
195 enable = lib.mkDefault true;
196 displayManager.lightdm = {
197 enable = lib.mkDefault true;
198 greeters.lomiri.enable = lib.mkDefault true;
199 };
200 };
201
202 environment.pathsToLink = [
203 # Configs for inter-app data exchange system
204 "/share/lomiri-content-hub/peers"
205 # Configs for inter-app URL requests
206 "/share/lomiri-url-dispatcher/urls"
207 # Splash screens & other images for desktop apps launched via lomiri-app-launch
208 "/share/lomiri-app-launch"
209 # TODO Try to get maliit stuff working
210 "/share/maliit/plugins"
211 # At least the network indicator is still under the unity name, due to leftover Unity-isms
212 "/share/unity"
213 # Data
214 "/share/sounds"
215 ];
216
217 systemd.user.services =
218 let
219 lomiriService = "lomiri.service";
220 lomiriServiceNames = [
221 lomiriService
222 "lomiri-full-greeter.service"
223 "lomiri-full-shell.service"
224 "lomiri-greeter.service"
225 "lomiri-shell.service"
226 ];
227 in
228 {
229 # Unconditionally run service that collects system-installed URL handlers before LUD
230 # TODO also run user-installed one?
231 "lomiri-url-dispatcher-update-system-dir" = {
232 description = "Lomiri URL dispatcher system directory updater";
233 wantedBy = [ "lomiri-url-dispatcher.service" ];
234 before = [ "lomiri-url-dispatcher.service" ];
235 serviceConfig = {
236 Type = "oneshot";
237 ExecStart = "${pkgs.lomiri.lomiri-url-dispatcher}/libexec/lomiri-url-dispatcher/lomiri-update-directory /run/current-system/sw/share/lomiri-url-dispatcher/urls/";
238 };
239 };
240
241 "lomiri-polkit-agent" = {
242 description = "Lomiri Polkit agent";
243 wantedBy = [ lomiriService ];
244 after = [ lomiriService ];
245 partOf = [ lomiriService ];
246 serviceConfig = {
247 Type = "simple";
248 Restart = "always";
249 ExecStart = "${pkgs.lomiri.lomiri-polkit-agent}/libexec/lomiri-polkit-agent/policykit-agent";
250 };
251 };
252
253 "mediascanner-2.0" = {
254 description = "Media Scanner";
255 wantedBy = lomiriServiceNames;
256 before = lomiriServiceNames;
257 partOf = lomiriServiceNames;
258 serviceConfig = {
259 Type = "dbus";
260 BusName = "com.lomiri.MediaScanner2.Daemon";
261 Restart = "on-failure";
262 ExecStart = "${lib.getExe pkgs.lomiri.mediascanner2}";
263 };
264 };
265 };
266
267 systemd.services = {
268 "dbus-com.lomiri.UserMetrics" = {
269 serviceConfig = {
270 Type = "dbus";
271 BusName = "com.lomiri.UserMetrics";
272 User = "usermetrics";
273 StandardOutput = "syslog";
274 SyslogIdentifier = "com.lomiri.UserMetrics";
275 ExecStart = "${pkgs.lomiri.libusermetrics}/libexec/libusermetrics/usermetricsservice";
276 }
277 // lib.optionalAttrs (!config.security.apparmor.enable) {
278 # Due to https://gitlab.com/ubports/development/core/libusermetrics/-/issues/8, auth must be disabled when not using AppArmor, lest the next database usage breaks
279 Environment = "USERMETRICS_NO_AUTH=1";
280 };
281 };
282 };
283
284 users.users.usermetrics = {
285 group = "usermetrics";
286 home = "/var/lib/usermetrics";
287 createHome = true;
288 isSystemUser = true;
289 };
290
291 users.groups.usermetrics = { };
292 })
293 ];
294
295 meta.maintainers = lib.teams.lomiri.members;
296}