sway: Reorganise and split into multiple files

This commit is contained in:
Simon Bruder 2021-07-17 14:10:02 +02:00
parent f3d958c1a9
commit 00a919d6d7
Signed by: simon
GPG key ID: 8D3C82F9F309F8EC
8 changed files with 380 additions and 364 deletions

View file

@ -14,7 +14,7 @@
./pass.nix
./programs.nix
./scripts
./sway.nix
./sway
./tmate.nix
./tmux.nix
./vdirsyncer.nix

View file

@ -1,8 +1,5 @@
{ 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";
@ -22,10 +19,17 @@ let
wallpaper = if nixosConfig.sbruder.unfree.allowAssets then wallpaperUnfree else wallpaperFree;
cfg = config.wayland.windowManager.sway.config;
makoInhibitStateFile = "${config.xdg.dataHome}/mako/inhibit-state";
in
lib.mkIf nixosConfig.sbruder.gui.enable {
{
imports = lib.optionals nixosConfig.sbruder.gui.enable [
./gammastep.nix
./kanshi.nix
./mako.nix
./waybar.nix
./xdg-desktop-portal.nix
];
} // (lib.mkIf nixosConfig.sbruder.gui.enable {
wayland.windowManager.sway = {
enable = true;
@ -227,19 +231,6 @@ lib.mkIf nixosConfig.sbruder.gui.enable {
);
};
home.sessionVariables = {
CLUTTER_BACKEND = "wayland";
GDK_BACKEND = "wayland";
GDK_DPI_SCALE = 1;
MOZ_ENABLE_WAYLAND = 1;
QT_QPA_PLATFORM = "wayland-egl";
QT_WAYLAND_DISABLE_WINDOWDECORATION = 1;
SDL_VIDEODRIVER = "wayland";
WLR_NO_HARDWARE_CURSORS = 1;
_JAVA_AWT_WM_NONREPARENTING = 1;
_JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=on";
};
systemd.user.targets.sway-session = {
Unit = {
Description = "sway compositor session";
@ -268,22 +259,6 @@ lib.mkIf nixosConfig.sbruder.gui.enable {
};
};
# Start on tty1
programs.zsh.initExtra = ''
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
export XDG_SESSION_TYPE="wayland" # otherwise set to tty
unset __HM_SESS_VARS_SOURCED __NIXOS_SET_ENVIRONMENT_DONE # otherwise sessionVariables are not updated
exec systemd-cat -t sway sway
fi
'';
home.packages = with pkgs; [
alacritty # terminal
brightnessctl # control screen brightness
sway-contrib.grimshot # screenshots
wdisplays # graphical output manager
];
xdg.configFile."swaynag/config".text =
let
# adding it to the header doesnt work since the defaults overwrite it
@ -307,334 +282,32 @@ lib.mkIf nixosConfig.sbruder.gui.enable {
${commonConfig}
'';
# home-managers waybar module performs additional checks that are overly strict
xdg.configFile."waybar/config".text =
let
watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" ''
${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \
| ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \
| ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end'
'';
# Start on tty1
programs.zsh.initExtra = ''
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
export XDG_SESSION_TYPE="wayland" # otherwise set to tty
unset __HM_SESS_VARS_SOURCED __NIXOS_SET_ENVIRONMENT_DONE # otherwise sessionVariables are not updated
exec systemd-cat -t sway sway
fi
'';
toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" ''
if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then
${pkgs.systemd}/bin/systemctl --user stop ${unit}
else
${pkgs.systemd}/bin/systemctl --user start ${unit}
fi
'';
# nerd fonts are abusing arabic which breaks latin text
# context: https://github.com/Alexays/Waybar/issues/628
lrm = "‎";
# for fine-grained control over spacing
thinsp = " ";
in
lib.generators.toJSON { } {
layer = "top";
position = "top";
height = 24;
modules-center = [ ];
modules-left = [
"sway/workspaces"
"sway/mode"
];
modules-right = [
"tray"
"custom/screencast"
"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" = {
exec = watchUserUnitState
"gammastep"
{ class = "active"; }
{ class = "inactive"; };
on-click = toggleUserUnitState "gammastep";
return-type = "json";
format = "";
tooltip = false;
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = " ";
deactivated = " ";
};
};
"custom/screencast" = {
exec = pkgs.writeScript "screencast-monitor" ''
#!${pkgs.python3}/bin/python3
import subprocess
import sys
active_outputs = 0
with subprocess.Popen(
["${pkgs.coreutils}/bin/stdbuf", "-o0", "${nixosConfig.services.pipewire.package}/bin/pw-link", "-m", "-o", "xdg-desktop-portal-wlr"],
stdout=subprocess.PIPE,
text=True,
) as proc:
for line in proc.stdout:
action = line.split(" ")[0]
if action == "=" or action == "+":
active_outputs += 1
elif action == "-":
active_outputs -= 1
else:
print(f"Invalid action {action} (in line {line})", file=sys.stderr)
if active_outputs > 0:
print("${lrm} ")
else:
print()
sys.stdout.flush()
'';
format = "{}";
tooltip = false;
};
backlight = {
format = "{percent}% {icon}";
format-icons = [ " " " " " " " " " " " " " " ];
on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -q set +5%";
on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -q set 5%-";
};
mpd = {
server = config.services.mpd.network.listenAddress;
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 -q -h ${config.services.mpd.network.listenAddress} volume +2";
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} 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 = "${lrm}${lrm} {icon} {format_source}";
format-muted = "${lrm}${lrm} {format_source}";
format-source = "{volume}% ${thinsp}";
format-source-muted = "${thinsp}";
format-icons = {
car = " ";
default = [ "" "奔" "" ];
hands-free = " ";
headphone = " ";
headset = " ";
phone = " ";
portable = " ";
};
on-click-right = "${pkgs.pavucontrol}/bin/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 = "${config.programs.alacritty.package}/bin/alacritty -e ${pkgs.networkmanager}/bin/nmtui";
};
"custom/vpn" = {
interval = 10;
exec = pkgs.writeShellScript "vpn-state" ''
${pkgs.iproute}/bin/ip -j link \
| ${pkgs.jq}/bin/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>";
};
};
xdg.configFile."waybar/style.css".source = pkgs.substituteAll ({
src = ../files/waybar/style.css;
} // solarized);
systemd.user.services.waybar = {
Unit = {
Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
Documentation = "https://github.com/Alexays/Waybar/wiki/";
PartOf = [ "sway-session.target" ];
};
Install.WantedBy = [ "sway-session.target" ];
Service = {
# ensure sway is already started, otherwise workspaces will not work
ExecStartPre = "${config.wayland.windowManager.sway.package}/bin/swaymsg";
ExecStart = "${pkgs.waybar}/bin/waybar";
ExecReload = "${pkgs.utillinux}/bin/kill -SIGUSR2 $MAINPID";
Restart = "on-failure";
RestartSec = "1s";
};
home.sessionVariables = {
CLUTTER_BACKEND = "wayland";
GDK_BACKEND = "wayland";
GDK_DPI_SCALE = 1;
MOZ_ENABLE_WAYLAND = 1;
QT_QPA_PLATFORM = "wayland-egl";
QT_WAYLAND_DISABLE_WINDOWDECORATION = 1;
SDL_VIDEODRIVER = "wayland";
WLR_NO_HARDWARE_CURSORS = 1;
_JAVA_AWT_WM_NONREPARENTING = 1;
_JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=on";
};
programs.mako = {
enable = true;
backgroundColor = solarized.base03;
borderColor = solarized.base02;
textColor = solarized.base0;
progressColor = "over ${solarized.base02}";
groupBy = "app-name";
defaultTimeout = 5000;
extraConfig = ''
[urgency=critical]
text-color=#dc322f
ignore-timeout=true
default-timeout=0
'';
};
systemd.user.services.mako = {
Unit.PartOf = [ "sway-session.target" ];
Install.WantedBy = [ "sway-session.target" ];
Service = {
ExecStart = "${pkgs.mako}/bin/mako";
Restart = "on-failure";
};
};
services.kanshi = {
enable = true;
profiles =
let
getMachineConfig = machine: machines:
if lib.hasAttr machine machines
then lib.getAttr machine machines
else { };
in
getMachineConfig
(nixosConfig.networking.hostName)
{
nunotaba = {
standalone.outputs = lib.singleton {
criteria = "eDP-1";
mode = "1920x1080";
position = "0,0";
};
home.outputs = [
{
criteria = "eDP-1";
mode = "1920x1080";
position = "0,424";
}
{
criteria = "Dell Inc. DELL U2410 F525M0A104NL";
mode = "1920x1200";
position = "1920,0";
}
];
};
};
};
services.gammastep = {
enable = true;
latitude = "49.52";
longitude = "10.17";
temperature = {
day = 6500;
night = 3500;
};
};
# screen recording/sharing with pipewire
xdg.configFile."xdg-desktop-portal-wlr/config".text = lib.generators.toINI { } {
screencast = {
max_fps = 30;
chooser_type = "simple";
chooser_cmd = "slurp -f %o -or";
};
};
}
home.packages = with pkgs; [
alacritty # terminal
brightnessctl # control screen brightness
sway-contrib.grimshot # screenshots
wdisplays # graphical output manager
];
})

View file

@ -0,0 +1,11 @@
{
services.gammastep = {
enable = true;
latitude = "49.52";
longitude = "10.17";
temperature = {
day = 6500;
night = 3500;
};
};
}

View file

@ -0,0 +1,35 @@
{ lib, nixosConfig, ... }:
let
getMachineConfig = machine:
if lib.hasAttr machine machineConfigs
then lib.getAttr machine machineConfigs
else { };
machineConfigs = {
nunotaba = {
standalone.outputs = lib.singleton {
criteria = "eDP-1";
mode = "1920x1080";
position = "0,0";
};
home.outputs = [
{
criteria = "eDP-1";
mode = "1920x1080";
position = "0,424";
}
{
criteria = "Dell Inc. DELL U2410 F525M0A104NL";
mode = "1920x1200";
position = "1920,0";
}
];
};
};
in
{
services.kanshi = {
enable = true;
profiles = getMachineConfig (nixosConfig.networking.hostName);
};
}

View file

@ -0,0 +1,35 @@
{ pkgs, ... }:
let
inherit ((import ../common.nix).colorschemes) solarized;
in
{
programs.mako = {
enable = true;
backgroundColor = solarized.base03;
borderColor = solarized.base02;
textColor = solarized.base0;
progressColor = "over ${solarized.base02}";
groupBy = "app-name";
defaultTimeout = 5000;
extraConfig = ''
[urgency=critical]
text-color=#dc322f
ignore-timeout=true
default-timeout=0
'';
};
systemd.user.services.mako = {
Unit.PartOf = [ "sway-session.target" ];
Install.WantedBy = [ "sway-session.target" ];
Service = {
ExecStart = "${pkgs.mako}/bin/mako";
Restart = "on-failure";
};
};
}

View file

@ -0,0 +1,249 @@
{ config, lib, nixosConfig, pkgs, ... }:
let
watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" ''
${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \
| ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \
| ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end'
'';
toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" ''
if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then
${pkgs.systemd}/bin/systemctl --user stop ${unit}
else
${pkgs.systemd}/bin/systemctl --user start ${unit}
fi
'';
# nerd fonts are abusing arabic which breaks latin text
# context: https://github.com/Alexays/Waybar/issues/628
lrm = "&#8206;";
# for fine-grained control over spacing
thinsp = "&#8201;";
in
{
# home-managers waybar module performs additional checks that are overly strict
xdg.configFile."waybar/config".text = lib.generators.toJSON { } {
layer = "top";
position = "top";
height = 24;
modules-center = [ ];
modules-left = [
"sway/workspaces"
"sway/mode"
];
modules-right = [
"tray"
"custom/screencast"
"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" = {
exec = watchUserUnitState
"gammastep"
{ class = "active"; }
{ class = "inactive"; };
on-click = toggleUserUnitState "gammastep";
return-type = "json";
format = "";
tooltip = false;
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = " ";
deactivated = " ";
};
};
"custom/screencast" = {
exec = pkgs.writeScript "screencast-monitor" ''
#!${pkgs.python3}/bin/python3
import subprocess
import sys
active_outputs = 0
with subprocess.Popen(
["${pkgs.coreutils}/bin/stdbuf", "-o0", "${nixosConfig.services.pipewire.package}/bin/pw-link", "-m", "-o", "xdg-desktop-portal-wlr"],
stdout=subprocess.PIPE,
text=True,
) as proc:
for line in proc.stdout:
action = line.split(" ")[0]
if action == "=" or action == "+":
active_outputs += 1
elif action == "-":
active_outputs -= 1
else:
print(f"Invalid action {action} (in line {line})", file=sys.stderr)
if active_outputs > 0:
print("${lrm} ")
else:
print()
sys.stdout.flush()
'';
format = "{}";
tooltip = false;
};
backlight = {
format = "{percent}% {icon}";
format-icons = [ " " " " " " " " " " " " " " ];
on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -q set +5%";
on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -q set 5%-";
};
mpd = {
server = config.services.mpd.network.listenAddress;
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 -q -h ${config.services.mpd.network.listenAddress} volume +2";
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} 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 = "${lrm}${lrm} {icon} {format_source}";
format-muted = "${lrm}${lrm} {format_source}";
format-source = "{volume}% ${thinsp}";
format-source-muted = "${thinsp}";
format-icons = {
car = " ";
default = [ "" "奔" "" ];
hands-free = " ";
headphone = " ";
headset = " ";
phone = " ";
portable = " ";
};
on-click-right = "${pkgs.pavucontrol}/bin/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 = "${config.programs.alacritty.package}/bin/alacritty -e ${pkgs.networkmanager}/bin/nmtui";
};
"custom/vpn" = {
interval = 10;
exec = pkgs.writeShellScript "vpn-state" ''
${pkgs.iproute}/bin/ip -j link \
| ${pkgs.jq}/bin/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>";
};
};
xdg.configFile."waybar/style.css".source = pkgs.substituteAll ({
src = ./waybar.css;
} // (import ../common.nix).colorschemes.solarized);
systemd.user.services.waybar = {
Unit = {
Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
Documentation = "https://github.com/Alexays/Waybar/wiki/";
PartOf = [ "sway-session.target" ];
};
Install.WantedBy = [ "sway-session.target" ];
Service = {
# ensure sway is already started, otherwise workspaces will not work
ExecStartPre = "${config.wayland.windowManager.sway.package}/bin/swaymsg";
ExecStart = "${pkgs.waybar}/bin/waybar";
ExecReload = "${pkgs.utillinux}/bin/kill -SIGUSR2 $MAINPID";
Restart = "on-failure";
RestartSec = "1s";
};
};
}

View file

@ -0,0 +1,13 @@
{ lib, ... }:
{
# screen recording/sharing with pipewire
# portal is installed in system configuration
xdg.configFile."xdg-desktop-portal-wlr/config".text = lib.generators.toINI { } {
screencast = {
max_fps = 30;
chooser_type = "simple";
chooser_cmd = "slurp -f %o -or";
};
};
}