dot
vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks
| 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 | }: |
| 20 | let |
| 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 = ""; |
| 49 | in |
| 50 | { |
| 51 | systemd.user.services = { |
| 52 | waybar = graphical { |
| 53 | description = "Waybar"; |
| 54 | exec = lib.getExe pkgs.waybar; |
| 55 | slice = "session-graphical.slice"; |
| 56 | service.ExecReload = "/bin/kill -SIGUSR2 $MAINPID"; |
| 57 | }; |
| 58 | |
| 59 | hypridle = graphical { |
| 60 | description = "Hyprland's idle daemon"; |
| 61 | exec = lib.getExe pkgs.hypridle; |
| 62 | slice = "session-graphical.slice"; |
| 63 | unit.ConditionEnvironment = "WAYLAND_DISPLAY"; |
| 64 | }; |
| 65 | |
| 66 | hyprpaper = graphical { |
| 67 | description = "Hyprland wallpaper daemon"; |
| 68 | exec = lib.getExe pkgs.hyprpaper; |
| 69 | slice = "session-graphical.slice"; |
| 70 | }; |
| 71 | |
| 72 | dunst = graphical { |
| 73 | description = "Dunst notification daemon"; |
| 74 | exec = lib.getExe pkgs.dunst; |
| 75 | slice = "session-graphical.slice"; |
| 76 | service = { |
| 77 | Type = "dbus"; |
| 78 | BusName = "org.freedesktop.Notifications"; |
| 79 | }; |
| 80 | }; |
| 81 | |
| 82 | # The Waybar flyouts (control centre, notifications). Started with the |
| 83 | # session so the first click on the Waybar button opens instantly. |
| 84 | eww = graphical { |
| 85 | description = "Eww daemon for the Waybar flyouts"; |
| 86 | exec = " --config /waybar/eww daemon --no-daemonize"; |
| 87 | }; |
| 88 | |
| 89 | hyprpolkitagent = graphical { |
| 90 | description = "Hyprland polkit agent"; |
| 91 | exec = "/libexec/hyprpolkitagent"; |
| 92 | slice = "session-graphical.slice"; |
| 93 | }; |
| 94 | |
| 95 | # Puts Wine/Proton tray icons (Battle.net) into Waybar's tray, so it needs |
| 96 | # the tray to be there first. |
| 97 | xembedsniproxy = graphical { |
| 98 | description = "XEmbed to StatusNotifierItem tray bridge"; |
| 99 | exec = lib.getExe pkgs.xembedsniproxy; |
| 100 | after = [ "waybar.service" ]; |
| 101 | # Restarting it while a Wine app is open breaks that app's tray icon until |
| 102 | # the app is restarted, so a rebuild leaves the running one alone. |
| 103 | unit.X-RestartIfChanged = false; |
| 104 | }; |
| 105 | |
| 106 | # Forwards the X11 clipboard (Wine/Proton games) to Wayland whatever has |
| 107 | # focus. Waits for Xwayland by itself. |
| 108 | xwl-clipbridge = graphical { |
| 109 | description = "X11 to Wayland clipboard bridge"; |
| 110 | exec = "/bin/python3 /hypr/scripts/xwl-clipbridge"; |
| 111 | service.Environment = [ "PATH=" ]; |
| 112 | }; |
| 113 | |
| 114 | # The apps opened at login (Signal, Discord, Faugus, OpenDeck, WowUp); see |
| 115 | # config/hypr/scripts/autostart-apps. It starts each one as its own unit and |
| 116 | # exits; the window placement rules for them are in hyprland.lua. |
| 117 | autostart-apps = graphical { |
| 118 | description = "Open the apps that start at login"; |
| 119 | exec = "/hypr/scripts/autostart-apps"; |
| 120 | after = [ "waybar.service" ]; |
| 121 | service = { |
| 122 | Type = "oneshot"; |
| 123 | Restart = "no"; |
| 124 | # The script finds the apps (and pgrep, uwsm, hyprctl, ...) on the |
| 125 | # system and user profiles, whatever environment the session imported. |
| 126 | Environment = [ |
| 127 | "PATH= |
| 128 | |
| 129 | :/etc/profiles/per-user//bin:/run/current-system/sw/bin" |
| 130 | ]; |
| 131 | # It waits for the tray and for Signal and Discord to open, up to about |
| 132 | # two minutes; more than the 15 s default the CachyOS settings set. |
| 133 | TimeoutStartSec = "3min"; |
| 134 | }; |
| 135 | unit.X-RestartIfChanged = false; |
| 136 | }; |
| 137 | }; |
| 138 | |
| 139 | # Network and Bluetooth live in the control centre, not the tray. blueman-applet |
| 140 | # still runs, from the autostart entry services.blueman installs (uwsm runs it |
| 141 | # as app-blueman@autostart.service), for pairing prompts and notifications; |
| 142 | # only its tray icon is turned off (ShowConnected needs that icon). |
| 143 | dconf.settings."org/blueman/general".plugin-list = [ |
| 144 | "!StatusIcon" |
| 145 | "!ShowConnected" |
| 146 | ]; |
| 147 | |
| 148 | # Bitwarden at login. This one stays an XDG autostart entry, as on CachyOS |
| 149 | # (uwsm runs those as systemd units too: app-bitwarden@autostart.service); the |
| 150 | # entry just needs NixOS's name for the program. |
| 151 | xdg.configFile."autostart/bitwarden.desktop".text = '' |
| 152 | [Desktop Entry] |
| 153 | Type=Application |
| 154 | Name=Bitwarden |
| 155 | Comment=Bitwarden startup script |
| 156 | Exec= |
| 157 | StartupNotify=false |
| 158 | Terminal=false |
| 159 | ''; |
| 160 | } |