Add SketchyBar integration to aerospace with bottom bar positioning
Integrate SketchyBar status bar with aerospace window manager, providing a native macOS status bar replacement with workspace indicators and system monitoring. Key features: - Add sketchybar.enable option to aerospace module - Install sketchybar package and fonts conditionally - Create main sketchybarrc with i3/sway color theme - Position bar at bottom with 40px bottom gap - Implement workspace indicators with dynamic visibility: - Hide empty workspaces - Show focused workspace with blue highlight - Show non-empty workspaces with inactive styling - Use centered icons with fixed 32px width - Add system monitoring plugins: CPU, memory, disk, battery, volume, clock - Integrate menu bar extras (Bluetooth, WiFi) as aliases - Configure aerospace to trigger workspace change events - Hide native macOS menu bar when SketchyBar enabled - Set up launchd agent for auto-start - Use SF Mono Regular 13.0 font matching waybar aesthetic
This commit is contained in:
@@ -61,6 +61,14 @@ in
|
||||
description = "Delay before focusing window";
|
||||
};
|
||||
};
|
||||
|
||||
sketchybar = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable SketchyBar status bar";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
@@ -72,9 +80,19 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
# Install aerospace package and autoraise if enabled
|
||||
# Hide macOS menu bar when SketchyBar is enabled
|
||||
# Note: Requires logout/login to take effect
|
||||
targets.darwin.defaults = mkIf cfg.sketchybar.enable {
|
||||
NSGlobalDomain = {
|
||||
_HIHideMenuBar = true;
|
||||
AppleMenuBarVisibleInFullscreen = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Install aerospace package and optional tools if enabled
|
||||
home.packages = [ pkgs.aerospace ]
|
||||
++ optionals cfg.autoraise.enable [ pkgs.autoraise ];
|
||||
++ optionals cfg.autoraise.enable [ pkgs.autoraise ]
|
||||
++ optionals cfg.sketchybar.enable [ pkgs.sketchybar pkgs.sketchybar-app-font ];
|
||||
|
||||
# Enable and configure aerospace
|
||||
programs.aerospace.enable = true;
|
||||
@@ -185,7 +203,24 @@ in
|
||||
esc = "mode main";
|
||||
"${cfg.leader}-p" = "mode main";
|
||||
};
|
||||
|
||||
# SketchyBar integration - notify bar of workspace changes
|
||||
exec-on-workspace-change = mkIf cfg.sketchybar.enable [
|
||||
"/bin/bash" "-c"
|
||||
"${pkgs.sketchybar}/bin/sketchybar --trigger aerospace_workspace_change FOCUSED=$AEROSPACE_FOCUSED_WORKSPACE PREV=$AEROSPACE_PREV_WORKSPACE"
|
||||
];
|
||||
}
|
||||
# Gaps configuration - prevent windows from overlapping SketchyBar
|
||||
(mkIf cfg.sketchybar.enable {
|
||||
gaps = {
|
||||
outer = {
|
||||
top = 0;
|
||||
bottom = 40;
|
||||
left = 0;
|
||||
right = 0;
|
||||
};
|
||||
};
|
||||
})
|
||||
cfg.userSettings
|
||||
];
|
||||
|
||||
@@ -215,5 +250,396 @@ in
|
||||
KeepAlive = true;
|
||||
};
|
||||
};
|
||||
|
||||
# SketchyBar configuration
|
||||
home.file.".config/sketchybar/sketchybarrc" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
onChange = "${pkgs.sketchybar}/bin/sketchybar --reload";
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
# Plugin directory
|
||||
PLUGIN_DIR="$HOME/.config/sketchybar/plugins"
|
||||
|
||||
# Colors - i3/sway theme with exact color matching
|
||||
# Focused window/workspace color from i3/sway
|
||||
FOCUSED=0xff285577
|
||||
|
||||
# Background colors matching i3blocks bar
|
||||
BAR_BG=0xcc000000 # Semi-transparent black
|
||||
ITEM_BG=0xff333333 # Dark gray for inactive items
|
||||
|
||||
# Text colors
|
||||
TEXT=0xffffffff # White text
|
||||
GRAY=0xff888888 # Muted text for inactive items
|
||||
|
||||
# Accent colors for warnings
|
||||
WARNING=0xffff9900
|
||||
CRITICAL=0xff900000
|
||||
|
||||
# Configure the bar appearance
|
||||
${pkgs.sketchybar}/bin/sketchybar --bar \
|
||||
position=bottom \
|
||||
height=32 \
|
||||
color=$BAR_BG \
|
||||
border_width=0 \
|
||||
corner_radius=0 \
|
||||
padding_left=10 \
|
||||
padding_right=10
|
||||
|
||||
# Set default properties for all items
|
||||
# Using monospace font to match waybar's Fira Code styling
|
||||
${pkgs.sketchybar}/bin/sketchybar --default \
|
||||
updates=when_shown \
|
||||
icon.font="SF Mono:Regular:13.0" \
|
||||
icon.color=$TEXT \
|
||||
icon.padding_left=4 \
|
||||
icon.padding_right=4 \
|
||||
label.font="SF Mono:Regular:13.0" \
|
||||
label.color=$TEXT \
|
||||
label.padding_left=4 \
|
||||
label.padding_right=4 \
|
||||
padding_left=4 \
|
||||
padding_right=4 \
|
||||
background.corner_radius=5 \
|
||||
background.height=24
|
||||
|
||||
# Register aerospace workspace change event
|
||||
${pkgs.sketchybar}/bin/sketchybar --add event aerospace_workspace_change
|
||||
|
||||
# Create workspace indicators for workspaces 1-10
|
||||
for sid in 1 2 3 4 5 6 7 8 9 10; do
|
||||
# Display "0" for workspace 10
|
||||
if [ "$sid" = "10" ]; then
|
||||
display="0"
|
||||
else
|
||||
display="$sid"
|
||||
fi
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item space.$sid left \
|
||||
--subscribe space.$sid aerospace_workspace_change \
|
||||
--set space.$sid \
|
||||
update_freq=2 \
|
||||
width=32 \
|
||||
background.color=$ITEM_BG \
|
||||
background.corner_radius=5 \
|
||||
background.height=20 \
|
||||
background.drawing=on \
|
||||
icon="$display" \
|
||||
icon.padding_left=13 \
|
||||
icon.padding_right=11 \
|
||||
icon.align=center \
|
||||
label.drawing=off \
|
||||
click_script="${pkgs.aerospace}/bin/aerospace workspace $sid" \
|
||||
script="$PLUGIN_DIR/aerospace.sh $sid"
|
||||
done
|
||||
|
||||
# Separator after workspaces
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item separator_left left \
|
||||
--set separator_left \
|
||||
icon="" \
|
||||
label="" \
|
||||
background.drawing=off \
|
||||
padding_left=10 \
|
||||
padding_right=10
|
||||
|
||||
# System monitoring modules (right side)
|
||||
# Note: Items added to 'right' appear in reverse order (last added = leftmost)
|
||||
# Adding in reverse to get: disk | cpu | memory | battery | volume | calendar
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item calendar right \
|
||||
--set calendar \
|
||||
icon="📅" \
|
||||
update_freq=30 \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
script="$PLUGIN_DIR/calendar.sh"
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item separator_media right \
|
||||
--set separator_media \
|
||||
icon="|" \
|
||||
label="" \
|
||||
background.drawing=off \
|
||||
padding_left=5 \
|
||||
padding_right=5
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item volume right \
|
||||
--set volume \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
script="$PLUGIN_DIR/volume.sh" \
|
||||
--subscribe volume volume_change
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item battery right \
|
||||
--set battery \
|
||||
update_freq=120 \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
script="$PLUGIN_DIR/battery.sh" \
|
||||
--subscribe battery system_woke power_source_change
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item separator_sys right \
|
||||
--set separator_sys \
|
||||
icon="|" \
|
||||
label="" \
|
||||
background.drawing=off \
|
||||
padding_left=5 \
|
||||
padding_right=5
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item memory right \
|
||||
--set memory \
|
||||
update_freq=5 \
|
||||
icon="🐏" \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
script="$PLUGIN_DIR/memory.sh"
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item cpu right \
|
||||
--set cpu \
|
||||
update_freq=2 \
|
||||
icon="🧠" \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
script="$PLUGIN_DIR/cpu.sh"
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --add item disk right \
|
||||
--set disk \
|
||||
update_freq=60 \
|
||||
icon="💾" \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
script="$PLUGIN_DIR/disk.sh"
|
||||
|
||||
# Menu bar extras / system tray items (rightmost)
|
||||
# Note: Requires Screen Recording permission for SketchyBar in System Settings
|
||||
# Use 'sketchybar --query default_menu_items' to discover available items
|
||||
|
||||
# Bluetooth
|
||||
${pkgs.sketchybar}/bin/sketchybar --add alias "Control Center,Bluetooth" right \
|
||||
--set "Control Center,Bluetooth" \
|
||||
alias.update_freq=1 \
|
||||
padding_left=0 \
|
||||
padding_right=0
|
||||
|
||||
# WiFi
|
||||
${pkgs.sketchybar}/bin/sketchybar --add alias "Control Center,WiFi" right \
|
||||
--set "Control Center,WiFi" \
|
||||
alias.update_freq=1 \
|
||||
padding_left=0 \
|
||||
padding_right=0
|
||||
|
||||
# Add other menu bar apps as discovered
|
||||
# Common examples:
|
||||
# - Cloudflare WARP: --add alias "Cloudflare WARP,Item-0" right
|
||||
# - Notion Calendar: --add alias "Notion Calendar,Item-0" right
|
||||
# Run 'sketchybar --query default_menu_items' to find exact names
|
||||
|
||||
# Update the bar
|
||||
${pkgs.sketchybar}/bin/sketchybar --update
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar aerospace workspace plugin
|
||||
home.file.".config/sketchybar/plugins/aerospace.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
# Colors
|
||||
FOCUSED_COLOR=0xff285577
|
||||
ITEM_BG=0xff333333
|
||||
TEXT=0xffffffff
|
||||
GRAY=0xff555555
|
||||
|
||||
# Get the currently focused workspace directly from aerospace
|
||||
# Trim whitespace to ensure clean comparison
|
||||
FOCUSED=$(${pkgs.aerospace}/bin/aerospace list-workspaces --focused | tr -d ' \n\r')
|
||||
|
||||
# Get list of empty workspaces
|
||||
EMPTY_WORKSPACES=$(${pkgs.aerospace}/bin/aerospace list-workspaces --monitor all --empty)
|
||||
|
||||
# Clean up the workspace number parameter
|
||||
WORKSPACE_NUM=$(echo "$1" | tr -d ' \n\r')
|
||||
|
||||
# Check if workspace has windows (is NOT empty)
|
||||
IS_EMPTY=false
|
||||
if echo "$EMPTY_WORKSPACES" | grep -q "^$WORKSPACE_NUM$"; then
|
||||
IS_EMPTY=true
|
||||
fi
|
||||
|
||||
# Check if this workspace is focused
|
||||
IS_FOCUSED=false
|
||||
if [ "$WORKSPACE_NUM" = "$FOCUSED" ]; then
|
||||
IS_FOCUSED=true
|
||||
fi
|
||||
|
||||
# Determine visibility and styling
|
||||
# Always show focused workspace (even if empty) with fixed width
|
||||
# Hide non-focused empty workspaces by setting width to 0 (collapsed)
|
||||
# Show non-focused non-empty workspaces with fixed width and inactive styling
|
||||
|
||||
if [ "$IS_FOCUSED" = "true" ]; then
|
||||
# Focused workspace - always show with focused styling
|
||||
${pkgs.sketchybar}/bin/sketchybar --set space.$WORKSPACE_NUM \
|
||||
drawing=on \
|
||||
width=32 \
|
||||
icon.padding_left=13 \
|
||||
icon.padding_right=11 \
|
||||
icon.align=center \
|
||||
background.color=$FOCUSED_COLOR \
|
||||
background.drawing=on \
|
||||
icon.color=$TEXT
|
||||
elif [ "$IS_EMPTY" = "true" ]; then
|
||||
# Empty workspace (not focused) - hide by turning off drawing
|
||||
${pkgs.sketchybar}/bin/sketchybar --set space.$WORKSPACE_NUM \
|
||||
drawing=off
|
||||
else
|
||||
# Non-empty workspace (not focused) - show with inactive styling
|
||||
${pkgs.sketchybar}/bin/sketchybar --set space.$WORKSPACE_NUM \
|
||||
drawing=on \
|
||||
width=32 \
|
||||
icon.padding_left=13 \
|
||||
icon.padding_right=11 \
|
||||
icon.align=center \
|
||||
background.color=$ITEM_BG \
|
||||
background.drawing=on \
|
||||
icon.color=$GRAY
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar CPU monitoring plugin
|
||||
home.file.".config/sketchybar/plugins/cpu.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
CORE_COUNT=$(sysctl -n machdep.cpu.thread_count)
|
||||
CPU_INFO=$(ps -eo pcpu,user)
|
||||
CPU_SYS=$(echo "$CPU_INFO" | grep -v $(whoami) | sed "s/[^ 0-9\.]//g" | awk "{sum+=\$1} END {print sum/(100.0 * $CORE_COUNT)}")
|
||||
CPU_USER=$(echo "$CPU_INFO" | grep $(whoami) | sed "s/[^ 0-9\.]//g" | awk "{sum+=\$1} END {print sum/(100.0 * $CORE_COUNT)}")
|
||||
CPU_PERCENT="$(echo "$CPU_SYS $CPU_USER" | awk '{printf "%.0f\n", ($1 + $2)*100}')"
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --set $NAME label="$CPU_PERCENT%"
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar memory monitoring plugin
|
||||
home.file.".config/sketchybar/plugins/memory.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
MEMORY_STATS=$(vm_stat)
|
||||
PAGES_FREE=$(echo "$MEMORY_STATS" | grep "Pages free" | awk '{print $3}' | tr -d '.')
|
||||
PAGES_ACTIVE=$(echo "$MEMORY_STATS" | grep "Pages active" | awk '{print $3}' | tr -d '.')
|
||||
PAGES_INACTIVE=$(echo "$MEMORY_STATS" | grep "Pages inactive" | awk '{print $3}' | tr -d '.')
|
||||
PAGES_WIRED=$(echo "$MEMORY_STATS" | grep "Pages wired down" | awk '{print $4}' | tr -d '.')
|
||||
PAGES_COMPRESSED=$(echo "$MEMORY_STATS" | grep "Pages stored in compressor" | awk '{print $5}' | tr -d '.')
|
||||
|
||||
TOTAL_PAGES=$((PAGES_FREE + PAGES_ACTIVE + PAGES_INACTIVE + PAGES_WIRED + PAGES_COMPRESSED))
|
||||
USED_PAGES=$((PAGES_ACTIVE + PAGES_INACTIVE + PAGES_WIRED + PAGES_COMPRESSED))
|
||||
MEMORY_PERCENT=$((USED_PAGES * 100 / TOTAL_PAGES))
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --set $NAME label="$MEMORY_PERCENT%"
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar disk monitoring plugin
|
||||
home.file.".config/sketchybar/plugins/disk.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
DISK_USAGE=$(df -H / | grep -v Filesystem | awk '{print $5}')
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --set $NAME label="$DISK_USAGE"
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar battery monitoring plugin
|
||||
home.file.".config/sketchybar/plugins/battery.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
PERCENTAGE=$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1)
|
||||
CHARGING=$(pmset -g batt | grep 'AC Power')
|
||||
|
||||
if [ "$PERCENTAGE" = "" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Select icon based on battery level
|
||||
case ''${PERCENTAGE} in
|
||||
9[0-9]|100) ICON="🔋"
|
||||
;;
|
||||
[6-8][0-9]) ICON="🔋"
|
||||
;;
|
||||
[3-5][0-9]) ICON="🔋"
|
||||
;;
|
||||
[1-2][0-9]) ICON="🔋"
|
||||
;;
|
||||
*) ICON="🪫"
|
||||
esac
|
||||
|
||||
# Show charging icon if connected to power
|
||||
if [[ $CHARGING != "" ]]; then
|
||||
ICON="⚡"
|
||||
fi
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --set $NAME icon="$ICON" label="''${PERCENTAGE}%"
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar volume monitoring plugin
|
||||
home.file.".config/sketchybar/plugins/volume.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$SENDER" = "volume_change" ]; then
|
||||
VOLUME=$(osascript -e "output volume of (get volume settings)")
|
||||
MUTED=$(osascript -e "output muted of (get volume settings)")
|
||||
|
||||
if [ "$MUTED" = "true" ]; then
|
||||
ICON="🔇"
|
||||
LABEL=""
|
||||
else
|
||||
case $VOLUME in
|
||||
[6-9][0-9]|100) ICON="🔊"
|
||||
;;
|
||||
[3-5][0-9]) ICON="🔉"
|
||||
;;
|
||||
*) ICON="🔈"
|
||||
esac
|
||||
LABEL="$VOLUME%"
|
||||
fi
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --set $NAME icon="$ICON" label="$LABEL"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# SketchyBar calendar/clock plugin
|
||||
home.file.".config/sketchybar/plugins/calendar.sh" = mkIf cfg.sketchybar.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/bash
|
||||
|
||||
${pkgs.sketchybar}/bin/sketchybar --set $NAME label="$(date '+%Y-%m-%d %H:%M')"
|
||||
'';
|
||||
};
|
||||
|
||||
# Launchd agent for auto-starting sketchybar
|
||||
launchd.agents.sketchybar = mkIf cfg.sketchybar.enable {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ "${pkgs.sketchybar}/bin/sketchybar" ];
|
||||
RunAtLoad = true;
|
||||
KeepAlive = true;
|
||||
StandardOutPath = "/tmp/sketchybar.log";
|
||||
StandardErrorPath = "/tmp/sketchybar.err.log";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user