at 25.11-pre 4.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 inherit (lib) 9 mkDefault 10 mkEnableOption 11 mkIf 12 mkOption 13 mkPackageOption 14 types 15 ; 16 17 cfg = config.services.monado; 18 19 runtimeManifest = "${cfg.package}/share/openxr/1/openxr_monado.json"; 20in 21{ 22 options.services.monado = { 23 enable = mkEnableOption "Monado user service"; 24 25 package = mkPackageOption pkgs "monado" { }; 26 27 defaultRuntime = mkOption { 28 type = types.bool; 29 description = '' 30 Whether to enable Monado as the default OpenXR runtime on the system. 31 32 Note that applications can bypass this option by setting an active 33 runtime in a writable XDG_CONFIG_DIRS location like `~/.config`. 34 ''; 35 default = false; 36 example = true; 37 }; 38 39 forceDefaultRuntime = mkOption { 40 type = types.bool; 41 description = '' 42 Whether to ensure that Monado is the active runtime set for the current 43 user. 44 45 This replaces the file `XDG_CONFIG_HOME/openxr/1/active_runtime.json` 46 when starting the service. 47 ''; 48 default = false; 49 example = true; 50 }; 51 52 highPriority = 53 mkEnableOption "high priority capability for monado-service" 54 // mkOption { default = true; }; 55 }; 56 57 config = mkIf cfg.enable { 58 security.wrappers."monado-service" = mkIf cfg.highPriority { 59 setuid = false; 60 owner = "root"; 61 group = "root"; 62 # cap_sys_nice needed for asynchronous reprojection 63 capabilities = "cap_sys_nice+eip"; 64 source = lib.getExe' cfg.package "monado-service"; 65 }; 66 67 services.udev.packages = with pkgs; [ xr-hardware ]; 68 69 systemd.user = { 70 services.monado = { 71 description = "Monado XR runtime service module"; 72 requires = [ "monado.socket" ]; 73 conflicts = [ "monado-dev.service" ]; 74 75 unitConfig.ConditionUser = "!root"; 76 77 environment = { 78 # Default options 79 # https://gitlab.freedesktop.org/monado/monado/-/blob/4548e1738591d0904f8db4df8ede652ece889a76/src/xrt/targets/service/monado.in.service#L12 80 XRT_COMPOSITOR_LOG = mkDefault "debug"; 81 XRT_PRINT_OPTIONS = mkDefault "on"; 82 IPC_EXIT_ON_DISCONNECT = mkDefault "off"; 83 # Needed to avoid libbasalt.so: cannot open shared object file: No such file or directory 84 VIT_SYSTEM_LIBRARY_PATH = mkDefault "${pkgs.basalt-monado}/lib/libbasalt.so"; 85 }; 86 87 preStart = mkIf cfg.forceDefaultRuntime '' 88 XDG_CONFIG_HOME="''${XDG_CONFIG_HOME:-$HOME/.config}" 89 targetDir="$XDG_CONFIG_HOME/openxr/1" 90 activeRuntimePath="$targetDir/active_runtime.json" 91 92 echo "Note: Replacing active runtime at '$activeRuntimePath'" 93 mkdir --parents "$targetDir" 94 ln --symbolic --force ${runtimeManifest} "$activeRuntimePath" 95 ''; 96 97 serviceConfig = { 98 ExecStart = 99 if cfg.highPriority then 100 "${config.security.wrapperDir}/monado-service" 101 else 102 lib.getExe' cfg.package "monado-service"; 103 Restart = "no"; 104 }; 105 106 restartTriggers = [ cfg.package ]; 107 }; 108 109 sockets.monado = { 110 description = "Monado XR service module connection socket"; 111 conflicts = [ "monado-dev.service" ]; 112 113 unitConfig.ConditionUser = "!root"; 114 115 socketConfig = { 116 ListenStream = "%t/monado_comp_ipc"; 117 RemoveOnStop = true; 118 119 # If Monado crashes while starting up, we want to close incoming OpenXR connections 120 FlushPending = true; 121 }; 122 123 restartTriggers = [ cfg.package ]; 124 125 wantedBy = [ "sockets.target" ]; 126 }; 127 }; 128 129 environment.systemPackages = [ cfg.package ]; 130 environment.pathsToLink = [ "/share/openxr" ]; 131 132 hardware.graphics.extraPackages = [ pkgs.monado-vulkan-layers ]; 133 134 environment.etc."xdg/openxr/1/active_runtime.json" = mkIf cfg.defaultRuntime { 135 source = runtimeManifest; 136 }; 137 }; 138 139 meta.maintainers = with lib.maintainers; [ Scrumplex ]; 140}