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