atagen

monolith

public
Star0
Watch0

Commit e1a086bc100d

tarball

atagen <boss@atagen.co>2026-10-17 06:25 UTC

1 file changed+117-2
nix: add a NixOS module and make the package run outside the devshell

ash opens libvulkan at runtime, so the built binary only worked where LD_LIBRARY_PATH pointed at the loader. The module follows wry's, a session entry, portals and an optional CAP_SYS_NICE wrapper for SCHED_RR and the realtime queue.
Modified file: flake.nix+117 additions−2 deletions
@@ -24,7 +24,9 @@
2424 craneLib = crane.mkLib pkgs;
2525 src = lib.cleanSourceWith {
2626 src = ./.;
27- filter = path: type: (craneLib.filterCargoSources path type) || lib.hasInfix "/shaders" path || lib.hasInfix "/res" path;
27+ filter =
28+ path: type:
29+ (craneLib.filterCargoSources path type) || lib.hasInfix "/shaders" path || lib.hasInfix "/res" path;
2830 name = "source";
2931 };
3032 lavapipeIcd = "${pkgs.mesa}/share/vulkan/icd.d/lvp_icd.${pkgs.stdenv.hostPlatform.parsed.cpu.name}.json";
@@ -61,6 +63,17 @@
6163 install -Dm644 res/monolith-portals.conf -t $out/share/xdg-desktop-portal
6264 install -Dm644 res/monolith.desktop -t $out/share/wayland-sessions
6365 '';
66+ # ash opens libvulkan at runtime, so it is not in the linked rpath.
67+ postFixup = ''
68+ patchelf --add-rpath ${lib.makeLibraryPath [ pkgs.vulkan-loader ]} $out/bin/monolith
69+ '';
70+ passthru.providedSessions = [ "monolith" ];
71+ meta = {
72+ description = "A tiling Wayland compositor";
73+ license = lib.licenses.eupl12;
74+ platforms = lib.platforms.linux;
75+ mainProgram = "monolith";
76+ };
6477 }
6578 );
6679
@@ -72,7 +85,11 @@
7285 cargoClippyExtraArgs = "--all-targets -- --deny warnings";
7386 }
7487 );
75- fmt = craneLib.cargoFmt { inherit src; pname = "monolith"; version = "0.0.0"; };
88+ fmt = craneLib.cargoFmt {
89+ inherit src;
90+ pname = "monolith";
91+ version = "0.0.0";
92+ };
7693 test = craneLib.cargoTest (
7794 commonArgs
7895 // {
@@ -83,12 +100,110 @@
83100 );
84101 };
85102 };
103+ nixosModule =
104+ {
105+ config,
106+ lib,
107+ pkgs,
108+ ...
109+ }:
110+ let
111+ inherit (lib)
112+ getExe
113+ literalExpression
114+ mkDefault
115+ mkEnableOption
116+ mkIf
117+ mkOption
118+ optional
119+ types
120+ ;
121+
122+ cfg = config.programs.monolith;
123+ in
124+ {
125+ options.programs.monolith = {
126+ enable = mkEnableOption "monolith, a tiling Wayland compositor";
127+
128+ package = mkOption {
129+ type = types.package;
130+ default = (mkProject pkgs).package;
131+ defaultText = literalExpression "monolith.packages.\${system}.default";
132+ description = "The monolith package to use.";
133+ };
134+
135+ realtime-scheduling = mkOption {
136+ type = types.bool;
137+ default = true;
138+ description = ''
139+ Wrap the monolith binary with CAP_SYS_NICE so its compositor thread runs
140+ SCHED_RR and its Vulkan queue gets realtime global priority. monolith clears
141+ the capability from everything it launches.
142+ '';
143+ };
144+
145+ xwayland.enable = mkEnableOption "Xwayland, started on the first X11 client" // {
146+ default = true;
147+ };
148+
149+ extraPackages = mkOption {
150+ type = with types; listOf package;
151+ default = with pkgs; [
152+ foot
153+ fuzzel
154+ swaylock
155+ wl-clipboard
156+ ];
157+ defaultText = literalExpression "with pkgs; [ foot fuzzel swaylock wl-clipboard ]";
158+ description = "Extra packages to be installed system wide.";
159+ };
160+ };
161+
162+ config = mkIf cfg.enable {
163+ environment.systemPackages = (optional (!cfg.realtime-scheduling) cfg.package) ++ cfg.extraPackages;
164+
165+ programs = {
166+ dconf.enable = mkDefault true;
167+ xwayland.enable = mkIf cfg.xwayland.enable (mkDefault true);
168+ };
169+
170+ security = {
171+ polkit.enable = true;
172+ pam.services.swaylock = { };
173+
174+ wrappers = mkIf cfg.realtime-scheduling {
175+ monolith = {
176+ owner = "root";
177+ group = "root";
178+ permissions = "a+rx";
179+ source = getExe cfg.package;
180+ capabilities = "cap_sys_nice+p";
181+ };
182+ };
183+ };
184+
185+ xdg.portal = {
186+ enable = mkDefault true;
187+ configPackages = mkDefault [ cfg.package ];
188+ extraPortals = [
189+ pkgs.xdg-desktop-portal-gtk
190+ pkgs.xdg-desktop-portal-wlr
191+ ];
192+ };
193+
194+ services.displayManager.sessionPackages = [ cfg.package ];
195+ };
196+ };
86197 in
87198 {
88199 packages = forAllSystems (pkgs: {
89200 default = (mkProject pkgs).package;
90201 });
91202
203+ overlays.default = final: _: { monolith = (mkProject final).package; };
204+
205+ nixosModules.default = nixosModule;
206+
92207 checks = forAllSystems (pkgs: (mkProject pkgs).checks);
93208
94209 devShells = forAllSystems (