Commit a2fea84
Eric Bower
·
2026-08-28 21:12:13 -0400 EDT
parent 4bc2206
refactor: replace noctalia Going minimal: swaybar, swayidle, swaylock
4 files changed,
+246,
-28
+76,
-25
1@@ -5,33 +5,52 @@ set $down j
2 set $up k
3 set $right l
4
5-set $bg0 #282828
6-set $bg1 #3c3836
7-set $bg3 #665c54
8-set $fg0 #fbf1c7
9-set $fg2 #d5c4a1
10-set $fg4 #a89984
11-set $bred #fb4934
12-set $bgreen #b8bb26
13-set $bblue #83a598
14+# 16-bit Terminal Palette (Monokai Classic)
15+set $bg #272822
16+set $fg #f8f8f2
17+
18+# Standard ANSI (0-7)
19+set $black #272822
20+set $red #f92672
21+set $green #a6e22e
22+set $yellow #e6db74
23+set $blue #66d9ef
24+set $magenta #ae81ff
25+set $cyan #a1efe4
26+set $white #f8f8f2
27+
28+# Bright ANSI (8-15)
29+set $br_black #75715e
30+set $br_red #fd971f
31+set $br_green #a6e22e
32+set $br_yellow #e6db74
33+set $br_blue #66d9ef
34+set $br_magenta #ae81ff
35+set $br_cyan #a1efe4
36+set $br_white #f8f8f2
37
38 # Color scheme border bg text indicator child_border
39-client.focused $bblue $bg0 $fg0 $bred $bblue
40-client.focused_inactive $bg3 $bg1 $fg2 $bg3 $bg3
41-client.unfocused $bg3 $bg0 $fg4 $bg3 $bg3
42-client.urgent $bred $bred $fg0 $bred $bred
43-client.placeholder $bg3 $bg0 $fg4 $bg3 $bg3
44-client.background $bg0
45+client.focused $blue $bg $fg $red $blue
46+client.focused_inactive $br_black $bg $white $br_black $br_black
47+client.unfocused $br_black $bg $white $br_black $br_black
48+client.urgent $red $red $bg $red $red
49+client.placeholder $br_black $bg $white $br_black $br_black
50+client.background $bg
51
52 default_border pixel 2
53
54-set $ipc noctalia msg
55-bindsym $mod+d exec $ipc panel-toggle launcher
56-bindsym --locked XF86AudioRaiseVolume exec $ipc volume-up
57-bindsym --locked XF86AudioLowerVolume exec $ipc volume-down
58-bindsym --locked XF86AudioMute exec $ipc volume-mute
59-bindsym --locked XF86MonBrightnessUp exec $ipc brightness-up
60-bindsym --locked XF86MonBrightnessDown exec $ipc brightness-down
61+# Audio volume controls (pamixer)
62+bindsym --locked XF86AudioRaiseVolume exec pamixer -i 5
63+bindsym --locked XF86AudioLowerVolume exec pamixer -d 5
64+bindsym --locked XF86AudioMute exec pamixer -t
65+bindsym --locked XF86AudioMicMute exec pamixer --default-source -t
66+
67+# Screen brightness controls (brightnessctl)
68+bindsym --locked XF86MonBrightnessUp exec brightnessctl set +5%
69+bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
70+
71+# Application Launcher (wmenu)
72+bindsym $mod+d exec wmenu-run -f "JetBrainsMono Nerd Font 10.5" -N "#272822" -n "#f8f8f2" -S "#66d9ef" -s "#272822" -p "run: "
73
74 floating_modifier $mod normal
75 # bindsym $mod+Return exec foot
76@@ -95,18 +114,33 @@ set $laptop eDP-1
77 output $laptop mode 2256x1504@59.999Hz
78 output $laptop scale 1.5
79
80+output * bg ~/config/wallpapers/webb_telescope.png fill
81+
82 # set $cahoots DP-2
83 # Samsung Electric Company U32J59x HCJTB01080
84 # output $cahoots scale 1.5
85
86-bindswitch lid:on output $laptop disable
87-bindswitch --reload lid:off output $laptop enable; exec noctalia
88+# Lock screen command
89+set $lock swaylock -F -e \
90+ -i ~/config/wallpapers/webb_telescope.png \
91+ --indicator-idle-visible
92+
93+bindsym $mod+Alt+l exec $lock
94
95-exec noctalia
96+# Laptop lid switch bindings
97+bindswitch lid:on exec $lock; output $laptop disable
98+bindswitch --reload lid:off output $laptop enable
99+
100+# Idle management (lock after 5 min, turn off displays after 10 min)
101+exec swayidle -w \
102+ timeout 300 '$lock' \
103+ timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
104+ before-sleep '$lock'
105
106 # required for xdg-desktop-portal-gtk.service
107 exec systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP DISPLAY MOZ_ENABLE_WAYLAND
108 exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway DISPLAY MOZ_ENABLE_WAYLAND=1
109+exec wlsunset -l 42.3 -L -83.0
110
111 input "type:touchpad" {
112 tap enabled
113@@ -123,3 +157,20 @@ input "20547:23623:Ploopy_Corporation_Ploopy_Adept_Trackball_Mouse" {
114 accel_profile "flat"
115 pointer_accel -0.5 # between -1 and 1
116 }
117+
118+bar {
119+ position bottom
120+ status_command python3 ~/.config/sway/status.py
121+ font pango:JetBrainsMono Nerd Font 10.5
122+
123+ colors {
124+ background $bg
125+ statusline $fg
126+ separator $br_black
127+
128+ focused_workspace $blue $blue $bg
129+ active_workspace $br_black $br_black $fg
130+ inactive_workspace $bg $bg $white
131+ urgent_workspace $red $red $bg
132+ }
133+}
+157,
-0
1@@ -0,0 +1,157 @@
2+#!/usr/bin/env python3
3+import json
4+import sys
5+import os
6+import subprocess
7+import threading
8+import time
9+
10+def get_sound():
11+ try:
12+ muted = subprocess.check_output(["pamixer", "--get-mute"], text=True).strip() == "true"
13+ vol = subprocess.check_output(["pamixer", "--get-volume"], text=True).strip()
14+ if muted:
15+ return f"MUTED {vol}%"
16+ return f"VOL {vol}%"
17+ except Exception:
18+ pass
19+ return "VOL ?"
20+
21+def get_battery():
22+ try:
23+ if not os.path.exists("/sys/class/power_supply"):
24+ return None
25+ bat_dirs = [d for d in os.listdir("/sys/class/power_supply") if d.startswith("BAT")]
26+ if not bat_dirs:
27+ return None
28+ bat_path = os.path.join("/sys/class/power_supply", bat_dirs[0])
29+ cap_file = os.path.join(bat_path, "capacity")
30+ stat_file = os.path.join(bat_path, "status")
31+
32+ if not os.path.exists(cap_file):
33+ return None
34+
35+ with open(cap_file) as f:
36+ cap = f.read().strip()
37+
38+ status = "Discharging"
39+ if os.path.exists(stat_file):
40+ with open(stat_file) as f:
41+ status = f.read().strip()
42+
43+ label = "CHR" if status == "Charging" else "BAT"
44+ return f"{label} {cap}%"
45+ except Exception:
46+ return None
47+
48+def get_brightness():
49+ try:
50+ actual = int(subprocess.check_output(["brightnessctl", "get"], text=True).strip())
51+ max_b = int(subprocess.check_output(["brightnessctl", "max"], text=True).strip())
52+ pct = int((actual / max_b) * 100)
53+ return f"BRT {pct}%"
54+ except Exception:
55+ return None
56+
57+def get_net():
58+ try:
59+ out = subprocess.check_output(
60+ ["nmcli", "-t", "-f", "TYPE,STATE,CONNECTION", "dev"],
61+ text=True
62+ ).strip()
63+
64+ eth_name = None
65+ wifi_ssid = None
66+
67+ for line in out.splitlines():
68+ parts = line.split(":")
69+ if len(parts) >= 3 and parts[1] == "connected":
70+ dev_type = parts[0]
71+ conn_name = parts[2]
72+ if dev_type == "ethernet":
73+ eth_name = conn_name if conn_name else "Wired"
74+ elif dev_type == "wifi":
75+ wifi_ssid = conn_name if conn_name else "WiFi"
76+
77+ if eth_name:
78+ return f"ETH {eth_name}"
79+ elif wifi_ssid:
80+ return f"NET {wifi_ssid}"
81+ return "NET Disconnected"
82+ except Exception:
83+ return "NET ?"
84+
85+def get_time():
86+ return time.strftime("%I:%M %m/%d").lstrip("0")
87+
88+def generate_blocks():
89+ blocks = []
90+
91+ # Sound (Monokai Green #a6e22e)
92+ blocks.append({"name": "sound", "full_text": get_sound(), "color": "#a6e22e"})
93+
94+ # Battery (Monokai Yellow #e6db74)
95+ bat = get_battery()
96+ if bat:
97+ blocks.append({"name": "battery", "full_text": bat, "color": "#e6db74"})
98+
99+ # Brightness (Monokai Cyan #66d9ef)
100+ bright = get_brightness()
101+ if bright:
102+ blocks.append({"name": "brightness", "full_text": bright, "color": "#66d9ef"})
103+
104+ # Network (Ethernet / WiFi) (Monokai Purple #ae81ff)
105+ blocks.append({"name": "wifi", "full_text": get_net(), "color": "#ae81ff"})
106+
107+ # Clock (Monokai White #f8f8f2)
108+ blocks.append({"name": "clock", "full_text": get_time(), "color": "#f8f8f2"})
109+
110+ return blocks
111+
112+def listen_clicks():
113+ while True:
114+ try:
115+ line = sys.stdin.readline()
116+ if not line:
117+ break
118+ clean_line = line.strip().lstrip("[,").rstrip(",")
119+ if not clean_line:
120+ continue
121+ event = json.loads(clean_line)
122+ block_name = event.get("name")
123+ button = event.get("button", 1)
124+
125+ if button == 1:
126+ if block_name == "wifi":
127+ try:
128+ subprocess.Popen(["monstar", "-e", "nmtui"])
129+ except FileNotFoundError:
130+ subprocess.Popen(["foot", "-e", "nmtui"])
131+ elif block_name == "sound":
132+ try:
133+ subprocess.Popen(["pavucontrol"])
134+ except FileNotFoundError:
135+ subprocess.Popen(["pamixer", "-t"])
136+ except Exception:
137+ pass
138+
139+def main():
140+ try:
141+ # i3bar / swaybar JSON protocol header
142+ print(json.dumps({"version": 1, "click_events": True}))
143+ print("[")
144+ sys.stdout.flush()
145+
146+ # Thread to handle click events on stdin
147+ threading.Thread(target=listen_clicks, daemon=True).start()
148+
149+ while True:
150+ blocks = generate_blocks()
151+ print(json.dumps(blocks) + ",")
152+ sys.stdout.flush()
153+ time.sleep(1)
154+ except (BrokenPipeError, KeyboardInterrupt):
155+ sys.exit(0)
156+
157+if __name__ == "__main__":
158+ main()
+8,
-2
1@@ -5,11 +5,11 @@ base-devel
2 bash-language-server
3 bat
4 bats
5-bemenu
6 bind
7 blueprint-compiler
8 bluez
9 bluez-utils
10+brightnessctl
11 bun
12 cmake
13 difftastic
14@@ -31,10 +31,10 @@ git-delta
15 go
16 golangci-lint
17 gopls
18+grim
19 gtk4-layer-shell
20 htop
21 hunspell-en_us
22-imv
23 inetutils
24 intel-ucode
25 isync
26@@ -57,6 +57,7 @@ moreutils
27 mpv
28 msmtp
29 ncdu
30+networkmanager
31 nfs-utils
32 nmap
33 nodejs
34@@ -68,6 +69,7 @@ oath-toolkit
35 obs-studio
36 openbsd-netcat
37 openssh
38+pamixer
39 pass
40 pass-otp
41 pavucontrol
42@@ -83,9 +85,12 @@ rsync
43 shellcheck
44 shfmt
45 shotcut
46+slurp
47 smartmontools
48 steam
49 sway
50+swayidle
51+swaylock
52 thunar
53 traceroute
54 ttf-jetbrains-mono-nerd
55@@ -100,6 +105,7 @@ wayland-protocols
56 wireguard-tools
57 wl-clipboard
58 wlsunset
59+wmenu
60 xdg-desktop-portal-wlr
61 xorg-xwayland
62 zfs-linux
+5,
-1
1@@ -40,7 +40,6 @@ mpv
2 networkmanager
3 nfs-utils
4 nm-connection-editor
5-noctalia
6 nodejs
7 noto-fonts-emoji
8 npm
9@@ -50,6 +49,7 @@ openssh
10 pamixer
11 pass
12 pass-otp
13+pavucontrol
14 pipewire-pulse
15 power-profiles-daemon
16 reflector
17@@ -59,17 +59,21 @@ shotcut
18 slurp
19 steam
20 sway
21+swayidle
22+swaylock
23 systemd-resolvconf
24 ttf-jetbrains-mono-nerd
25 ttf-noto-nerd
26 unzip
27 vim
28+viu
29 vulkan-radeon
30 wireguard-tools
31 wireless_tools
32 wl-clipboard
33 wlr-randr
34 wlsunset
35+wmenu
36 xdg-utils
37 xorg-xwayland
38 zig