Created i3blocks configuration with modules matching waybar setup including disk, CPU, memory, pulseaudio, backlight, network, battery, and clock. Applied matching color scheme and workspace button styling. i3blocks works with i3wm unlike waybar which only supports sway. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
442 lines
14 KiB
Nix
442 lines
14 KiB
Nix
{ config, lib, pkgs, ... }:
|
||
|
||
with lib;
|
||
|
||
let
|
||
cfg = config.home.i3_sway;
|
||
|
||
shared_config = recursiveUpdate rec {
|
||
modifier = "Mod4";
|
||
terminal = "ghostty";
|
||
defaultWorkspace = "workspace number 1";
|
||
|
||
keybindings = {
|
||
"${shared_config.modifier}+Return" = "exec ${terminal}";
|
||
"${shared_config.modifier}+Shift+q" = "kill";
|
||
|
||
"${shared_config.modifier}+h" = "focus left";
|
||
"${shared_config.modifier}+j" = "focus down";
|
||
"${shared_config.modifier}+k" = "focus up";
|
||
"${shared_config.modifier}+l" = "focus right";
|
||
|
||
"${shared_config.modifier}+Shift+h" = "move left";
|
||
"${shared_config.modifier}+Shift+j" = "move down";
|
||
"${shared_config.modifier}+Shift+k" = "move up";
|
||
"${shared_config.modifier}+Shift+l" = "move right";
|
||
|
||
"${shared_config.modifier}+Left" = "focus left";
|
||
"${shared_config.modifier}+Down" = "focus down";
|
||
"${shared_config.modifier}+Up" = "focus up";
|
||
"${shared_config.modifier}+Right" = "focus right";
|
||
|
||
"${shared_config.modifier}+Shift+Left" = "move left";
|
||
"${shared_config.modifier}+Shift+Down" = "move down";
|
||
"${shared_config.modifier}+Shift+Up" = "move up";
|
||
"${shared_config.modifier}+Shift+Right" = "move right";
|
||
|
||
#"${shared_config.modifier}+h" = "split h";
|
||
"${shared_config.modifier}+v" = "split v";
|
||
"${shared_config.modifier}+Shift+f" = "fullscreen toggle";
|
||
|
||
"${shared_config.modifier}+s" = "layout stacking";
|
||
"${shared_config.modifier}+w" = "layout tabbed";
|
||
"${shared_config.modifier}+e" = "layout toggle split";
|
||
|
||
"${shared_config.modifier}+Shift+space" = "floating toggle";
|
||
"${shared_config.modifier}+space" = "focus mode_toggle";
|
||
|
||
"${shared_config.modifier}+a" = "focus parent";
|
||
|
||
"${shared_config.modifier}+Shift+minus" = "move scratchpad";
|
||
"${shared_config.modifier}+minus" = "scratchpad show";
|
||
|
||
"${shared_config.modifier}+1" = "workspace number 1";
|
||
"${shared_config.modifier}+2" = "workspace number 2";
|
||
"${shared_config.modifier}+3" = "workspace number 3";
|
||
"${shared_config.modifier}+4" = "workspace number 4";
|
||
"${shared_config.modifier}+5" = "workspace number 5";
|
||
"${shared_config.modifier}+6" = "workspace number 6";
|
||
"${shared_config.modifier}+7" = "workspace number 7";
|
||
"${shared_config.modifier}+8" = "workspace number 8";
|
||
"${shared_config.modifier}+9" = "workspace number 9";
|
||
"${shared_config.modifier}+0" = "workspace number 10";
|
||
|
||
"${shared_config.modifier}+Shift+1" =
|
||
"move container to workspace number 1";
|
||
"${shared_config.modifier}+Shift+2" =
|
||
"move container to workspace number 2";
|
||
"${shared_config.modifier}+Shift+3" =
|
||
"move container to workspace number 3";
|
||
"${shared_config.modifier}+Shift+4" =
|
||
"move container to workspace number 4";
|
||
"${shared_config.modifier}+Shift+5" =
|
||
"move container to workspace number 5";
|
||
"${shared_config.modifier}+Shift+6" =
|
||
"move container to workspace number 6";
|
||
"${shared_config.modifier}+Shift+7" =
|
||
"move container to workspace number 7";
|
||
"${shared_config.modifier}+Shift+8" =
|
||
"move container to workspace number 8";
|
||
"${shared_config.modifier}+Shift+9" =
|
||
"move container to workspace number 9";
|
||
"${shared_config.modifier}+Shift+0" =
|
||
"move container to workspace number 10";
|
||
|
||
"${shared_config.modifier}+Shift+c" = "reload";
|
||
"${shared_config.modifier}+Shift+r" = "restart";
|
||
|
||
"${shared_config.modifier}+r" = "mode resize";
|
||
|
||
"XF86MonBrightnessUp" = "exec brightnessctl s +5%";
|
||
"XF86MonBrightnessDown" = "exec brightnessctl s 5%-";
|
||
};
|
||
} cfg.extraSharedConfig;
|
||
in {
|
||
options.home.i3_sway = {
|
||
extraSharedConfig = mkOption {
|
||
default = {};
|
||
};
|
||
extraI3Config = mkOption {
|
||
default = {};
|
||
};
|
||
extraSwayConfig = mkOption {
|
||
default = {};
|
||
};
|
||
};
|
||
|
||
config = {
|
||
# i3blocks configuration file
|
||
home.file.".config/i3blocks/config".text = ''
|
||
# i3blocks config - replicating waybar setup
|
||
separator_block_width=15
|
||
markup=pango
|
||
|
||
[disk]
|
||
command=df -h / | awk 'NR==2 {print "💾 " $5}'
|
||
interval=30
|
||
separator=true
|
||
|
||
[cpu]
|
||
command=top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print "🧠 " int(100 - $1) "%"}'
|
||
interval=2
|
||
separator=true
|
||
|
||
[memory]
|
||
command=free | awk 'NR==2 {printf "🐏 %.0f%%\n", $3*100/$2}'
|
||
interval=5
|
||
separator=true
|
||
|
||
[pulseaudio]
|
||
command=${pkgs.writeShellScript "i3blocks-pulseaudio" ''
|
||
volume=$(pactl get-sink-volume @DEFAULT_SINK@ | grep -Po '\d+%' | head -1)
|
||
muted=$(pactl get-sink-mute @DEFAULT_SINK@ | grep -o 'yes')
|
||
if [ "$muted" = "yes" ]; then
|
||
echo "🔇"
|
||
else
|
||
vol_num=''${volume%\%}
|
||
if [ $vol_num -le 33 ]; then
|
||
echo "🔈 $volume"
|
||
elif [ $vol_num -le 66 ]; then
|
||
echo "🔉 $volume"
|
||
else
|
||
echo "🔊 $volume"
|
||
fi
|
||
fi
|
||
''}
|
||
interval=1
|
||
signal=10
|
||
separator=true
|
||
|
||
[backlight]
|
||
command=${pkgs.writeShellScript "i3blocks-backlight" ''
|
||
if command -v brightnessctl &>/dev/null; then
|
||
brightnessctl g | awk -v max=$(brightnessctl m) '{printf "☀️ %.0f%%\n", ($1/max)*100}'
|
||
fi
|
||
''}
|
||
interval=1
|
||
separator=true
|
||
|
||
[network]
|
||
command=${pkgs.writeShellScript "i3blocks-network" ''
|
||
if iwgetid -r &>/dev/null; then
|
||
ssid=$(iwgetid -r)
|
||
signal=$(grep "^\s*w" /proc/net/wireless | awk '{print int($3 * 100 / 70)}')
|
||
echo "📶 $ssid ($signal%)"
|
||
else
|
||
ip=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||
if [ -n "$ip" ]; then
|
||
echo "🔌 $ip"
|
||
else
|
||
echo "❌"
|
||
fi
|
||
fi
|
||
''}
|
||
interval=5
|
||
separator=true
|
||
|
||
[battery]
|
||
command=${pkgs.writeShellScript "i3blocks-battery" ''
|
||
if [ -d /sys/class/power_supply/BAT0 ]; then
|
||
capacity=$(cat /sys/class/power_supply/BAT0/capacity)
|
||
status=$(cat /sys/class/power_supply/BAT0/status)
|
||
|
||
if [ "$status" = "Charging" ]; then
|
||
echo "⚡ $capacity%"
|
||
else
|
||
echo "🔋 $capacity%"
|
||
fi
|
||
fi
|
||
''}
|
||
interval=10
|
||
separator=true
|
||
|
||
[time]
|
||
command=date '+%Y-%m-%d %H:%M'
|
||
interval=1
|
||
separator=false
|
||
'';
|
||
|
||
xsession.windowManager.i3 = let
|
||
base_i3_config = recursiveUpdate shared_config {
|
||
bars = [{
|
||
position = "bottom";
|
||
statusCommand = "${pkgs.i3blocks}/bin/i3blocks";
|
||
trayOutput = "primary"; # Enable system tray on primary output
|
||
fonts = {
|
||
names = [ "Fira Code" "monospace" ];
|
||
size = 11.0;
|
||
};
|
||
colors = {
|
||
background = "#000000";
|
||
statusline = "#ffffff";
|
||
separator = "#666666";
|
||
|
||
# Workspace button colors (matching waybar)
|
||
focusedWorkspace = {
|
||
border = "#285577";
|
||
background = "#285577";
|
||
text = "#ffffff";
|
||
};
|
||
activeWorkspace = {
|
||
border = "#5f676a";
|
||
background = "#5f676a";
|
||
text = "#ffffff";
|
||
};
|
||
inactiveWorkspace = {
|
||
border = "#222222";
|
||
background = "#222222";
|
||
text = "#888888";
|
||
};
|
||
urgentWorkspace = {
|
||
border = "#900000";
|
||
background = "#900000";
|
||
text = "#ffffff";
|
||
};
|
||
};
|
||
}];
|
||
keybindings = shared_config.keybindings // {
|
||
"${shared_config.modifier}+d" = "exec rofi -show drun";
|
||
"${shared_config.modifier}+Shift+e" =
|
||
"exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit'";
|
||
};
|
||
startup = [
|
||
# GNOME polkit authentication agent
|
||
{
|
||
command = "/run/current-system/sw/libexec/polkit-gnome-authentication-agent-1";
|
||
always = false;
|
||
notification = false;
|
||
}
|
||
# Picom compositor for smooth rendering and no tearing (important for Nvidia)
|
||
{
|
||
command = "picom --backend glx -b";
|
||
always = false;
|
||
notification = false;
|
||
}
|
||
# NetworkManager system tray applet
|
||
{
|
||
command = "nm-applet";
|
||
always = false;
|
||
notification = false;
|
||
}
|
||
# Set wallpaper with feh
|
||
{
|
||
command = "feh --bg-scale ${../../wallpapers/metroid-samus-returns-kz-3440x1440.jpg}";
|
||
always = false;
|
||
notification = false;
|
||
}
|
||
];
|
||
};
|
||
in {
|
||
enable = true;
|
||
config = recursiveUpdate base_i3_config cfg.extraI3Config;
|
||
};
|
||
|
||
wayland.windowManager.sway = let
|
||
base_sway_config = recursiveUpdate shared_config {
|
||
bars = []; # Disable default bar, use waybar instead
|
||
keybindings = shared_config.keybindings // {
|
||
"${shared_config.modifier}+d" = "exec wofi --show drun";
|
||
"${shared_config.modifier}+Shift+e" =
|
||
"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'";
|
||
};
|
||
input = {
|
||
"type:keyboard" = {
|
||
xkb_options = "caps:escape";
|
||
};
|
||
"type:touchpad" = {
|
||
tap = "enabled";
|
||
tap_button_map = "lrm";
|
||
drag = "enabled";
|
||
natural_scroll = "disabled";
|
||
dwt = "enabled";
|
||
};
|
||
};
|
||
output = {
|
||
"*" = {
|
||
bg = "${../../wallpapers/metroid-samus-returns-kz-3440x1440.jpg} fill";
|
||
};
|
||
};
|
||
};
|
||
in {
|
||
enable = true;
|
||
config = recursiveUpdate base_sway_config cfg.extraSwayConfig;
|
||
};
|
||
|
||
programs.waybar = {
|
||
enable = true;
|
||
systemd.enable = true;
|
||
settings = {
|
||
mainBar = {
|
||
layer = "top";
|
||
position = "bottom";
|
||
height = 30;
|
||
spacing = 4;
|
||
|
||
modules-left = [ "sway/workspaces" "sway/mode" ];
|
||
modules-center = [ ];
|
||
modules-right = [ "disk" "cpu" "memory" "pulseaudio" "backlight" "network" "battery" "tray" "clock" ];
|
||
|
||
"sway/workspaces" = {
|
||
disable-scroll = true;
|
||
all-outputs = true;
|
||
};
|
||
|
||
"clock" = {
|
||
format = "{:%Y-%m-%d %H:%M}";
|
||
tooltip-format = "<tt><small>{calendar}</small></tt>";
|
||
calendar = {
|
||
mode = "year";
|
||
mode-mon-col = 3;
|
||
weeks-pos = "right";
|
||
on-scroll = 1;
|
||
format = {
|
||
months = "<span color='#ffead3'><b>{}</b></span>";
|
||
days = "<span color='#ecc6d9'><b>{}</b></span>";
|
||
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
|
||
weekdays = "<span color='#ffcc66'><b>{}</b></span>";
|
||
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
||
};
|
||
};
|
||
};
|
||
|
||
"disk" = {
|
||
interval = 30;
|
||
format = "💾 {percentage_used}%";
|
||
path = "/";
|
||
tooltip-format = "Used: {used} / {total} ({percentage_used}%)\nFree: {free} ({percentage_free}%)";
|
||
};
|
||
|
||
"cpu" = {
|
||
format = "🧠 {usage}%";
|
||
tooltip = false;
|
||
};
|
||
|
||
"memory" = {
|
||
format = "🐏 {percentage}%";
|
||
tooltip-format = "RAM: {used:0.1f}G / {total:0.1f}G";
|
||
};
|
||
|
||
"pulseaudio" = {
|
||
format = "{icon} {volume}%";
|
||
format-muted = "🔇";
|
||
format-icons = {
|
||
headphone = "🎧";
|
||
default = [ "🔈" "🔉" "🔊" ];
|
||
};
|
||
on-click = "pavucontrol";
|
||
};
|
||
|
||
"backlight" = {
|
||
format = "☀️ {percent}%";
|
||
tooltip = false;
|
||
};
|
||
|
||
"network" = {
|
||
format-wifi = "📶 {essid} ({signalStrength}%)";
|
||
format-ethernet = "🔌 {ipaddr}";
|
||
format-disconnected = "❌";
|
||
tooltip-format = "{ifname}: {ipaddr}/{cidr}";
|
||
};
|
||
|
||
"battery" = {
|
||
states = {
|
||
warning = 30;
|
||
critical = 15;
|
||
};
|
||
format = "{icon} {capacity}%";
|
||
format-charging = "⚡ {capacity}%";
|
||
format-icons = [ "🪫" "🔋" "🔋" "🔋" "🔋" ];
|
||
};
|
||
|
||
"tray" = {
|
||
spacing = 10;
|
||
};
|
||
};
|
||
};
|
||
style = ''
|
||
* {
|
||
padding: 0 4px;
|
||
font-family: "Fira Code", monospace;
|
||
font-size: 13px;
|
||
}
|
||
|
||
#workspaces button {
|
||
padding: 0 8px;
|
||
background-color: transparent;
|
||
color: #ffffff;
|
||
border: none;
|
||
}
|
||
|
||
#workspaces button.focused {
|
||
background-color: #285577;
|
||
font-weight: bold;
|
||
}
|
||
|
||
#workspaces button.visible {
|
||
background-color: #5f676a;
|
||
}
|
||
|
||
#workspaces button.urgent {
|
||
background-color: #900000;
|
||
}
|
||
'';
|
||
};
|
||
|
||
programs.rofi = {
|
||
enable = true;
|
||
theme = "solarized";
|
||
extraConfig = {
|
||
modi = "drun,run,window";
|
||
show-icons = true;
|
||
drun-display-format = "{name}";
|
||
disable-history = false;
|
||
hide-scrollbar = true;
|
||
display-drun = " Apps";
|
||
display-run = " Run";
|
||
display-window = " Windows";
|
||
sidebar-mode = true;
|
||
};
|
||
};
|
||
};
|
||
}
|