sway: Reorganise and split into multiple files
This commit is contained in:
parent
f3d958c1a9
commit
00a919d6d7
|
@ -14,7 +14,7 @@
|
||||||
./pass.nix
|
./pass.nix
|
||||||
./programs.nix
|
./programs.nix
|
||||||
./scripts
|
./scripts
|
||||||
./sway.nix
|
./sway
|
||||||
./tmate.nix
|
./tmate.nix
|
||||||
./tmux.nix
|
./tmux.nix
|
||||||
./vdirsyncer.nix
|
./vdirsyncer.nix
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
{ config, lib, nixosConfig, pkgs, ... }:
|
{ config, lib, nixosConfig, pkgs, ... }:
|
||||||
let
|
let
|
||||||
common = import ./common.nix;
|
|
||||||
solarized = common.colorschemes.solarized;
|
|
||||||
|
|
||||||
# Source: “境目” by 3211 on Pixiv: https://www.pixiv.net/en/artworks/39266182
|
# Source: “境目” by 3211 on Pixiv: https://www.pixiv.net/en/artworks/39266182
|
||||||
wallpaperUnfree = pkgs.fetchurl {
|
wallpaperUnfree = pkgs.fetchurl {
|
||||||
name = "wallpaper-unfree";
|
name = "wallpaper-unfree";
|
||||||
|
@ -22,10 +19,17 @@ let
|
||||||
wallpaper = if nixosConfig.sbruder.unfree.allowAssets then wallpaperUnfree else wallpaperFree;
|
wallpaper = if nixosConfig.sbruder.unfree.allowAssets then wallpaperUnfree else wallpaperFree;
|
||||||
|
|
||||||
cfg = config.wayland.windowManager.sway.config;
|
cfg = config.wayland.windowManager.sway.config;
|
||||||
|
|
||||||
makoInhibitStateFile = "${config.xdg.dataHome}/mako/inhibit-state";
|
|
||||||
in
|
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 = {
|
wayland.windowManager.sway = {
|
||||||
enable = true;
|
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 = {
|
systemd.user.targets.sway-session = {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "sway compositor session";
|
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 =
|
xdg.configFile."swaynag/config".text =
|
||||||
let
|
let
|
||||||
# adding it to the header doesn’t work since the defaults overwrite it
|
# adding it to the header doesn’t work since the defaults overwrite it
|
||||||
|
@ -307,334 +282,32 @@ lib.mkIf nixosConfig.sbruder.gui.enable {
|
||||||
${commonConfig}
|
${commonConfig}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# home-manager’s waybar module performs additional checks that are overly strict
|
# Start on tty1
|
||||||
xdg.configFile."waybar/config".text =
|
programs.zsh.initExtra = ''
|
||||||
let
|
if [[ -z $WAYLAND_DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
|
||||||
watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" ''
|
export XDG_SESSION_TYPE="wayland" # otherwise set to tty
|
||||||
${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \
|
unset __HM_SESS_VARS_SOURCED __NIXOS_SET_ENVIRONMENT_DONE # otherwise sessionVariables are not updated
|
||||||
| ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \
|
exec systemd-cat -t sway sway
|
||||||
| ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end'
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" ''
|
home.sessionVariables = {
|
||||||
if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then
|
CLUTTER_BACKEND = "wayland";
|
||||||
${pkgs.systemd}/bin/systemctl --user stop ${unit}
|
GDK_BACKEND = "wayland";
|
||||||
else
|
GDK_DPI_SCALE = 1;
|
||||||
${pkgs.systemd}/bin/systemctl --user start ${unit}
|
MOZ_ENABLE_WAYLAND = 1;
|
||||||
fi
|
QT_QPA_PLATFORM = "wayland-egl";
|
||||||
'';
|
QT_WAYLAND_DISABLE_WINDOWDECORATION = 1;
|
||||||
|
SDL_VIDEODRIVER = "wayland";
|
||||||
# nerd fonts are abusing arabic which breaks latin text
|
WLR_NO_HARDWARE_CURSORS = 1;
|
||||||
# context: https://github.com/Alexays/Waybar/issues/628
|
_JAVA_AWT_WM_NONREPARENTING = 1;
|
||||||
lrm = "‎";
|
_JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=on";
|
||||||
|
|
||||||
# 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";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.mako = {
|
home.packages = with pkgs; [
|
||||||
enable = true;
|
alacritty # terminal
|
||||||
|
brightnessctl # control screen brightness
|
||||||
backgroundColor = solarized.base03;
|
sway-contrib.grimshot # screenshots
|
||||||
borderColor = solarized.base02;
|
wdisplays # graphical output manager
|
||||||
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";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
11
users/simon/modules/sway/gammastep.nix
Normal file
11
users/simon/modules/sway/gammastep.nix
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
services.gammastep = {
|
||||||
|
enable = true;
|
||||||
|
latitude = "49.52";
|
||||||
|
longitude = "10.17";
|
||||||
|
temperature = {
|
||||||
|
day = 6500;
|
||||||
|
night = 3500;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
35
users/simon/modules/sway/kanshi.nix
Normal file
35
users/simon/modules/sway/kanshi.nix
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
35
users/simon/modules/sway/mako.nix
Normal file
35
users/simon/modules/sway/mako.nix
Normal 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
249
users/simon/modules/sway/waybar.nix
Normal file
249
users/simon/modules/sway/waybar.nix
Normal 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 = "‎";
|
||||||
|
|
||||||
|
# for fine-grained control over spacing
|
||||||
|
thinsp = " ";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# home-manager’s 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
13
users/simon/modules/sway/xdg-desktop-portal.nix
Normal file
13
users/simon/modules/sway/xdg-desktop-portal.nix
Normal 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue