summaryrefslogtreecommitdiff
path: root/common/modules
diff options
context:
space:
mode:
authorbrustybee <beebeeb5k@gmail.com>2026-04-03 03:27:14 +0530
committerbrustybee <beebeeb5k@gmail.com>2026-04-03 03:27:14 +0530
commit415f9f859e5ee48bd7e28468b95cd3fadba33f7e (patch)
tree6ac11dd847a9f05742cd3498eabd7bcb7d19b284 /common/modules
parent141855bcaed2d386107240f4090bf7f4a7364f7f (diff)
add bspwm and polybar ( kinda )
Diffstat (limited to 'common/modules')
-rw-r--r--common/modules/bspwm/default.nix182
-rw-r--r--common/modules/bspwm/polybar.nix337
-rw-r--r--common/modules/default.nix1
-rw-r--r--common/modules/matugen/default.nix12
-rw-r--r--common/modules/matugen/templates/matugen-bspwm.nix16
-rw-r--r--common/modules/matugen/templates/matugen-polybar.nix25
6 files changed, 573 insertions, 0 deletions
diff --git a/common/modules/bspwm/default.nix b/common/modules/bspwm/default.nix
new file mode 100644
index 0000000..9edc85c
--- /dev/null
+++ b/common/modules/bspwm/default.nix
@@ -0,0 +1,182 @@
+{
+ homeManager,
+ inputs,
+ moduleNameSpace,
+ ...
+}:
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.${moduleNameSpace}.bspwm;
+ snip = pkgs.writeShellScript "snip" ''
+ case $1 in
+ full)
+ ${pkgs.maim}/bin/maim | ${pkgs.xclip}/bin/xclip -selection clipboard -t image/png
+ ;;
+ selection)
+ ${pkgs.maim}/bin/maim -s | ${pkgs.xclip}/bin/xclip -selection clipboard -t image/png
+ ;;
+ esac
+ '';
+
+ smart-alacritty = pkgs.writeShellScript "smart-alacritty" ''
+ alacritty msg create-window || exec alacritty
+ '';
+
+ smart-ghostty = pkgs.writeShellScript "smart-ghostty" ''
+ ghostty +new-window || exec ghostty
+ '';
+
+ terminal =
+ if config.beeMods.terminal.default == "alacritty" then
+ "${smart-alacritty}"
+ else if config.beeMods.terminal.default == "ghostty" then
+ "${smart-ghostty}"
+ else
+ "st";
+in
+{
+ imports = lib.optionalAttrs homeManager [ ./polybar.nix ];
+
+ options.${moduleNameSpace}.bspwm = {
+ enable = lib.mkEnableOption "bspwm setup";
+ };
+
+ config = lib.mkIf cfg.enable (
+ if homeManager then
+ {
+ xsession.windowManager.bspwm = {
+ enable = true;
+ monitors = {
+ "eDP" = [
+ "1"
+ "2"
+ "3"
+ "4"
+ "5"
+ "6"
+ "7"
+ "8"
+ "9"
+ ];
+ };
+
+ rules = {
+ "Alacritty" = {
+ desktop = "^1";
+ follow = true;
+ };
+ "ghostty" = {
+ desktop = "^1";
+ follow = true;
+ };
+ "zen" = {
+ desktop = "^2";
+ follow = true;
+ };
+ "firefox" = {
+ desktop = "^2";
+ follow = true;
+ };
+ "vesktop" = {
+ desktop = "^3";
+ follow = true;
+ };
+ "discord" = {
+ desktop = "^3";
+ follow = true;
+ };
+ "steam" = {
+ desktop = "^4";
+ follow = true;
+ };
+ };
+
+ settings = {
+ border_width = 2;
+ window_gap = 5;
+ split_ratio = 0.55;
+ click_to_focus = "any";
+ pointer_modifier = "mod4";
+ pointer_action1 = "move";
+ pointer_action2 = "resize_side";
+ pointer_action3 = "resize_corner";
+ focus_follows_pointer = true;
+ };
+
+ extraConfig = ''
+ [ -f ~/.config/bspwm/colors ] && . ~/.config/bspwm/colors
+ '';
+
+ startupPrograms = [
+ "feh --no-fehbg --bg-fill $(rg wallpaper ~/.config/beeSettings | cut -d'=' -f2)"
+ "xsetroot -cursor_name left_ptr"
+ "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"
+ "gnome-keyring-daemon --start --components=secrets,ssh,pkcs11"
+ "xrandr --output eDP --set TearFree on"
+ "polybar"
+ ];
+ };
+
+ services.sxhkd = {
+ enable = true;
+ keybindings = {
+ "super + Return" = terminal;
+ "super + r" = "pkill -USR1 -x sxhkd; bspc wm -r";
+ "super + q" = "bspc node -c";
+ "super + m" = "bspc quit";
+
+ "super + a" = "rofi -show drun";
+ "super + period" = "rofi -show emoji -modi emoji";
+ "alt + F4" = "rofi -show power-menu -modi power-menu:rofi-power-menu";
+ "super + y" = "beesettings wall";
+ "super + comma" = "beesettings settings";
+ "super + b" = "zen";
+ "super + e" = "nautilus";
+ "super + F12" = "gnome-calculator";
+
+ "Print" = "${snip} full";
+ "super + Print" = "${snip} selection";
+
+ "super + {h,j,k,l}" = "bspc node -f {west,south,north,east}";
+ "super + shift + {h,j,k,l}" = "bspc node -s {west,south,north,east}";
+ "super + {Left,Down,Up,Right}" = "bspc node -v {-50 0,0 50,0 -50,50 0}";
+
+ "super + space" = "bspc node -t ~floating";
+ "alt + f" = "bspc node -t ~fullscreen";
+ "super + i" = "bspc node -g hidden=on";
+
+ "super + shift + i" = "bspc node any.hidden.local -g hidden=off";
+
+ "super + {1-9}" = "bspc desktop -f '^{1-9}'";
+ "super + shift + {1-9}" = "bspc node -d '^{1-9}'";
+
+ "XF86AudioRaiseVolume" = "volume-control up";
+ "XF86AudioLowerVolume" = "volume-control down";
+ "XF86AudioMute" = "volume-control mute";
+ "XF86AudioMicMute" = "mic-control toggle";
+ "XF86MonBrightnessUp" = "brightness-control up";
+ "XF86MonBrightnessDown" = "brightness-control down";
+
+ "XF86Audio{Play,Next,Prev,Stop}" = "playerctl {play-pause,next,previous,stop}";
+
+ "alt + h" = "bspc node -z left -50 0 || bspc node -z right -50 0";
+ "alt + j" = "bspc node -z bottom 0 50 || bspc node -z top 0 50";
+ "alt + k" = "bspc node -z top 0 -50 || bspc node -z bottom 0 -50";
+ "alt + l" = "bspc node -z right 50 0 || bspc node -z left 50 0";
+ "alt + a" = "bspc desktop -l next";
+ };
+ };
+ }
+ else
+ {
+ services.xserver = {
+ windowManager.bspwm.enable = true;
+ };
+ }
+ );
+}
diff --git a/common/modules/bspwm/polybar.nix b/common/modules/bspwm/polybar.nix
new file mode 100644
index 0000000..09da86e
--- /dev/null
+++ b/common/modules/bspwm/polybar.nix
@@ -0,0 +1,337 @@
+{
+ config,
+ pkgs,
+ ...
+}:
+let
+ polybar-bluetooth = pkgs.writeShellApplication {
+ name = "polybar-bluetooth";
+ runtimeInputs = with pkgs; [
+ bluez
+ dbus
+ gnugrep
+ coreutils
+ findutils
+ ];
+ text = ''
+ print_status() {
+ if bluetoothctl show | grep -q "Powered: yes"; then
+ if bluetoothctl info | grep -q "Connected: yes"; then
+ dev=$(bluetoothctl info | grep "Alias" | cut -d: -f2 | xargs)
+ echo "$dev"
+ else
+ echo "On"
+ fi
+ else
+ echo "Off"
+ fi
+ }
+
+ print_status
+
+ # Subscribe to DBus for instant updates without polling
+ dbus-monitor --system "type='signal',sender='org.bluez',member='PropertiesChanged'" 2>/dev/null | \
+ grep --line-buffered "member=PropertiesChanged" | \
+ while read -r _; do
+ print_status
+ done
+ '';
+ };
+
+ polybar-network = pkgs.writeShellApplication {
+ name = "polybar-network";
+ runtimeInputs = with pkgs; [
+ iproute2
+ networkmanager
+ gnugrep
+ coreutils
+ ];
+ text = ''
+ print_status() {
+ if ip route | grep -q "^default"; then
+ ssid=$(nmcli -t -f NAME connection show --active | head -n1)
+
+ if [ -z "$ssid" ]; then
+ echo "Connected..."
+ else
+ echo "$ssid"
+ fi
+ else
+ echo "Offline"
+ fi
+ }
+
+ print_status
+
+ ip monitor route address link | \
+ grep --line-buffered ".*" | \
+ while read -r _; do
+ print_status
+ done
+ '';
+ };
+
+ polybar-power = pkgs.writeShellApplication {
+ name = "polybar-power";
+ runtimeInputs = with pkgs; [
+ power-profiles-daemon
+ dbus
+ gnugrep
+ coreutils
+ ];
+ text = ''
+ print_status() {
+ # ShellCheck fix: Use POSIX classes [:lower:] instead of a-z
+ powerprofilesctl get 2>/dev/null | tr '[:lower:]' '[:upper:]'
+ }
+
+ print_status
+
+ dbus-monitor --system "type='signal',sender='net.hadess.PowerProfiles'" 2>/dev/null | \
+ grep --line-buffered "member=PropertiesChanged" | \
+ while read -r _; do
+ print_status
+ done
+ '';
+ };
+
+ polybar-audio = pkgs.writeShellApplication {
+ name = "polybar-audio";
+ runtimeInputs = with pkgs; [
+ wireplumber
+ pulseaudio
+ gawk
+ gnugrep
+ coreutils
+ ];
+ text = ''
+ print_vol() {
+ vol=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{print int($2*100)}')
+ if wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED; then
+ echo "MUTED"
+ else
+ echo "$vol%"
+ fi
+ }
+
+ print_vol
+ pactl subscribe | grep --line-buffered "sink" | while read -r _; do
+ print_vol
+ done
+ '';
+ };
+
+ polybar-mic = pkgs.writeShellApplication {
+ name = "polybar-mic";
+ runtimeInputs = with pkgs; [
+ wireplumber
+ pulseaudio
+ gawk
+ gnugrep
+ coreutils
+ ];
+ text = ''
+ get_mic_status() {
+ vol=$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@)
+ if [[ "$vol" == *"MUTED"* ]]; then
+ echo "MUTED"
+ else
+ echo "$vol" | awk '{print int($2*100) "%"}'
+ fi
+ }
+
+ sleep 0.2
+ get_mic_status
+
+ pactl subscribe 2>/dev/null | grep --line-buffered "Event 'change' on source" | while read -r _; do
+ get_mic_status
+ done
+ '';
+ };
+in
+{
+ services.polybar = {
+ enable = true;
+
+ # Basic startup script
+ script = "polybar main &";
+
+ config = {
+ # --- BASE SETTINGS ---
+ "section/base" = {
+ include-file = "~/.config/polybar/colors.ini";
+ };
+
+ "bar/main" = {
+ width = "100%";
+ height = "20pt";
+ radius = 0;
+ bottom = false;
+
+ background = "\${colors.background}";
+ foreground = "\${colors.foreground}";
+
+ border-size = 0;
+ padding-left = 2;
+ padding-right = 2;
+ module-margin = 1;
+
+ separator = "|";
+ separator-foreground = "\${colors.disabled}";
+
+ font-0 = "IosevkaInput:size=10;3";
+
+ modules-left = "bspwm";
+ modules-center = "date powerprofile";
+ modules-right = "memory cpu battery mic audio bluetooth network tray";
+
+ enable-ipc = true;
+ wm-restack = "bspwm";
+ };
+
+ "module/tray" = {
+ type = "internal/tray";
+ tray-spacing = "8px";
+ tray-size = "14pt";
+ };
+
+ "module/bspwm" = {
+ type = "internal/bspwm";
+ pin-workspaces = true;
+ inline-mode = false;
+ label-focused = "%name%";
+ label-focused-background = "\${colors.primary}";
+ label-focused-foreground = "\${colors.on_primary}";
+ label-focused-underline = "\${colors.primary}";
+ label-focused-padding = 2;
+ label-occupied = "%name%";
+ label-occupied-foreground = "\${colors.primary}";
+ label-occupied-padding = 2;
+ label-urgent = "%name%";
+ label-urgent-background = "\${colors.alert}";
+ label-urgent-padding = 2;
+ label-empty = "%name%";
+ label-empty-foreground = "\${colors.disabled}";
+ label-empty-padding = 2;
+ };
+
+ "module/memory" = {
+ type = "internal/memory";
+ interval = 2;
+ format-prefix = "RAM ";
+ format-prefix-foreground = "\${colors.primary}";
+ label = "%percentage_used:2%%";
+ };
+
+ "module/cpu" = {
+ type = "internal/cpu";
+ interval = 2;
+ format-prefix = "CPU ";
+ format-prefix-foreground = "\${colors.primary}";
+ label = "%percentage:2%%";
+ };
+
+ "module/date" = {
+ type = "internal/date";
+ interval = 30;
+ date = "%I:%M %p";
+ date-alt = "%Y-%m-%d %H:%M:%S";
+ label = "%date%";
+ label-foreground = "\${colors.primary}";
+ };
+
+ "module/battery" = {
+ type = "internal/battery";
+ battery = "BAT1";
+ adapter = "ACAD";
+ full-at = 99;
+ low-at = 10;
+ poll-interval = 5;
+ format-charging = "<label-charging>";
+ format-charging-prefix = "CHR ";
+ format-charging-prefix-foreground = "\${colors.primary}";
+ format-discharging = "<label-discharging>";
+ format-discharging-prefix = "BAT ";
+ format-discharging-prefix-foreground = "\${colors.primary}";
+ format-full = "<label-full>";
+ format-full-prefix = "BAT ";
+ format-full-prefix-foreground = "\${colors.primary}";
+ label-charging = "%percentage%%";
+ label-discharging = "%percentage%%";
+ label-full = "100%";
+ };
+
+ "module/bluetooth" = {
+ type = "custom/script";
+ tail = true;
+ format-prefix = "BT ";
+ format-prefix-foreground = "\${colors.primary}";
+ exec = "${polybar-bluetooth}/bin/polybar-bluetooth";
+
+ click-left = "${pkgs.writeShellScript "rofi-bt-wrapper" ''
+ export PATH=$PATH:${pkgs.rofi}/bin
+ ${pkgs.rofi-bluetooth}/bin/rofi-bluetooth
+ ''}";
+
+ click-right = "${pkgs.bluez}/bin/bluetoothctl power off";
+ };
+
+ "module/network" = {
+ type = "custom/script";
+ tail = true;
+ format-prefix = "WIFI ";
+ format-prefix-foreground = "\${colors.primary}";
+ exec = "${polybar-network}/bin/polybar-network";
+
+ click-left = "${pkgs.writeShellScript "rofi-net-wrapper" ''
+ export PATH=$PATH:${pkgs.rofi}/bin:${pkgs.networkmanager}/bin
+ ${pkgs.rofi-network-manager}/bin/rofi-network-manager
+ ''}";
+ };
+
+ "module/powerprofile" = {
+ type = "custom/script";
+ tail = true;
+ format = "<label>";
+ label = "%output%";
+ label-foreground = "\${colors.foreground}";
+ exec = "${polybar-power}/bin/polybar-power";
+
+ click-left = "${pkgs.writeShellScript "ppd-toggle" ''
+ current=$(${pkgs.power-profiles-daemon}/bin/powerprofilesctl get)
+ case "$current" in
+ power-saver) ${pkgs.power-profiles-daemon}/bin/powerprofilesctl set balanced ;;
+ balanced) ${pkgs.power-profiles-daemon}/bin/powerprofilesctl set performance ;;
+ performance) ${pkgs.power-profiles-daemon}/bin/powerprofilesctl set power-saver ;;
+ esac
+ ''}";
+ };
+
+ "module/audio" = {
+ type = "custom/script";
+ tail = true;
+ format-prefix = "VOL ";
+ format-prefix-foreground = "\${colors.primary}";
+ exec = "${polybar-audio}/bin/polybar-audio";
+
+ click-right = "${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
+ click-left = "${pkgs.pavucontrol}/bin/pavucontrol -t 3";
+ scroll-up = "${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ --limit 1.0";
+ scroll-down = "${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
+ };
+
+ "module/mic" = {
+ type = "custom/script";
+ tail = true;
+ format-prefix = "MIC ";
+ format-prefix-foreground = "\${colors.primary}";
+ exec = "${polybar-mic}/bin/polybar-mic";
+
+ click-left = "${pkgs.pavucontrol}/bin/pavucontrol -t 4";
+ click-right = "${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
+ scroll-up = "${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%+ --limit 1.0";
+ scroll-down = "${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%-";
+ };
+ };
+ };
+}
diff --git a/common/modules/default.nix b/common/modules/default.nix
index 377ebb1..bd9b4d6 100644
--- a/common/modules/default.nix
+++ b/common/modules/default.nix
@@ -11,6 +11,7 @@ let
modules = {
mango = import ./mango args;
dwm = import ./dwm args;
+ bspwm = import ./bspwm args;
terminal = import ./terminal args;
beevim = import ./beevim args;
matugen = import ./matugen args;
diff --git a/common/modules/matugen/default.nix b/common/modules/matugen/default.nix
index 5ce3014..b0ccf94 100644
--- a/common/modules/matugen/default.nix
+++ b/common/modules/matugen/default.nix
@@ -186,6 +186,18 @@ in
output_path = '~/.config/wallust/templates/sequences'
''}
+ ${lib.optionalString config.beeMods.bspwm.enable ''
+ [templates.bspwm]
+ input_path = "~/.config/matugen/templates/bspwm-colors"
+ output_path = "~/.config/bspwm/colors"
+ post_hook = "bspc wm -r"
+ ''}
+
+ [templates.polybar]
+ input_path = "~/.config/matugen/templates/polybar-colors.ini"
+ output_path = "~/.config/polybar/colors.ini"
+ post_hook = "pkill polybar; polybar &"
+
[templates.zed]
input_path = '~/.config/matugen/templates/zed.json'
output_path = '~/.config/zed/themes/matugen.json'
diff --git a/common/modules/matugen/templates/matugen-bspwm.nix b/common/modules/matugen/templates/matugen-bspwm.nix
new file mode 100644
index 0000000..1e0a546
--- /dev/null
+++ b/common/modules/matugen/templates/matugen-bspwm.nix
@@ -0,0 +1,16 @@
+{
+ xdg.configFile = {
+ "matugen/templates/bspwm-colors" = {
+ enable = true;
+ text =
+ # sh
+ ''
+ #!/bin/bash
+ bspc config focused_border_color '{{colors.primary.default.hex}}'
+ bspc config active_border_color '{{colors.tertiary.default.hex}}'
+ bspc config normal_border_color '{{colors.outline.default.hex}}'
+ bspc config presel_feedback_color '{{colors.secondary.default.hex}}'
+ '';
+ };
+ };
+}
diff --git a/common/modules/matugen/templates/matugen-polybar.nix b/common/modules/matugen/templates/matugen-polybar.nix
new file mode 100644
index 0000000..40cf1cf
--- /dev/null
+++ b/common/modules/matugen/templates/matugen-polybar.nix
@@ -0,0 +1,25 @@
+{
+ xdg.configFile = {
+ "matugen/templates/polybar-colors.ini" = {
+ enable = true;
+ text =
+ # ini
+ ''
+ [colors]
+ <* if {{ is_dark_mode }} *>
+ background = {{colors.surface.default.hex}}
+ background-alt = {{colors.surface_container.default.hex}}
+ <* else *>
+ background={{colors.surface_container.default.hex}}
+ background-alt = {{colors.surface_container_highest.default.hex}};
+ <* endif *>
+ foreground = {{colors.on_surface.default.hex}}
+ primary = {{colors.primary.default.hex}}
+ on_primary = {{colors.on_primary.default.hex}}
+ secondary = {{colors.secondary.default.hex}}
+ alert = {{colors.error.default.hex}}
+ disabled = {{colors.outline.default.hex}}
+ '';
+ };
+ };
+}