diff options
Diffstat (limited to 'modules/user/sternenseemann')
-rw-r--r-- | modules/user/sternenseemann/services/sway.nix | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/modules/user/sternenseemann/services/sway.nix b/modules/user/sternenseemann/services/sway.nix new file mode 100644 index 00000000..8a81c41c --- /dev/null +++ b/modules/user/sternenseemann/services/sway.nix @@ -0,0 +1,317 @@ +{ config, pkgs, lib, ... }: + +let + + cfg = config.vuizvui.user.sternenseemann.services.sway; + + inherit (pkgs.vuizvui.profpatsch) + getBins + ; + + bins = (getBins config.hardware.pulseaudio.package [ "pactl" ]) + // (getBins pkgs.dbus [ "dbus-run-session" ]) + // (getBins cfg.package [ "sway" ]) + // (getBins pkgs.i3status [ "i3status" ]) + // (getBins pkgs.brightnessctl [ "brightnessctl" ]) + // (getBins pkgs.swaylock [ "swaylock" ]) + ; + + dpiXresources = pkgs.writeText "Xresources" '' + Xft.dpi: 96 + ''; + + workspaceConfig = lib.concatMapStringsSep "\n" (n: '' + bindsym $mod+${n} workspace number ${n} + bindsym $mod+Shift+${n} move container to workspace number ${n} + '') (builtins.map builtins.toString [ 0 1 2 3 4 5 6 7 8 9 ]); + + additionalBindsConfig = lib.concatStringsSep "\n" + (lib.mapAttrsToList (bind: cmd: '' + bindsym ${bind} exec ${cmd} + '') cfg.additionalBinds); + + mkColorOption = name: default: lib.mkOption { + type = lib.types.str; + description = "${name} color"; + inherit default; + }; + +in { + options = { + vuizvui.user.sternenseemann.services.sway = { + enable = lib.mkEnableOption "sterni's sway"; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.sway.override { + withBaseWrapper = true; + withGtkWrapper = true; + }; + description = "Sway package to use."; + }; + + menu = lib.mkOption { + type = lib.types.str; + description = "Menu launcher command to use."; + }; + + term = lib.mkOption { + type = lib.types.str; + description = "Terminal emulator command to use."; + }; + + lockArgs = lib.mkOption { + type = with lib.types; listOf str; + description = '' + Arguments to pass to swaylock. + ''; + default = []; + }; + + additionalBinds = lib.mkOption { + type = with lib.types; attrsOf str; + default = {}; + description = '' + Additional key bindings which are appended + to the end of the sway config file. + ''; + }; + + colors = { + background = mkColorOption "background" "#000000"; + active = mkColorOption "active window" "#ffffff"; + inactive = mkColorOption "inactive window" "#000000"; + urgent = mkColorOption "urgent window" "#900000"; + indicate = mkColorOption "indicator" "#d0d0d0"; + }; + + font = { + name = lib.mkOption { + type = lib.types.str; + description = '' + Name of the font to use for bar and window titles. + ''; + default = "monospace"; + }; + + size = lib.mkOption { + type = lib.types.int; + description = '' + Font size to use for bar and window titles. + ''; + default = 12; + }; + }; + + autolaunchFish = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether to automatically start sway when logging in on tty1. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + programs.fish.loginShellInit = lib.mkIf cfg.autolaunchFish '' + if test -z "$DISPLAY"; and test -z "$WAYLAND_DISPLAY"; and test (tty) = "/dev/tty1" + set -x SWAYSOCK "/run/user/"(id -u)"/sway.sock" + exec ${bins.dbus-run-session} -- ${bins.sway} + end + ''; + + environment.systemPackages = [ + cfg.package + ]; + + environment.sessionVariables = { + # firefox screencapture + XDG_SESSION_TYPE = "wayland"; + XDG_CURRENT_DESKTOP = "sway"; + MOZ_ENABLE_WAYLAND = "1"; + MOZ_USE_XINPUT2 = "1"; + # SDL + SDL_VIDEODRIVER = "wayland"; + # QT + QT_QPA_PLATFORM = "wayland"; + QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; + # keyboard layout + XKB_DEFAULT_LAYOUT = "de"; + XKB_DEFAULT_VARIANT = "neo"; + }; + + services.pipewire.enable = true; + + xdg.portal = { + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-wlr + xdg-desktop-portal-gtk + ]; + gtkUsePortal = true; + }; + + security.pam.services.swaylock = {}; + + environment.etc = { + "sway/config".text = '' + # correct DPI after hotplugging + exec ${pkgs.xorg.xrdb}/bin/xrdb -load ${dpiXresources} + + # set the one true modifier + set $mod Mod4 + + # neo arrow keys + set $left i + set $right e + set $up l + set $down a + + bindsym $mod+Shift+c reload + + bindsym $mod+Shift+q kill + + bindsym $mod+f fullscreen + + bindsym $mod+h splith + bindsym $mod+v splitv + + bindsym $mod+s layout stacking + bindsym $mod+t layout tabbed + bindsym $mod+n layout toggle split + + # focus + bindsym $mod+Shift+space floating toggle + bindsym $mod+space focus mode_toggle + floating_modifier $mod normal + + bindsym $mod+p focus parent + + bindsym $mod+$left focus left + bindsym $mod+$down focus down + bindsym $mod+$up focus up + bindsym $mod+$right focus right + + # moving + bindsym $mod+Shift+$left move left + bindsym $mod+Shift+$down move down + bindsym $mod+Shift+$up move up + bindsym $mod+Shift+$right move right + + # resizing + mode "resize" { + bindsym $left resize shrink width 10px + bindsym $down resize grow height 10px + bindsym $up resize shrink height 10px + bindsym $right resize grow width 10px + + bindsym Return mode "default" + bindsym Escape mode "default" + } + bindsym $mod+r mode "resize" + + ${workspaceConfig} + + bindsym $mod+u exec ${bins.swaylock} ${lib.escapeShellArgs cfg.lockArgs} + + # volume controls + bindsym XF86AudioRaiseVolume exec ${bins.pactl} set-sink-volume @DEFAULT_SINK@ +5% + bindsym XF86AudioLowerVolume exec ${bins.pactl} set-sink-volume @DEFAULT_SINK@ -5% + bindsym XF86AudioMute exec ${bins.pactl} set-sink-mute @DEFAULT_SINK@ toggle + bindsym XF86AudioMicMute exec ${bins.pactl} set-source-mute @DEFAULT_SOURCE@ toggle + + # brightness controls + bindsym XF86MonBrightnessDown exec ${bins.brightnessctl} set 5%- + bindsym XF86MonBrightnessUp exec ${bins.brightnessctl} set +5% + + # standard launch binds + bindsym $mod+Return exec ${cfg.term} + bindsym $mod+d exec ${cfg.menu} + + ${additionalBindsConfig} + + # aesthetics + font "${cfg.font.name} ${builtins.toString cfg.font.size}" + + # waste some space + gaps inner 10 + + # colors + set $bg ${cfg.colors.background} + set $act ${cfg.colors.active} + set $inact ${cfg.colors.inactive} + set $urg ${cfg.colors.urgent} + set $ind ${cfg.colors.indicate} + + output * bg $bg solid_color + + # class border backgr. text indicator + client.focused $act $act $inact $ind + client.focused_inactive $inact $inact $act $inact + client.unfocused $inact $inact $act $inact + client.urgent $urg $urg $act $urg + + # bar aesthetics + bar { + # TODO(sterni): replace i3status with something better™ + status_command ${bins.i3status} + position top + colors { + font "${cfg.font.name} ${builtins.toString cfg.font.size}" + statusline $act + background $inact + # type border bg text + focused_workspace $act $act $inact + active_workspace $act $act $ind + inactive_workspace $inact $inact $act + urgent_workspace $urg $urg $act + } + } + ''; + + "xdg/i3status/config".text = '' + general { + output_format = "i3bar" + colors = true + interval = 1 + } + + order += "volume master" + order += "battery all" + order += "tztime dotdate" + order += "tztime dottime" + order += "tztime offset" + + volume master { + format = "🔊: %volume" + format_muted = "🔈: %volume" + device = "pulse" + } + + battery all { + format = "%status: %percentage" + status_chr = "⚡" + status_bat = "🔋" + status_unk = "❓" + status_full = "💯" + low_threshold = 10 + } + + tztime dotdate { + timezone = "UTC" + format = "%Y-%m-%d" + } + + tztime dottime { + timezone = "UTC" + format = "%H·%M" + } + + tztime offset { + format = "%z" + } + ''; + }; + }; +} |