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