dot

vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks

142 lines5396 bytesNix
1# The desktop's background programs, as systemd user services. On CachyOS most
2# of these were started by hyprland.lua (hl.exec_cmd at hyprland.start).
3#
4# uwsm starts Hyprland and then graphical-session.target; every service here is
5# wanted by that target and stopped with it, so they come up after the
6# compositor is ready and go away at logout. They are restarted if they crash.
7#
8# systemctl --user status waybar is it running, and its last log lines
9# journalctl --user -u waybar -f follow its log
10# systemctl --user restart waybar e.g. after changing its config
11#
12# Slices are uwsm's: session-graphical for the shell itself (bar, idle, wallpaper,
13# notifications), background-graphical for helpers.
14{
15 config,
16 lib,
17 pkgs,
18 ...
19}:
20let
21 graphical =
22 {
23 description,
24 exec,
25 slice ? "background-graphical.slice",
26 after ? [ ],
27 unit ? { },
28 service ? { },
29 }:
30 {
31 Unit = {
32 Description = description;
33 PartOf = [ "graphical-session.target" ];
34 After = [ "graphical-session.target" ] ++ after;
35 Requisite = [ "graphical-session.target" ];
36 }
37 // unit;
38 Service = {
39 ExecStart = exec;
40 Restart = "on-failure";
41 RestartSec = 2;
42 Slice = slice;
43 }
44 // service;
45 Install.WantedBy = [ "graphical-session.target" ];
46 };
47
48 configDir = "${config.xdg.configHome}";
49in
50{
51 systemd.user.services = {
52 # Waybar, hypridle, hyprpaper and dunst come from their Home Manager modules
53 # (desktop.nix); these put them with the rest of the shell.
54 waybar.Service.Slice = "session-graphical.slice";
55 hypridle.Service.Slice = "session-graphical.slice";
56 hyprpaper.Service.Slice = "session-graphical.slice";
57 dunst = {
58 Service.Slice = "session-graphical.slice";
59 # The module only starts dunst on the first notification (D-Bus
60 # activation); start it with the session, as before.
61 Install.WantedBy = [ "graphical-session.target" ];
62 };
63
64 # The Waybar flyouts (control centre, notifications). Started with the
65 # session so the first click on the Waybar button opens instantly.
66 eww = graphical {
67 description = "Eww daemon for the Waybar flyouts";
68 exec = "${lib.getExe pkgs.eww} --config ${configDir}/waybar/eww daemon --no-daemonize";
69 };
70
71 hyprpolkitagent = graphical {
72 description = "Hyprland polkit agent";
73 exec = "${pkgs.hyprpolkitagent}/libexec/hyprpolkitagent";
74 slice = "session-graphical.slice";
75 };
76
77 # Puts Wine/Proton tray icons (Battle.net) into Waybar's tray, so it needs
78 # the tray to be there first.
79 xembedsniproxy = graphical {
80 description = "XEmbed to StatusNotifierItem tray bridge";
81 exec = lib.getExe pkgs.xembedsniproxy;
82 after = [ "waybar.service" ];
83 # Restarting it while a Wine app is open breaks that app's tray icon until
84 # the app is restarted, so a rebuild leaves the running one alone.
85 unit.X-RestartIfChanged = false;
86 };
87
88 # Forwards the X11 clipboard (Wine/Proton games) to Wayland whatever has
89 # focus. Waits for Xwayland by itself.
90 xwl-clipbridge = graphical {
91 description = "X11 to Wayland clipboard bridge";
92 exec = "${pkgs.python3-desktop}/bin/python3 ${configDir}/hypr/scripts/xwl-clipbridge";
93 service.Environment = [ "PATH=${lib.makeBinPath [ pkgs.wl-clipboard ]}" ];
94 };
95
96 # The apps opened at login (Signal, Discord, Faugus, OpenDeck, WowUp); see
97 # config/hypr/scripts/autostart-apps. It starts each one as its own unit and
98 # exits; the window placement rules for them are in config/hypr/startup.lua.
99 autostart-apps = graphical {
100 description = "Open the apps that start at login";
101 exec = "${configDir}/hypr/scripts/autostart-apps";
102 after = [ "waybar.service" ];
103 service = {
104 Type = "oneshot";
105 Restart = "no";
106 # The script finds the apps (and pgrep, uwsm, hyprctl, ...) on the
107 # system and user profiles, whatever environment the session imported.
108 Environment = [
109 "PATH=${
110 lib.makeBinPath [ pkgs.python3-desktop ]
111 }:/etc/profiles/per-user/${config.home.username}/bin:/run/current-system/sw/bin"
112 ];
113 # It waits for the tray and for Signal and Discord to open, up to about
114 # two minutes; more than the 15 s default the CachyOS settings set.
115 TimeoutStartSec = "3min";
116 };
117 unit.X-RestartIfChanged = false;
118 };
119 };
120
121 # Network and Bluetooth live in the control centre, not the tray. blueman-applet
122 # still runs, from the autostart entry services.blueman installs (uwsm runs it
123 # as app-blueman@autostart.service), for pairing prompts and notifications;
124 # only its tray icon is turned off (ShowConnected needs that icon).
125 dconf.settings."org/blueman/general".plugin-list = [
126 "!StatusIcon"
127 "!ShowConnected"
128 ];
129
130 # Bitwarden at login. This one stays an XDG autostart entry, as on CachyOS
131 # (uwsm runs those as systemd units too: app-bitwarden@autostart.service); the
132 # entry just needs NixOS's name for the program.
133 xdg.configFile."autostart/bitwarden.desktop".text = ''
134 [Desktop Entry]
135 Type=Application
136 Name=Bitwarden
137 Comment=Bitwarden startup script
138 Exec=${lib.getExe pkgs.bitwarden-desktop}
139 StartupNotify=false
140 Terminal=false
141 '';
142}