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