diff --git a/modules/services/window-managers/i3-sway/sway.nix b/modules/services/window-managers/i3-sway/sway.nix index b713c715..66d25b01 100644 --- a/modules/services/window-managers/i3-sway/sway.nix +++ b/modules/services/window-managers/i3-sway/sway.nix @@ -162,6 +162,36 @@ let ''; }; + bindswitches = mkOption { + type = types.attrsOf bindswitchOption; + default = { }; + defaultText = "No bindswitches by default"; + description = '' + Binds to execute the sway command command on state changes. Supported switches are lid (laptop + lid) and tablet (tablet mode) switches. Valid values for state are on, off and toggle. These switches are + on when the device lid is shut and when tablet mode is active respectively. toggle is also supported to run + a command both when the switch is toggled on or off. + See sway(5). + ''; + example = lib.literalExpression '' + let + laptop = "eDP-1"; + in + { + "lid:on" = { + reload = true; + locked = true; + action = "output ''${laptop} disable"; + }; + "lid:off" = { + reload = true; + locked = true; + action = "output ''${laptop} enable"; + }; + } + ''; + }; + bindkeysToCode = mkOption { type = types.bool; default = false; @@ -267,6 +297,42 @@ let }; }; + bindswitchOption = types.submodule { + options = { + action = mkOption { + type = types.str; + description = "The sway command to execute on state changes"; + }; + + locked = mkOption { + type = types.bool; + default = false; + description = '' + Unless the flag --locked is set, the command + will not be run when a screen locking program + is active. If there is a matching binding with + and without --locked, the one with will be preferred + when locked and the one without will be + preferred when unlocked. + ''; + }; + + reload = mkOption { + type = types.bool; + default = false; + description = '' + If the --reload flag is given, the binding will + also be executed when the config is reloaded. + toggle bindings will not be executed on reload. + The --locked flag will operate as normal so if + the config is reloaded while locked and + --locked is not given, the binding will not be + executed. + ''; + }; + }; + }; + commonFunctions = import ./lib/functions.nix { inherit config cfg lib; moduleName = "sway"; @@ -290,11 +356,32 @@ let ; startupEntryStr = - { command, always, ... }: + { + command, + always, + ... + }: '' ${if always then "exec_always" else "exec"} ${command} ''; + bindswitchesStr = + bindswitches: + concatStringsSep "\n" ( + mapAttrsToList ( + event: + { + locked, + reload, + action, + }: + let + args = (lib.optionalString locked "--locked ") + (lib.optionalString reload "--reload "); + in + "bindswitch ${args} ${event} ${action}" + ) bindswitches + ); + moduleStr = moduleType: name: attrs: '' ${moduleType} "${name}" { ${concatStringsSep "\n" (lib.mapAttrsToList (name: value: " ${name} ${value}") attrs)} @@ -358,6 +445,7 @@ let }) (keycodebindingsStr keycodebindings) ] + ++ optional (builtins.attrNames bindswitches != [ ]) (bindswitchesStr bindswitches) ++ mapAttrsToList inputStr input ++ mapAttrsToList outputStr output # outputs ++ mapAttrsToList seatStr seat # seats @@ -378,7 +466,6 @@ let ++ [ cfg.extraConfig ] ); }; - in { meta.maintainers = with lib.maintainers; [ diff --git a/tests/modules/services/window-managers/sway/default.nix b/tests/modules/services/window-managers/sway/default.nix index 1212bf58..ad6745b3 100644 --- a/tests/modules/services/window-managers/sway/default.nix +++ b/tests/modules/services/window-managers/sway/default.nix @@ -1,6 +1,7 @@ { sway-bar-focused-colors = ./sway-bar-focused-colors.nix; sway-bindkeys-to-code-and-extra-config = ./sway-bindkeys-to-code-and-extra-config.nix; + sway-bindswitches = ./sway-bindswitches.nix; sway-default = ./sway-default.nix; sway-followmouse = ./sway-followmouse.nix; sway-followmouse-legacy = ./sway-followmouse-legacy.nix; diff --git a/tests/modules/services/window-managers/sway/sway-bindswitches.conf b/tests/modules/services/window-managers/sway/sway-bindswitches.conf new file mode 100644 index 00000000..de25387a --- /dev/null +++ b/tests/modules/services/window-managers/sway/sway-bindswitches.conf @@ -0,0 +1,110 @@ +font pango:monospace 8.000000 +floating_modifier Mod1 +default_border pixel 2 +default_floating_border pixel 2 +hide_edge_borders none +focus_wrapping no +focus_follows_mouse yes +focus_on_window_activation smart +mouse_warping output +workspace_layout default +workspace_auto_back_and_forth no +client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 +client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a +client.unfocused #333333 #222222 #888888 #292d2e #222222 +client.urgent #2f343a #900000 #ffffff #900000 #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c +client.background #ffffff + +bindsym Mod1+0 workspace number 10 +bindsym Mod1+1 workspace number 1 +bindsym Mod1+2 workspace number 2 +bindsym Mod1+3 workspace number 3 +bindsym Mod1+4 workspace number 4 +bindsym Mod1+5 workspace number 5 +bindsym Mod1+6 workspace number 6 +bindsym Mod1+7 workspace number 7 +bindsym Mod1+8 workspace number 8 +bindsym Mod1+9 workspace number 9 +bindsym Mod1+Down focus down +bindsym Mod1+Left focus left +bindsym Mod1+Return exec @foot@/bin/foot +bindsym Mod1+Right focus right +bindsym Mod1+Shift+0 move container to workspace number 10 +bindsym Mod1+Shift+1 move container to workspace number 1 +bindsym Mod1+Shift+2 move container to workspace number 2 +bindsym Mod1+Shift+3 move container to workspace number 3 +bindsym Mod1+Shift+4 move container to workspace number 4 +bindsym Mod1+Shift+5 move container to workspace number 5 +bindsym Mod1+Shift+6 move container to workspace number 6 +bindsym Mod1+Shift+7 move container to workspace number 7 +bindsym Mod1+Shift+8 move container to workspace number 8 +bindsym Mod1+Shift+9 move container to workspace number 9 +bindsym Mod1+Shift+Down move down +bindsym Mod1+Shift+Left move left +bindsym Mod1+Shift+Right move right +bindsym Mod1+Shift+Up move up +bindsym Mod1+Shift+c reload +bindsym Mod1+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' +bindsym Mod1+Shift+h move left +bindsym Mod1+Shift+j move down +bindsym Mod1+Shift+k move up +bindsym Mod1+Shift+l move right +bindsym Mod1+Shift+minus move scratchpad +bindsym Mod1+Shift+q kill +bindsym Mod1+Shift+space floating toggle +bindsym Mod1+Up focus up +bindsym Mod1+a focus parent +bindsym Mod1+b splith +bindsym Mod1+d exec @dmenu@/bin/dmenu_run +bindsym Mod1+e layout toggle split +bindsym Mod1+f fullscreen toggle +bindsym Mod1+h focus left +bindsym Mod1+j focus down +bindsym Mod1+k focus up +bindsym Mod1+l focus right +bindsym Mod1+minus scratchpad show +bindsym Mod1+r mode resize +bindsym Mod1+s layout stacking +bindsym Mod1+space focus mode_toggle +bindsym Mod1+v splitv +bindsym Mod1+w layout tabbed + +bindswitch lid:on exec echo "Lid moved" +bindswitch --locked --reload tablet:on exec echo "Lid moved" +mode "resize" { + bindsym Down resize grow height 10 px + bindsym Escape mode default + bindsym Left resize shrink width 10 px + bindsym Return mode default + bindsym Right resize grow width 10 px + bindsym Up resize shrink height 10 px + bindsym h resize shrink width 10 px + bindsym j resize grow height 10 px + bindsym k resize shrink height 10 px + bindsym l resize grow width 10 px +} + +bar { + font pango:monospace 8.000000 + mode dock + hidden_state hide + position bottom + status_command @i3status@/bin/i3status + swaybar_command @sway@/bin/swaybar + workspace_buttons yes + strip_workspace_numbers no + tray_output * + colors { + background #000000 + statusline #ffffff + separator #666666 + focused_workspace #4c7899 #285577 #ffffff + active_workspace #333333 #5f676a #ffffff + inactive_workspace #333333 #222222 #888888 + urgent_workspace #2f343a #900000 #ffffff + binding_mode #2f343a #900000 #ffffff + } +} + +exec "@dbus@/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP XDG_SESSION_TYPE NIXOS_OZONE_WL XCURSOR_THEME XCURSOR_SIZE; systemctl --user reset-failed && systemctl --user start sway-session.target && swaymsg -mt subscribe '[]' || true && systemctl --user stop sway-session.target" diff --git a/tests/modules/services/window-managers/sway/sway-bindswitches.nix b/tests/modules/services/window-managers/sway/sway-bindswitches.nix new file mode 100644 index 00000000..3fae58b0 --- /dev/null +++ b/tests/modules/services/window-managers/sway/sway-bindswitches.nix @@ -0,0 +1,30 @@ +{ config, pkgs, ... }: + +{ + home.enableNixpkgsReleaseCheck = false; + wayland.windowManager.sway = { + enable = true; + package = config.lib.test.mkStubPackage { outPath = "@sway@"; }; + checkConfig = false; + # overriding findutils causes issues + config.menu = "${pkgs.dmenu}/bin/dmenu_run"; + config = { + bindswitches = { + "lid:on" = { + action = ''exec echo "Lid moved"''; + }; + "tablet:on" = { + action = ''exec echo "Lid moved"''; + reload = true; + locked = true; + }; + }; + }; + }; + + nmt.script = '' + assertFileExists home-files/.config/sway/config + assertFileContent home-files/.config/sway/config \ + ${./sway-bindswitches.conf} + ''; +}