nixos-config/users/simon/modules/sway.nix

488 lines
17 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{ config, lib, nixosConfig, pkgs, ... }:
let
common = import ./common.nix;
solarized = common.colorschemes.solarized;
# Source: “境目” by 3211 on Pixiv: https://www.pixiv.net/en/artworks/39266182
wallpaperUnfree = pkgs.fetchurl {
name = "wallpaper-unfree";
url = "https://i.pximg.net/img-original/img/2013/10/22/04/25/37/39266182_p0.jpg";
sha256 = "053gc9jd4cbkkwgcirrhpzbn933dfh83l30p1sz55m5d8zx1lk65";
curlOpts = "--referer https://pixiv.net";
meta.license = lib.licenses.unfree;
};
wallpaperFree = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/swaywm/sway/3b2bc894a5ebbcbbd6707d45a25d171779c2e874/assets/Sway_Wallpaper_Blue_1920x1080.png";
sha256 = "1rkqd0h7w64plibn7k3krk5vdc3pnv3fc7m2xc2mxnwrbsgngwsz";
meta.license = lib.licenses.cc0;
};
wallpaper = if nixosConfig.sbruder.unfree.allowAssets then wallpaperUnfree else wallpaperFree;
cfg = config.wayland.windowManager.sway.config;
thinsp = "";
in
lib.mkIf nixosConfig.sbruder.gui.enable {
wayland.windowManager.sway = {
enable = true;
systemdIntegration = true;
config = {
modifier = "Mod4";
terminal = "alacritty";
menu = "${pkgs.dmenu-wayland}/bin/dmenu-wl_path | ${pkgs.dmenu-wayland}/bin/dmenu-wl -nb '#002b36' -nf '#839496' -sb '#859900' -sf '#073642' | ${pkgs.findutils}/bin/xargs swaymsg exec --";
output = {
"*".bg = "${wallpaper} fill";
# FIXME: maybe use kanshi
eDP-1 = {
resolution = "1920x1080";
position = "0,424";
};
"Dell Inc. DELL U2410 F525M0A104NL" = {
resolution = "1920x1200";
position = "1920,0";
};
};
input."type:keyboard" = {
xkb_layout = "de";
xkb_options = "compose:caps";
xkb_numlock = "enable";
};
keybindings = {
# Basics
"${cfg.modifier}+Return" = "exec ${cfg.terminal}";
"${cfg.modifier}+Shift+c" = "kill";
"${cfg.modifier}+r" = "exec ${cfg.menu}";
"${cfg.modifier}+Control+r" = "reload";
"${cfg.modifier}+Shift+q" = "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'";
# Focus
"${cfg.modifier}+${cfg.left}" = "focus left";
"${cfg.modifier}+${cfg.down}" = "focus down";
"${cfg.modifier}+${cfg.up}" = "focus up";
"${cfg.modifier}+${cfg.right}" = "focus right";
"${cfg.modifier}+Left" = "focus left";
"${cfg.modifier}+Down" = "focus down";
"${cfg.modifier}+Up" = "focus up";
"${cfg.modifier}+Right" = "focus right";
# Moving
"${cfg.modifier}+Shift+${cfg.left}" = "move left";
"${cfg.modifier}+Shift+${cfg.down}" = "move down";
"${cfg.modifier}+Shift+${cfg.up}" = "move up";
"${cfg.modifier}+Shift+${cfg.right}" = "move right";
"${cfg.modifier}+Shift+Left" = "move left";
"${cfg.modifier}+Shift+Down" = "move down";
"${cfg.modifier}+Shift+Up" = "move up";
"${cfg.modifier}+Shift+Right" = "move right";
# Workspaces
"${cfg.modifier}+1" = "workspace number 1";
"${cfg.modifier}+2" = "workspace number 2";
"${cfg.modifier}+3" = "workspace number 3";
"${cfg.modifier}+4" = "workspace number 4";
"${cfg.modifier}+5" = "workspace number 5";
"${cfg.modifier}+6" = "workspace number 6";
"${cfg.modifier}+7" = "workspace number 7";
"${cfg.modifier}+8" = "workspace number 8";
"${cfg.modifier}+9" = "workspace number 9";
"${cfg.modifier}+0" = "workspace number 10";
"${cfg.modifier}+Shift+1" = "move container to workspace number 1";
"${cfg.modifier}+Shift+2" = "move container to workspace number 2";
"${cfg.modifier}+Shift+3" = "move container to workspace number 3";
"${cfg.modifier}+Shift+4" = "move container to workspace number 4";
"${cfg.modifier}+Shift+5" = "move container to workspace number 5";
"${cfg.modifier}+Shift+6" = "move container to workspace number 6";
"${cfg.modifier}+Shift+7" = "move container to workspace number 7";
"${cfg.modifier}+Shift+8" = "move container to workspace number 8";
"${cfg.modifier}+Shift+9" = "move container to workspace number 9";
"${cfg.modifier}+Shift+0" = "move container to workspace number 10";
# Moving workspaces between outputs
"${cfg.modifier}+Control+${cfg.left}" = "move workspace to output left";
"${cfg.modifier}+Control+${cfg.down}" = "move workspace to output down";
"${cfg.modifier}+Control+${cfg.up}" = "move workspace to output up";
"${cfg.modifier}+Control+${cfg.right}" = "move workspace to output right";
"${cfg.modifier}+Control+Left" = "move workspace to output left";
"${cfg.modifier}+Control+Down" = "move workspace to output down";
"${cfg.modifier}+Control+Up" = "move workspace to output up";
"${cfg.modifier}+Control+Right" = "move workspace to output right";
# Splits
"${cfg.modifier}+b" = "splith";
"${cfg.modifier}+v" = "splitv";
# Layouts
"${cfg.modifier}+s" = "layout stacking";
"${cfg.modifier}+t" = "layout tabbed";
"${cfg.modifier}+e" = "layout toggle split";
"${cfg.modifier}+f" = "fullscreen toggle";
"${cfg.modifier}+a" = "focus parent";
"${cfg.modifier}+Control+space" = "floating toggle";
"${cfg.modifier}+space" = "focus mode_toggle";
# Scratchpad
"${cfg.modifier}+Shift+minus" = "move scratchpad";
"${cfg.modifier}+minus" = "scratchpad show";
# Resize mode
"${cfg.modifier}+d" = "mode resize";
# Multimedia Keys
"XF86AudioMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle";
"XF86AudioMicMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle";
"--locked XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
"--locked XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%";
"XF86AudioRaiseVolume" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%";
"XF86AudioLowerVolume" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%";
"XF86AudioPrev" = "exec ${pkgs.mpc_cli}/bin/mpc next";
"XF86AudioNext" = "exec ${pkgs.mpc_cli}/bin/mpc prev";
"XF86AudioPlay" = "exec ${pkgs.mpc_cli}/bin/mpc toggle";
# Mumble PTT
"--no-repeat Shift_R" = "exec ${pkgs.dbus}/bin/dbus-send --session --type=method_call --dest=net.sourceforge.mumble.mumble / net.sourceforge.mumble.Mumble.startTalking";
"--no-repeat --release Shift_R" = "exec ${pkgs.dbus}/bin/dbus-send --session --type=method_call --dest=net.sourceforge.mumble.mumble / net.sourceforge.mumble.Mumble.stopTalking";
# reset
"Shift_R+Shift" = "exec ${pkgs.dbus}/bin/dbus-send --session --type=method_call --dest=net.sourceforge.mumble.mumble / net.sourceforge.mumble.Mumble.stopTalking";
# Locking and DPMS
"${cfg.modifier}+y" = "exec ${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}";
"--locked ${cfg.modifier}+q" = ''exec 'test $(swaymsg -t get_outputs | ${pkgs.jq}/bin/jq "[.[].dpms] | any") = "true" && swaymsg "output * dpms off" || swaymsg "output * dpms on"'';
};
bars = [
{ command = "waybar"; }
];
assigns = {
"2" = [
{ app_id = "firefox"; }
#{ class="Chromium"; }
];
"3" = [
{ app_id = "net.sourceforge.mumble."; }
{ class = "Claws-mail"; }
];
"4" = [
{ app_id = "anki"; }
{ app_id = "libreoffice-startcenter"; }
{ app_id = "net.sourceforge.gscan2pdf"; }
{ app_id = "org.pwmt.zathura"; }
{ app_id = "xournalpp"; }
];
"5" = [
{ app_id = "audacious"; }
{ app_id = "pavucontrol"; }
];
"8" = [
{ app_id = "darktable"; }
{ app_id = "org.inkscape.Inkscape"; }
{ class = "Blender"; }
{ class = "Gimp"; }
{ class = "krita"; }
];
};
window.border = 1;
floating = {
titlebar = true;
border = 1;
};
colors = {
focused = rec { border = "#93a1a1"; background = "#073642"; text = "#93a1a1"; indicator = "#2aa198"; childBorder = background; };
focusedInactive = rec { border = "#839496"; background = "#002b36"; text = "#839496"; indicator = "#2aa198"; childBorder = background; };
unfocused = rec { border = "#839496"; background = "#002b36"; text = "#839496"; indicator = "#2aa198"; childBorder = background; };
urgent = rec { border = "#073642"; background = "#dc322f"; text = "#073642"; indicator = "#2aa198"; childBorder = background; };
};
fonts = [ "monospace 10" ];
};
extraConfig = ''
# Auto lock
exec ${pkgs.swayidle}/bin/swayidle -w \
timeout 300 "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}" \
timeout 300 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"' \
before-sleep "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}"
# Cursor
seat seat0 xcursor_theme Adwaita
exec ${pkgs.mako}/bin/mako
'';
extraSessionCommands = ''
export CLUTTER_BACKEND=wayland
export GDK_BACKEND=wayland
export GDK_DPI_SCALE=1
export MOZ_ENABLE_WAYLAND=1
export QT_QPA_PLATFORM=wayland-egl
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
export SDL_VIDEODRIVER=wayland
export WLR_NO_HARDWARE_CURSORS=1
export _JAVA_AWT_WM_NONREPARENTING=1
'';
};
# Start on tty1
programs.zsh.initExtra = ''
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
export XDG_SESSION_TYPE="wayland" # otherwise set to tty
exec sway
fi
'';
home.packages = with pkgs; [
alacritty # terminal
brightnessctl # control screen brightness
sway-contrib.grimshot # screenshots
(waybar.override { pulseSupport = true; }) # better status bar FIXME: Remove override with 21.03 (https://github.com/NixOS/nixpkgs/pull/98490)
wdisplays # graphical output manager
];
xdg.configFile = {
# home-managers waybar module performs additional checks that are overly strict
"waybar/config".text = lib.generators.toJSON { } {
layer = "top";
position = "top";
height = 24;
modules-center = [ ];
modules-left = [
"sway/workspaces"
"sway/mode"
];
modules-right = [
"tray"
"custom/redshift"
"idle_inhibitor"
"backlight"
"mpd"
"pulseaudio"
"network"
"custom/vpn"
"network#speed"
"memory"
"cpu"
"temperature"
"battery"
"clock"
];
"sway/workspaces" = {
disable-scroll = true;
};
"sway/mode" = {
format = "{}";
};
tray = {
spacing = 5;
};
"custom/redshift" = {
interval = 10;
exec = pkgs.writeShellScript "waybar-redshift-state" ''
if systemctl --user show redshift | grep -q ActiveState=active; then
echo '{"tooltip": "Redshift active", "class": "active"}'
else
echo '{"tooltip": "Redshift inactive", "class": "inactive"}'
fi
'';
on-click = pkgs.writeShellScript "waybar-redshift-toggle" ''
if systemctl --user show redshift | grep -q ActiveState=active; then
systemctl --user stop redshift
else
systemctl --user start redshift
fi
'';
return-type = "json";
format = "";
tooltip = false;
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = " ";
deactivated = " ";
};
};
backlight = {
format = "{percent}% {icon}";
format-icons = [ " " " " " " " " " " " " " " ];
on-scroll-up = "brightnessctl set +5%";
on-scroll-down = "brightnessctl set 5%-";
};
mpd = {
server = "${config.services.mpd.dataDir}/socket";
format = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ";
format-disconnected = "Disconnected ";
format-stopped = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ";
unknown-tag = "N/A";
interval = 2;
tooltip-format = "MPD (connected)";
tooltip-format-disconnected = "MPD (disconnected)";
on-scroll-up = "${pkgs.mpc_cli}/bin/mpc volume +2";
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc volume -2";
consume-icons = {
on = " ";
};
random-icons = {
off = " ";
on = " ";
};
repeat-icons = {
on = " ";
};
single-icons = {
on = " ";
};
state-icons = {
paused = "";
playing = "";
};
};
pulseaudio = {
format = "{volume}% {icon} {format_source}";
format-bluetooth = "{volume}% {icon} {format_source}";
format-bluetooth-muted = " {icon} {format_source}"; # FIXME: see below
format-muted = " {format_source}"; # FIXME: use normal mute icon (ﱝ ), which for some reason is displayed right of the source?
format-source = "{volume}% ${thinsp}";
format-source-muted = "${thinsp}";
format-icons = {
car = " ";
default = [ "" "奔" "" ];
hands-free = " ";
headphone = " ";
headset = " ";
phone = " ";
portable = " ";
};
on-click-right = "pavucontrol";
};
network = {
format-wifi = "{essid} ({signalStrength}%) ";
format-ethernet = "{ifname}: {ipaddr}/{cidr} ";
format-linked = "{ifname} (No IP) ";
format-disconnected = "Disconnected ";
format-alt = "{ifname}: {ipaddr}/{cidr}";
tooltip = false;
on-click-right = "alacritty -e nmtui";
};
"custom/vpn" = {
interval = 10;
exec = pkgs.writeShellScript "vpn-state" ''
ip -j link \
| jq --unbuffered --compact-output '
[[.[].ifname | select(. | startswith("mullvad"))][] | split("-")[1] + " ${thinsp}"] as $conns
| { text: ($conns[0] // ""), class: (if $conns | length > 0 then "connected" else "disconnected" end) }'
'';
return-type = "json";
format = "{}";
tooltip = false;
};
"network#speed" = {
interval = 2;
format = "{bandwidthDownBits:>8} {bandwidthUpBits:>8} ";
format-alt = "{bandwidthDownOctets:>8} {bandwidthUpOctets:>8} ";
format-disconnected = " 0b/s 0b/s";
tooltip = false;
};
memory = {
interval = 2;
format = "{:2}% ";
};
cpu = {
interval = 2;
format = "{usage:2}% ";
tooltip = false;
};
temperature = {
critical-threshold = 80;
format = "{temperatureC}°C {icon}";
format-icons = [ "" "" "" "" "" ];
};
battery = {
interval = 5;
format = "{capacity}% {icon}";
format-charging = "{capacity}% ";
format-plugged = "{capacity}% ";
format-alt = "{time} {icon}";
format-icons = [ "" "" "" "" "" "" "" "" "" "" "" ];
states = {
critical = 15;
good = 95;
warning = 30;
};
};
clock = {
format = "{:%H:%M %Z}";
format-alt = "{:%Y-%m-%d (%a)}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
};
"waybar/style.css".source = pkgs.substituteAll ({
src = ../files/waybar/style.css;
} // solarized);
# FIXME deduplicate (everything except text is redundant)
"swaynag/config".text = ''
font=Monospace 12
[warning]
text=b58900
background=fdf6e3
border=eee8d5
border-bottom=eee8d5
button-background=eee8d5
[error]
text=dc322f
background=fdf6e3
border=eee8d5
border-bottom=eee8d5
button-background=eee8d5
'';
};
programs.mako = {
enable = true;
backgroundColor = solarized.base03;
borderColor = solarized.base02;
textColor = solarized.base0;
progressColor = "over ${solarized.base02}";
groupBy = "app-name";
defaultTimeout = 5000;
};
services.redshift = {
enable = true;
package = pkgs.redshift-wlr;
extraOptions = [ "-v" "-m" "wayland" ];
latitude = "49.52";
longitude = "10.17";
temperature = {
day = 6500;
night = 3500;
};
};
}