-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflake.nix
331 lines (302 loc) · 11.8 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
{
description = "A dynamic tiling Wayland compositor.";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
fht-share-picker = {
url = "github:nferhat/fht-share-picker/gtk-rewrite";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-parts.follows = "flake-parts";
inputs.rust-overlay.follows = "";
};
};
outputs = inputs @ {self, ...}: let
# NOTE: For now function lives with the outputs declaration since its used by perSystem.packages
# and also flake.nixosModules.fht-compositor. A better solution (that I haven't figured out)
# is use the overlay provided by this flake in the nixos module
fht-compositor-package = {
lib,
libGL,
libdisplay-info,
libinput,
seatd,
libxkbcommon,
mesa,
pipewire,
dbus,
wayland,
pkg-config,
rustPlatform,
# Optional stuff that can be toggled on by the user.
# These correspond to cargo features.
withUdevBackend ? true,
withWinitBackend ? true,
withXdgScreenCast ? true,
withProfiling ? false,
}:
rustPlatform.buildRustPackage {
pname = "fht-compositor";
version = self.shortRev or self.dirtyShortRev or "unknown";
src = ./.;
postPatch = ''
patchShebangs res/fht-compositor-session
substituteInPlace res/fht-compositor.service \
--replace-fail '/usr/bin' "$out/bin"
'';
cargoLock = {
# NOTE: Since dependencies such as smithay are only distributed with git,
# we are forced to allow cargo to fetch them.
allowBuiltinFetchGit = true;
lockFile = ./Cargo.lock;
};
strictDeps = true;
nativeBuildInputs = [rustPlatform.bindgenHook pkg-config];
buildInputs =
[libGL libdisplay-info libinput seatd libxkbcommon mesa wayland]
++ lib.optional withXdgScreenCast dbus
++ lib.optional withXdgScreenCast pipewire;
# NOTE: Whenever adding features, don't forget to specify them here!!
buildFeatures =
lib.optional withXdgScreenCast "xdg-screencast-portal"
++ lib.optional withWinitBackend "winit-backend"
++ lib.optional withUdevBackend "udev-backend"
++ lib.optional withProfiling "profile-with-puffin";
buildNoDefaultFeatures = true;
postInstall =
''
install -Dm644 res/fht-compositor.desktop -t $out/share/wayland-sessions
# Supporting session targets. Maybe add a systemd option?
install -Dm755 res/fht-compositor-session $out/bin/fht-compositor-session
install -Dm644 res/fht-compositor{.service,-shutdown.target} -t $out/share/systemd/user
''
+ lib.optionalString withXdgScreenCast ''
install -Dm644 res/fht-compositor.portal -t $out/share/xdg-desktop-portal/portals
install -Dm644 res/fht-compositor-portals.conf -t $out/share/xdg-desktop-portal
'';
env.RUSTFLAGS = toString (
map (arg: "-C link-arg=" + arg) [
"-Wl,--push-state,--no-as-needed"
"-lEGL"
"-lwayland-client"
"-Wl,--pop-state"
]
);
passthru.providedSessions = ["fht-compositor"];
meta = {
description = "A dynamic tiling Wayland compositor.";
homepage = "https://github.com/nferhat/fht-compositor";
license = lib.licenses.gpl3Only;
mainProgram = "fht-compositor";
platforms = lib.platforms.linux;
};
};
in
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
systems = ["x86_64-linux"];
perSystem = {
self',
pkgs,
inputs',
...
}: let
in {
# NOTE: This is for the Nix code formatter!!
formatter = pkgs.alejandra;
packages = rec {
fht-compositor = pkgs.callPackage fht-compositor-package {};
default = fht-compositor;
# This build is only for dev purposes. it is meant to be build fast for
# fast development. It is also the reason why its not stripped.
#
# Preferably if you are developing the compositor, you'd want to enter the provided
# dev shell and run `cargo build ...`
fht-compositor-debug = fht-compositor.overrideAttrs (next: prev: {
pname = prev.pname + "-debug";
cargoBuildType = "debug";
cargoCheckType = next.cargoBuildType;
dontStrip = true;
});
};
devShells.default = let
rust-bin = inputs.rust-overlay.lib.mkRustBin {} pkgs;
inherit (self'.packages) fht-compositor;
in
pkgs.mkShell {
packages = [
# For developement purposes, a nightly toolchain is preferred.
# We use nightly cargo for formatting, though compiling is limited to
# whatever is specified inside ./rust-toolchain.toml
(rust-bin.selectLatestNightlyWith (toolchain:
toolchain.default.override {
extensions = ["rust-analyzer" "rust-src"];
}))
pkgs.alejandra # for formatting this flake if needed
pkgs.nodePackages.prettier # formatting documentation
];
inherit (fht-compositor) buildInputs nativeBuildInputs;
env = {
# WARN: Do not overwrite this variable in your shell!
# It is required for `dlopen()` to work on some libraries; see the comment
# in the package expression
#
# This should only be set with `CARGO_BUILD_RUSTFLAGS="$CARGO_BUILD_RUSTFLAGS -C your-flags"`
CARGO_BUILD_RUSTFLAGS = fht-compositor.RUSTFLAGS;
};
};
};
flake.nixosModules = rec {
default = fht-compositor;
fht-compositor = {
lib,
config,
options,
pkgs,
...
}: let
cfg = config.programs.fht-compositor;
fht-share-picker-pkg = inputs.fht-share-picker.packages."${pkgs.system}".default;
in {
options.programs.fht-compositor = {
enable = lib.mkEnableOption "fht-compositor";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.callPackage fht-compositor-package {};
};
};
config = lib.mkMerge [
{
# Require an XDG environment. Makes our life 100x easier.
environment.systemPackages = [pkgs.xdg-utils];
xdg = {
autostart.enable = lib.mkDefault true;
menus.enable = lib.mkDefault true;
mime.enable = lib.mkDefault true;
icons.enable = lib.mkDefault true;
};
}
(lib.mkIf (builtins.elem "xdg-screencast-portal" cfg.package.buildFeatures) {
# Install the share-picker application in order to select what to screencast.
environment.systemPackages = [fht-share-picker-pkg];
})
(lib.mkIf cfg.enable {
# Install the fht-compositor package to display servers in order to make the .desktop
# file discoverable (providing a fht-compositor desktop entry)
services =
if lib.strings.versionAtLeast config.system.nixos.release "24.05"
then {
displayManager.sessionPackages = [cfg.package];
}
else {
xserver.displayManager.sessionPackages = [cfg.package];
};
# OpenGL/mesa is required. We do not have a software renderer.
hardware =
if lib.strings.versionAtLeast config.system.nixos.release "24.11"
then {
graphics.enable = lib.mkDefault true;
}
else {
opengl.enable = lib.mkDefault true;
};
})
(lib.mkIf cfg.enable {
environment.systemPackages = [cfg.package];
services.gnome.gnome-keyring.enable = true;
# Provide the xdg-desktop-portal-gtk portal for users, since we only cover the screencast
# one with the compositor. Fallback on GTK for everything else.
xdg.portal = {
enable = true;
extraPortals = lib.mkIf (
!cfg.package.cargoBuildNoDefaultFeatures || builtins.elem "xdg-screencast-portal" cfg.package.cargoBuildFeatures
) [pkgs.xdg-desktop-portal-gtk];
configPackages = [cfg.package];
};
# These also contribute to making our life 100x easier, as well as providing a more
# fleshed out setup out of the box.
security.polkit.enable = true;
programs.dconf.enable = lib.mkDefault true;
systemd.user.services.fht-compositor-polkit = {
description = "PolicyKit Authentication Agent provided by fht-compositor";
wantedBy = ["fht-compositor.service"];
after = ["graphical-session.target"];
partOf = ["graphical-session.target"];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
Restart = "on-failure";
RestartSec = 1;
TimeoutStopSec = 10;
};
};
})
];
};
};
flake.homeModules = rec {
default = fht-compositor;
# NOTE: This module implementation is directly ripped from home-manager's helix module
# home-manager/modules/programs/helix.nix
fht-compositor = {
lib,
config,
options,
pkgs,
...
}: let
cfg = config.programs.fht-compositor;
tomlFormat = pkgs.formats.toml {};
in {
options.programs.fht-compositor = {
enable = lib.mkEnableOption "fht-compositor";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.callPackage fht-compositor-package {};
};
settings = lib.mkOption {
type = tomlFormat.type;
default = {};
example = lib.literalExpression ''
{
autostart = [];
general.cursor-warps = true;
decorations.border = {
thickness = 3;
radius = 0;
focused-color = {
start = "#5781b9";
end = "7fc8db";
angle = 0;
};
};
animations.disable = false;
keybinds."Super-q" = "quit";
rules = [
{ on-workspace = 5; floating = true; centered = true };
# other window rules...
]
}
'';
description = ''
Configuration written to
{file}`$XDG_CONFIG_HOME/fht/compositor.toml`.
'';
};
};
config = lib.mkIf cfg.enable {
home.packages = [cfg.package];
xdg.configFile.fht-compositor-config = lib.mkIf (cfg.settings != {}) {
target = "fht/compositor.toml";
source = tomlFormat.generate "fht-compositor-config" cfg.settings;
};
};
};
};
};
}