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 fonts.packages = with pkgs; [ 53 ubuntu-classic # Ubuntu is default font 54 ]; 55 56 # 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. 57 # Until Mir/Lomiri can be properly used without it, force it on so everything behaves as expected. 58 programs.xwayland.enable = lib.mkForce true; 59 60 services.ayatana-indicators = { 61 enable = true; 62 packages = ( 63 with pkgs; 64 [ 65 ayatana-indicator-datetime # Clock 66 ayatana-indicator-session # Controls for shutting down etc 67 ] 68 ); 69 }; 70 }) 71 72 # Full Lomiri DE 73 (lib.mkIf cfg.enable { 74 # We need the basic setup as well 75 services.desktopManager.lomiri.basics = true; 76 77 environment = { 78 systemPackages = 79 (with pkgs; [ 80 glib # XDG MIME-related tools identify it as GNOME, add gio for MIME identification to work 81 libayatana-common 82 ubports-click 83 ]) 84 ++ (with pkgs.lomiri; [ 85 hfd-service 86 libusermetrics 87 lomiri 88 lomiri-calculator-app 89 lomiri-calendar-app 90 lomiri-camera-app 91 lomiri-clock-app 92 lomiri-content-hub 93 lomiri-docviewer-app 94 lomiri-download-manager 95 lomiri-filemanager-app 96 lomiri-gallery-app 97 lomiri-history-service 98 lomiri-mediaplayer-app 99 lomiri-music-app 100 lomiri-polkit-agent 101 lomiri-schemas # exposes some required dbus interfaces 102 lomiri-session # wrappers to properly launch the session 103 lomiri-sounds 104 lomiri-system-settings 105 lomiri-telephony-service 106 lomiri-terminal-app 107 lomiri-thumbnailer 108 lomiri-url-dispatcher 109 mediascanner2 # TODO possibly needs to be kicked off by graphical-session.target 110 morph-browser 111 qtmir # not having its desktop file for Xwayland available causes any X11 application to crash the session 112 teleports 113 ]); 114 }; 115 116 hardware = { 117 bluetooth.enable = lib.mkDefault true; 118 }; 119 120 networking.networkmanager.enable = lib.mkDefault true; 121 122 systemd.packages = with pkgs.lomiri; [ 123 hfd-service 124 lomiri-download-manager 125 ]; 126 127 services.dbus.packages = with pkgs.lomiri; [ 128 hfd-service 129 libusermetrics 130 lomiri-download-manager 131 ]; 132 133 # Copy-pasted basic stuff 134 hardware.graphics.enable = lib.mkDefault true; 135 fonts.enableDefaultPackages = lib.mkDefault true; 136 programs.dconf.enable = lib.mkDefault true; 137 138 services.accounts-daemon.enable = true; 139 140 services.ayatana-indicators = { 141 enable = true; 142 packages = 143 ( 144 with pkgs; 145 [ 146 ayatana-indicator-display 147 ayatana-indicator-messages 148 ayatana-indicator-power 149 ] 150 ++ lib.optionals config.hardware.bluetooth.enable [ ayatana-indicator-bluetooth ] 151 ++ lib.optionals (config.services.pulseaudio.enable || config.services.pipewire.pulse.enable) [ 152 ayatana-indicator-sound 153 ] 154 ) 155 ++ ( 156 with pkgs.lomiri; 157 [ lomiri-telephony-service ] 158 ++ lib.optionals config.networking.networkmanager.enable [ lomiri-indicator-network ] 159 ); 160 }; 161 162 services.udisks2.enable = true; 163 services.upower.enable = true; 164 services.geoclue2.enable = true; 165 166 services.gnome.evolution-data-server = { 167 enable = true; 168 plugins = with pkgs; [ 169 # TODO: lomiri.address-book-service 170 ]; 171 }; 172 173 services.telepathy.enable = true; 174 175 services.displayManager = { 176 defaultSession = lib.mkDefault "lomiri"; 177 sessionPackages = with pkgs.lomiri; [ lomiri-session ]; 178 }; 179 180 services.xserver = { 181 enable = lib.mkDefault true; 182 displayManager.lightdm = { 183 enable = lib.mkDefault true; 184 greeters.lomiri.enable = lib.mkDefault true; 185 }; 186 }; 187 188 environment.pathsToLink = [ 189 # Configs for inter-app data exchange system 190 "/share/lomiri-content-hub/peers" 191 # Configs for inter-app URL requests 192 "/share/lomiri-url-dispatcher/urls" 193 # Splash screens & other images for desktop apps launched via lomiri-app-launch 194 "/share/lomiri-app-launch" 195 # TODO Try to get maliit stuff working 196 "/share/maliit/plugins" 197 # At least the network indicator is still under the unity name, due to leftover Unity-isms 198 "/share/unity" 199 # Data 200 "/share/sounds" 201 ]; 202 203 systemd.user.services = 204 let 205 lomiriService = "lomiri.service"; 206 lomiriServiceNames = [ 207 lomiriService 208 "lomiri-full-greeter.service" 209 "lomiri-full-shell.service" 210 "lomiri-greeter.service" 211 "lomiri-shell.service" 212 ]; 213 in 214 { 215 # Unconditionally run service that collects system-installed URL handlers before LUD 216 # TODO also run user-installed one? 217 "lomiri-url-dispatcher-update-system-dir" = { 218 description = "Lomiri URL dispatcher system directory updater"; 219 wantedBy = [ "lomiri-url-dispatcher.service" ]; 220 before = [ "lomiri-url-dispatcher.service" ]; 221 serviceConfig = { 222 Type = "oneshot"; 223 ExecStart = "${pkgs.lomiri.lomiri-url-dispatcher}/libexec/lomiri-url-dispatcher/lomiri-update-directory /run/current-system/sw/share/lomiri-url-dispatcher/urls/"; 224 }; 225 }; 226 227 "lomiri-polkit-agent" = { 228 description = "Lomiri Polkit agent"; 229 wantedBy = [ lomiriService ]; 230 after = [ lomiriService ]; 231 partOf = [ lomiriService ]; 232 serviceConfig = { 233 Type = "simple"; 234 Restart = "always"; 235 ExecStart = "${pkgs.lomiri.lomiri-polkit-agent}/libexec/lomiri-polkit-agent/policykit-agent"; 236 }; 237 }; 238 239 "mediascanner-2.0" = { 240 description = "Media Scanner"; 241 wantedBy = lomiriServiceNames; 242 before = lomiriServiceNames; 243 partOf = lomiriServiceNames; 244 serviceConfig = { 245 Type = "dbus"; 246 BusName = "com.lomiri.MediaScanner2.Daemon"; 247 Restart = "on-failure"; 248 ExecStart = "${lib.getExe pkgs.lomiri.mediascanner2}"; 249 }; 250 }; 251 }; 252 253 systemd.services = { 254 "dbus-com.lomiri.UserMetrics" = { 255 serviceConfig = 256 { 257 Type = "dbus"; 258 BusName = "com.lomiri.UserMetrics"; 259 User = "usermetrics"; 260 StandardOutput = "syslog"; 261 SyslogIdentifier = "com.lomiri.UserMetrics"; 262 ExecStart = "${pkgs.lomiri.libusermetrics}/libexec/libusermetrics/usermetricsservice"; 263 } 264 // lib.optionalAttrs (!config.security.apparmor.enable) { 265 # 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 266 Environment = "USERMETRICS_NO_AUTH=1"; 267 }; 268 }; 269 }; 270 271 users.users.usermetrics = { 272 group = "usermetrics"; 273 home = "/var/lib/usermetrics"; 274 createHome = true; 275 isSystemUser = true; 276 }; 277 278 users.groups.usermetrics = { }; 279 }) 280 ]; 281 282 meta.maintainers = lib.teams.lomiri.members; 283}