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

512 lines
17 KiB
Nix
Raw Normal View History

2020-12-05 15:01:40 +01:00
{ config, lib, pkgs, ... }:
2020-11-07 14:13:43 +01:00
let
common = import ./common.nix;
solarized = common.colorschemes.solarized;
2020-12-02 21:39:42 +01:00
wallpaper = pkgs.stdenv.mkDerivation {
name = "wallpaper";
src = pkgs.fetchurl {
url = "https://i.pximg.net/img-original/img/2013/10/22/04/25/37/39266182_p0.jpg";
sha256 = "053gc9jd4cbkkwgcirrhpzbn933dfh83l30p1sz55m5d8zx1lk65";
curlOpts = "--referer https://pixiv.net";
};
nativeBuildInputs = [
pkgs.unstable.waifu2x-converter-cpp
];
# -o $out does not work (why?)
buildPhase = ''
waifu2x-converter-cpp -i $src -o wallpaper.png
'';
installPhase = ''
cp wallpaper.png $out
'';
dontUnpack = true;
dontConfigure = true;
dontFixup = true;
};
2020-11-07 14:13:43 +01:00
cfg = config.wayland.windowManager.sway.config;
thinsp = "";
2020-12-07 19:49:43 +01:00
waybar = (pkgs.waybar.override { pulseSupport = true; }); # FIXME: Remove override with 21.03 (https://github.com/NixOS/nixpkgs/pull/98490)
2020-11-07 14:13:43 +01:00
in
lib.mkIf config.sbruder.gui.enable {
2020-11-07 14:13:43 +01:00
wayland.windowManager.sway = {
enable = true;
2020-12-07 19:52:06 +01:00
systemdIntegration = true;
2020-11-07 14:13:43 +01:00
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";
# 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"'';
};
2020-12-07 19:49:43 +01:00
bars = [ ]; # started by systemd service
2020-11-07 14:13:43 +01:00
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}" \
2020-11-07 14:13:43 +01:00
timeout 300 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"' \
before-sleep "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}"
2020-11-07 14:13:43 +01:00
# Cursor
seat seat0 xcursor_theme Adwaita
exec ${pkgs.mako}/bin/mako
'';
extraSessionCommands = ''
export CLUTTER_BACKEND=wayland
export GDK_BACKEND=wayland
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.profileExtra = ''
2020-12-07 19:59:49 +01:00
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
export XDG_SESSION_TYPE="wayland" # otherwise set to tty
exec sway
fi
'';
2020-12-07 19:49:43 +01:00
home.packages = (with pkgs; [
alacritty # terminal
brightnessctl # control screen brightness
sway-contrib.grimshot # screenshots
2020-11-14 10:15:54 +01:00
wdisplays # graphical output manager
2020-12-07 19:49:43 +01:00
]) ++ [
waybar # better status bar FIXME: see above
];
2020-12-07 19:49:43 +01:00
# taken from <home-manager/modules/programs/waybar.nix>
systemd.user.services.waybar = {
Unit = {
Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
Documentation = "https://github.com/Alexays/Waybar/wiki";
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "dbus";
BusName = "fr.arouillard.waybar";
ExecStart = "${waybar}/bin/waybar"; # FIXME see above
Restart = "always";
RestartSec = "1sec";
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
};
xdg.configFile = {
2020-11-07 14:13:43 +01:00
# home-managers waybar module performs additional checks that are overly strict
"waybar/config".text = builtins.toJSON {
2020-11-07 14:13:43 +01:00
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
'';
2020-11-07 14:13:43 +01:00
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 = {
2020-12-05 18:53:35 +01:00
server = "${config.services.mpd.dataDir}/socket";
2020-11-07 14:13:43 +01:00
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)";
2020-12-05 18:53:35 +01:00
on-scroll-up = "${pkgs.mpc_cli}/bin/mpc -h ${config.services.mpd.dataDir}/socket volume +2";
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -h ${config.services.mpd.dataDir}/socket volume -2";
2020-11-07 14:13:43 +01:00
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 = "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) }'
'';
2020-11-07 14:13:43 +01:00
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 ({
2020-11-07 14:13:43 +01:00
src = ../files/waybar/style.css;
} // solarized);
2020-11-26 07:29:04 +01:00
# 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
'';
};
2020-11-07 14:13:43 +01:00
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;
};
};
2020-11-07 14:13:43 +01:00
}