This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / 2configs / desktops / sway / default.nix
16 kB 473 lines
1{ 2 pkgs, 3 lib, 4 self, 5 ... 6}: 7let 8 9 term = "/run/current-system/sw/bin/kitty"; 10 11 # Unified script: switch to workspace and move it to current output 12 gotoWorkspace = pkgs.writeShellApplication { 13 name = "goto-workspace"; 14 runtimeInputs = [ 15 pkgs.sway 16 pkgs.jq 17 ]; 18 text = '' 19 WS="$1" 20 CURRENT_OUTPUT=$(swaymsg -r -t get_outputs | jq -r '.[] | select(.focused == true).name') 21 swaymsg workspace "$WS" 22 swaymsg move workspace to output "$CURRENT_OUTPUT" 23 ''; 24 }; 25 26in 27{ 28 # Make goto-workspace available system-wide for workspace switching 29 environment.systemPackages = [ gotoWorkspace ]; 30 31 # Firefox as a persistent systemd user service — starts after workspace-manager 32 # so the sway rule to hide the anchor window is already registered 33 systemd.user.services.firefox = { 34 description = "Firefox Web Browser"; 35 partOf = [ "sway-session.target" ]; 36 wantedBy = [ "sway-session.target" ]; 37 after = [ 38 "sway-session.target" 39 "workspace-manager.service" 40 ]; 41 # Never restart on `nixos-rebuild switch` — that would kill all open 42 # browser windows. A new Firefox build is only picked up at the next 43 # sway session start. 44 restartIfChanged = false; 45 stopIfChanged = false; 46 serviceConfig = { 47 Type = "simple"; 48 ExecStart = lib.getExe self.packages.${pkgs.system}.firefox; 49 Restart = "always"; 50 RestartSec = 2; 51 }; 52 }; 53 imports = [ 54 ../lib/wayland.nix 55 ./noctalia.nix 56 ./wallpaper.nix 57 ]; 58 programs.sway = { 59 enable = true; 60 wrapperFeatures.gtk = true; 61 # Do NOT hardcode SWAYSOCK here: sway >=1.11 ignores an inherited value and 62 # creates its own per-pid socket (sway-ipc.$uid.$pid.sock). Exporting a 63 # fixed path baked a dead socket into the firefox/workspace-manager user 64 # services, breaking all swaymsg calls (and thus tab restore). Let sway 65 # advertise the real socket; the import-environment below propagates it. 66 }; 67 68 # Enable realtime scheduling for sway 69 security.pam.loginLimits = [ 70 { 71 domain = "@users"; 72 item = "rtprio"; 73 type = "-"; 74 value = 1; 75 } 76 ]; 77 78 systemd.user.services.swayidle = { 79 description = "Idle manager for Wayland"; 80 documentation = [ "man:swayidle(1)" ]; 81 partOf = [ "sway-session.target" ]; 82 wantedBy = [ "sway-session.target" ]; 83 serviceConfig = { 84 Type = "simple"; 85 ExecStart = '' 86 ${pkgs.swayidle}/bin/swayidle -w \ 87 timeout 120 '${lib.getExe' pkgs.systemd "systemctl"} --user start lock.target' \ 88 timeout 300 '${lib.getExe' pkgs.systemd "systemctl"} suspend-then-hibernate' \ 89 before-sleep '${lib.getExe' pkgs.systemd "systemctl"} --user start lock.target' 90 ''; 91 Restart = "on-failure"; 92 RestartSec = 1; 93 }; 94 }; 95 96 # Inhibit idle when audio is playing (prevents suspend during calls/music) 97 systemd.user.services.sway-audio-idle-inhibit = { 98 description = "Inhibit idle when audio is playing"; 99 partOf = [ "sway-session.target" ]; 100 wantedBy = [ "sway-session.target" ]; 101 serviceConfig = { 102 Type = "simple"; 103 ExecStart = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit"; 104 Restart = "on-failure"; 105 RestartSec = 1; 106 }; 107 }; 108 109 systemd.user.services.sway-urgent-rumble = { 110 description = "Trigger rumble on urgent windows"; 111 partOf = [ "sway-session.target" ]; 112 wantedBy = [ "sway-session.target" ]; 113 serviceConfig = { 114 Type = "simple"; 115 ExecStart = lib.getExe ( 116 pkgs.writeShellApplication { 117 name = "sway-urgent-rumble"; 118 runtimeInputs = [ 119 pkgs.sway 120 pkgs.jq 121 self.packages.${pkgs.system}.gpd-rumble 122 ]; 123 text = '' 124 # Find first force-feedback capable device 125 FF_DEVICE="" 126 for ev in /sys/class/input/event*; do 127 if [ -f "$ev/device/capabilities/ff" ] && [ "$(cat "$ev/device/capabilities/ff")" != "0" ]; then 128 FF_DEVICE="/dev/input/''${ev##*/}" 129 break 130 fi 131 done 132 133 if [ -z "$FF_DEVICE" ]; then 134 echo "No force-feedback device found, exiting" 135 exit 0 136 fi 137 138 echo "Using force-feedback device: $FF_DEVICE" 139 140 swaymsg -t subscribe -m '["window"]' | \ 141 jq --unbuffered -r 'select(.change == "urgent" and .container.urgent == true) | "urgent"' | \ 142 while read -r _; do 143 gpd-rumble 200 100 "$FF_DEVICE" & 144 done 145 ''; 146 } 147 ); 148 Restart = "on-failure"; 149 RestartSec = 1; 150 }; 151 }; 152 153 environment.etc."sway/config".text = '' 154 # Default config for sway 155 # 156 # Copy this to ~/.config/sway/config and edit it to your liking. 157 # 158 # Read `man 5 sway` for a complete reference. 159 160 ### Variables 161 # 162 # Logo key. Use Mod1 for Alt. 163 set $mod Mod4 164 # Home row direction keys, like vim 165 set $left h 166 set $down j 167 set $up k 168 set $right l 169 # Your preferred terminal emulator 170 set $term ${term} 171 # Your preferred application launcher 172 # Note: pass the final command to swaymsg so that the resulting window can be opened 173 # on the original workspace that the command was run on. 174 set $menu ${pkgs.dmenu}/bin/dmenu_path | menu | xargs swaymsg exec -- 175 176 ### Output configuration 177 # 178 # Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/) 179 # output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill 180 # 181 # Example configuration: 182 # 183 # output HDMI-A-1 resolution 1920x1080 position 1920,0 184 # 185 # You can get the names of your outputs by running: swaymsg -t get_outputs 186 187 # Per-machine output overrides (scale, resolution, position) live here. 188 include /etc/sway/config.d/*.conf 189 190 ### Idle configuration 191 # 192 # Example configuration: 193 # 194 # exec swayidle -w \ 195 # timeout 300 'swaylock -f -c 000000' \ 196 # timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \ 197 # before-sleep 'swaylock -f -c 000000' 198 # 199 # This will lock your screen after 300 seconds of inactivity, then turn off 200 # your displays after another 300 seconds, and turn your screens back on when 201 # resumed. It will also lock your screen before your computer goes to sleep. 202 203 ### Input configuration 204 # 205 # Example configuration: 206 # 207 input "2321:21128:HTIX5288:00_0911:5288_Touchpad" { 208 tap enabled 209 } 210 input "2362:628:PIXA3854:00_093A:0274_Touchpad" { 211 tap enabled 212 } 213 # 214 # You can get the names of your inputs by running: swaymsg -t get_inputs 215 # Read `man 5 sway-input` for more information about this section. 216 217 ### Key bindings 218 # 219 # Basics: 220 # 221 # Start a terminal 222 bindsym $mod+Shift+Return exec $term 223 224 # Kill focused window 225 bindsym $mod+Shift+c kill 226 227 # Start your launcher 228 bindsym $mod+d exec $menu 229 230 # Drag floating windows by holding down $mod and left mouse button. 231 # Resize them with right mouse button + $mod. 232 # Despite the name, also works for non-floating windows. 233 # Change normal to inverse to use left mouse button for resizing and right 234 # mouse button for dragging. 235 floating_modifier $mod normal 236 237 # Reload the configuration file 238 bindsym $mod+Shift+r reload 239 240 # Exit sway (logs you out of your Wayland session) 241 bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit' 242 # 243 # Moving around: 244 # 245 # Move your focus around 246 bindsym $mod+Left focus left 247 bindsym $mod+Down focus down 248 bindsym $mod+Up focus up 249 bindsym $mod+Right focus right 250 251 # Move the focused window with the same, but add Shift 252 bindsym $mod+Shift+Left move left 253 bindsym $mod+Shift+Down move down 254 bindsym $mod+Shift+Up move up 255 bindsym $mod+Shift+Right move right 256 # Layout stuff: 257 # 258 # Split bindings removed to avoid accidental sub-containers. 259 # Use $mod+w to flatten into tabs, $mod+e to toggle split direction. 260 bindsym $mod+n split none 261 262 # Switch the current container between different layout styles 263 bindsym $mod+s layout stacking 264 bindsym $mod+w layout tabbed 265 bindsym $mod+e layout toggle split 266 267 # Make the current focus fullscreen 268 bindsym $mod+f fullscreen 269 270 # Toggle the current focus between tiling and floating mode 271 bindsym $mod+Shift+space floating toggle 272 273 # Swap focus between the tiling area and the floating area 274 bindsym $mod+a focus mode_toggle 275 276 # Workspace manager menu 277 bindsym $mod+space exec ${lib.getExe self.packages.${pkgs.system}.workspace-menu} 278 279 # Move focus to the parent container 280 bindsym $mod+Shift+a focus parent 281 # 282 # Scratchpad: 283 # 284 # Sway has a "scratchpad", which is a bag of holding for windows. 285 # You can send windows there and get them back later. 286 287 # Move the currently focused window to the scratchpad 288 bindsym $mod+Shift+minus move scratchpad 289 290 # Show the next scratchpad window or hide the focused scratchpad window. 291 # If there are multiple scratchpad windows, this command cycles through them. 292 bindsym $mod+minus scratchpad show 293 # 294 # Resizing containers: 295 # 296 mode "resize" { 297 # left will shrink the containers width 298 # right will grow the containers width 299 # up will shrink the containers height 300 # down will grow the containers height 301 bindsym $left resize shrink width 10px 302 bindsym $down resize grow height 10px 303 bindsym $up resize shrink height 10px 304 bindsym $right resize grow width 10px 305 306 # Ditto, with arrow keys 307 bindsym Left resize shrink width 10px 308 bindsym Down resize grow height 10px 309 bindsym Up resize shrink height 10px 310 bindsym Right resize grow width 10px 311 312 # Return to default mode 313 bindsym Return mode "default" 314 bindsym Escape mode "default" 315 } 316 bindsym $mod+r mode "resize" 317 318 default_border pixel 1 319 default_floating_border none 320 smart_borders on 321 322 bindsym $mod+q exec ${pkgs.writers.writeDash "goto_workspace" '' 323 set -efux 324 WS=$(swaymsg -r -t get_workspaces | 325 jq -r '.[].name' | 326 menu -p 'Workspace name: ' 327 ) 328 if [ -n "$WS" ]; then 329 ${lib.getExe gotoWorkspace} "$WS" 330 fi 331 ''} 332 333 bindsym $mod+Shift+q exec ${pkgs.writers.writeDash "moveto_workspace" '' 334 set -efux 335 WS=$(swaymsg -r -t get_workspaces | 336 jq -r '.[].name' | 337 menu -p 'Workspace name: ' 338 ) 339 if [ -n "$WS" ]; then 340 swaymsg move container to workspace "$WS" 341 fi 342 ''} 343 344 bindsym $mod+y exec /run/current-system/sw/bin/switch-theme toggle 345 346 bindsym $mod+Tab exec ${pkgs.sway-overfocus}/bin/sway-overfocus split-rw group-rw split-dw group-dw 347 bindsym $mod+Escape workspace back_and_forth 348 349 # Focus primary output 350 bindsym $mod+F1 exec ${ 351 lib.getExe ( 352 pkgs.writeShellApplication { 353 name = "focus-primary-output"; 354 runtimeInputs = [ 355 pkgs.sway 356 pkgs.jq 357 ]; 358 text = '' 359 PRIMARY=$(swaymsg -r -t get_outputs | jq -r 'sort_by(.x, .y) | .[0].name') 360 swaymsg focus output "$PRIMARY" 361 ''; 362 } 363 ) 364 } 365 366 # Cycle through secondary outputs 367 bindsym $mod+F2 exec ${ 368 lib.getExe ( 369 pkgs.writeShellApplication { 370 name = "cycle-secondary-outputs"; 371 runtimeInputs = [ 372 pkgs.sway 373 pkgs.jq 374 pkgs.gnugrep 375 pkgs.coreutils 376 ]; 377 text = '' 378 OUTPUTS=$(swaymsg -r -t get_outputs | jq -r 'sort_by(.x, .y)') 379 PRIMARY=$(echo "$OUTPUTS" | jq -r '.[0].name') 380 CURRENT=$(echo "$OUTPUTS" | jq -r '.[] | select(.focused == true).name') 381 SECONDARIES=$(echo "$OUTPUTS" | jq -r '.[1:] | .[].name') 382 383 if [ -z "$SECONDARIES" ]; then 384 exit 0 385 fi 386 387 if [ "$CURRENT" = "$PRIMARY" ]; then 388 # Focus first secondary 389 NEXT=$(echo "$SECONDARIES" | head -n1) 390 else 391 # Find next secondary in the list 392 NEXT=$(echo "$SECONDARIES" | grep -A1 "^$CURRENT$" | tail -n1) 393 # If we're at the end, wrap to first secondary 394 if [ "$NEXT" = "$CURRENT" ]; then 395 NEXT=$(echo "$SECONDARIES" | head -n1) 396 fi 397 fi 398 399 swaymsg focus output "$NEXT" 400 ''; 401 } 402 ) 403 } 404 405 # screenlock (random live video/image from ~/wallpaper via swaylock-plugin) 406 bindsym $mod+F11 exec ${lib.getExe' pkgs.systemd "systemctl"} --user start lock.target 407 bindsym $mod+l exec ${lib.getExe' pkgs.systemd "systemctl"} --user start lock.target 408 409 # kill window (xkill-like) 410 mode "kill" { 411 bindsym --whole-window button1 kill, mode "default" 412 bindsym --whole-window button2 mode "default" 413 bindsym --whole-window button3 mode "default" 414 bindsym Escape mode "default" 415 } 416 bindsym $mod+x mode "kill" 417 418 # media buttons 419 bindsym XF86AudioMute exec ${pkgs.pulseaudio.out}/bin/pactl -- set-sink-mute @DEFAULT_SINK@ toggle 420 bindsym XF86AudioRaiseVolume exec ${pkgs.pulseaudio.out}/bin/pactl -- set-sink-volume @DEFAULT_SINK@ +4% 421 bindsym XF86AudioLowerVolume exec ${pkgs.pulseaudio.out}/bin/pactl -- set-sink-volume @DEFAULT_SINK@ -4% 422 423 # brightness keys 424 bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%- 425 bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+ 426 427 # background programs 428 exec ${pkgs.copyq}/bin/copyq --start-server 429 exec ydotoold 430 exec_always pkill kanshi; exec ${pkgs.kanshi}/bin/kanshi 431 432 433 # theme and env specific stuff 434 exec_always ${pkgs.writers.writeDash "dbus-sway-environment" '' 435 set -efux 436 # XDG_SESSION_TYPE=wayland must be exported here: with DISPLAY set but 437 # XDG_SESSION_TYPE unset, Firefox (and other apps) started from the systemd 438 # user manager pick the X11/XWayland screencast path, which captures a black 439 # screen under sway. Setting it explicitly makes them use the PipeWire portal. 440 dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP=sway XDG_SESSION_TYPE=wayland 441 systemctl --user set-environment XDG_SESSION_TYPE=wayland 442 systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP 443 systemctl --user start --no-block sway-session.target 444 systemctl --user stop xdg-desktop-portal xdg-desktop-portal-wlr 445 systemctl --user start xdg-desktop-portal xdg-desktop-portal-wlr 446 ''} 447 448 exec_always ${pkgs.writers.writeDash "gsettings" '' 449 set -efux 450 export XDG_DATA_DIRS=${pkgs.gsettings-desktop-schemas}:$XDG_DATA_DIRS 451 gnome_schema=org.gnome.desktop.interface 452 gsettings set $gnome_schema gtk-theme 'Dracula' 453 ''} 454 455 # keyboard 456 input type:keyboard { 457 xkb_layout us 458 xkb_variant altgr-intl 459 xkb_options caps:hyper 460 } 461 462 # Hide the workspace-manager Firefox anchor window. Registered statically 463 # here (not just by the daemon at runtime) so the rule exists before the 464 # firefox.service starts, otherwise the anchor flashes onto the current 465 # workspace and gets captured as a phantom tab. 466 for_window [title="^workspace-anchor"] move scratchpad 467 468 # flameshot 469 for_window [app_id="flameshot"] border pixel 0, floating enable, fullscreen disable, move absolute position 0 0 470 exec ${pkgs.flameshot}/bin/flameshot 471 ''; 472 473}