Simon Bruder
539befeba2
This still has some issues (notably the release not triggering when switching workspaces while the PTT key is hold).
497 lines
17 KiB
Nix
497 lines
17 KiB
Nix
{ config, lib, pkgs, ... }:
|
||
let
|
||
common = import ./common.nix;
|
||
solarized = common.colorschemes.solarized;
|
||
|
||
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;
|
||
};
|
||
|
||
cfg = config.wayland.windowManager.sway.config;
|
||
thinsp = " ";
|
||
in
|
||
lib.mkIf config.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.profileExtra = ''
|
||
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-manager’s waybar module performs additional checks that are overly strict
|
||
"waybar/config".text = builtins.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 -h ${config.services.mpd.dataDir}/socket volume +2";
|
||
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -h ${config.services.mpd.dataDir}/socket 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 = "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;
|
||
};
|
||
};
|
||
}
|