Add sway/wofi/foot Wayland desktop stack with per-host toggle
New opt-in feature for x86_64 desktops: sway + wofi + foot + swaybg +
swaylock + swayidle + grim + slurp + waybar + wl-clipboard. mako on
arch, dunst on debian (mako isn't packaged for debian).
Files:
- .chezmoi.yaml.tmpl: added data.sway flag (true on miche/byte/kaiser,
false on Pis). Override per host with ~/.config/chezmoi/features/sway
or ~/.config/chezmoi/features/no-sway marker files.
- run_once_40-install-sway.sh.tmpl: installs packages if .sway=true,
exits 0 otherwise. Sets up the marker file.
- dot_config/{sway,foot,wofi,waybar,mako}/: existing configs from miche.
Per-host toggle workflow:
# On any box, enable sway:
touch ~/.config/chezmoi/features/sway
chezmoi apply
# On a sway-enabled box, disable it:
touch ~/.config/chezmoi/features/no-sway
rm ~/.config/chezmoi/features/sway
chezmoi apply
Currently sway packages are already installed on miche (existed before
this commit). Byte will get them via the new run_once_40 script.
Pis (rye, crouton) are unaffected — install script early-returns.
This commit is contained in:
parent
fe73bbecba
commit
6bbaa8f2f5
21 changed files with 965 additions and 1 deletions
|
|
@ -61,3 +61,21 @@ age:
|
||||||
data:
|
data:
|
||||||
os_family: {{ $osFamily | quote }}
|
os_family: {{ $osFamily | quote }}
|
||||||
os_id: {{ .chezmoi.osRelease.id | quote }}
|
os_id: {{ .chezmoi.osRelease.id | quote }}
|
||||||
|
|
||||||
|
# Sway/Wayland desktop stack — enabled per host. Pis don't need it
|
||||||
|
# (headless); x86_64 desktops do. Override at runtime by creating
|
||||||
|
# `~/.config/chezmoi/features/sway` (force ON) or
|
||||||
|
# `~/.config/chezmoi/features/no-sway` (force OFF).
|
||||||
|
#
|
||||||
|
# To toggle for a new box: `touch ~/.config/chezmoi/features/sway`
|
||||||
|
# then `chezmoi apply`.
|
||||||
|
{{- $swayOverrideOn := stat (joinPath .chezmoi.homeDir ".config/chezmoi/features/sway") }}
|
||||||
|
{{- $swayOverrideOff := stat (joinPath .chezmoi.homeDir ".config/chezmoi/features/no-sway") }}
|
||||||
|
{{- if $swayOverrideOn }}
|
||||||
|
sway: true
|
||||||
|
{{- else if $swayOverrideOff }}
|
||||||
|
sway: false
|
||||||
|
{{- else }}
|
||||||
|
{{- $swayHosts := list "miche" "byte" "kaiser" }}
|
||||||
|
sway: {{ has .chezmoi.hostname $swayHosts }}
|
||||||
|
{{- end }}
|
||||||
88
dot_config/foot/foot.ini
Normal file
88
dot_config/foot/foot.ini
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
# foot terminal — gruvbox dark, Maple Mono 14pt with Terminus fallback
|
||||||
|
# Reference: man foot.ini
|
||||||
|
|
||||||
|
[main]
|
||||||
|
font=Maple Mono CN:size=14,Terminus:size=14
|
||||||
|
font-bold=Maple Mono CN:weight=bold:size=14
|
||||||
|
font-italic=Maple Mono CN:slant=italic:size=14
|
||||||
|
font-bold-italic=Maple Mono CN:weight=bold:slant=italic:size=14
|
||||||
|
font-size-adjustment=0.5
|
||||||
|
pad=8x8
|
||||||
|
term=foot
|
||||||
|
# (Previously set to "foot-extra", but that terminfo is not installed in the
|
||||||
|
# CachyOS foot package; only foot, foot+base, foot-direct are. Setting
|
||||||
|
# TERM=foot-extra breaks every ncurses program — htop, nvtop, vim, etc. —
|
||||||
|
# with "cannot initialize terminal type". "foot" has 256 colors and
|
||||||
|
# everything modern tools need.)
|
||||||
|
# kaiser runs zsh as the login shell (SHELL=/bin/fish was misleading — that
|
||||||
|
# comes from sway's inherited env, not the user's actual shell). Hardcode
|
||||||
|
# /usr/bin/zsh here. foot does NOT expand $SHELL in the shell= value (it
|
||||||
|
# passes the literal string to its child), so don't try the sh,-c trick —
|
||||||
|
# it just makes foot spawn a binary literally named "${SHELL:-/bin/bash}"
|
||||||
|
# and exit with "No such file or directory".
|
||||||
|
shell=/usr/bin/zsh
|
||||||
|
|
||||||
|
# PTY
|
||||||
|
# utmphelper is not packaged with foot on this CachyOS build. Leave it unset
|
||||||
|
# to disable utmp logging for foot sessions; harmless and not required.
|
||||||
|
|
||||||
|
# Initial geometry
|
||||||
|
initial-window-size-chars=120x32
|
||||||
|
|
||||||
|
[scrollback]
|
||||||
|
lines=10000
|
||||||
|
indicator-position=relative
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
style=block
|
||||||
|
blink=yes
|
||||||
|
blink-rate=500
|
||||||
|
beam-thickness=2px
|
||||||
|
|
||||||
|
[mouse]
|
||||||
|
hide-when-typing=yes
|
||||||
|
alternate-scroll-mode=true
|
||||||
|
|
||||||
|
[colors-dark]
|
||||||
|
# Gruvbox dark palette (gruvbox-community) — bg0_h / fg / 16 ANSI
|
||||||
|
# https://github.com/gruvbox-community/gruvbox
|
||||||
|
background=1d2021
|
||||||
|
foreground=ebdbb2
|
||||||
|
# Slight transparency — 0.90 alpha. Foot 1.27+ uses a separate alpha key
|
||||||
|
# (in [colors-dark], not 8-digit hex — that was foot 1.24 syntax).
|
||||||
|
alpha=0.90
|
||||||
|
|
||||||
|
# Regular ANSI (0-7)
|
||||||
|
regular0=282828
|
||||||
|
regular1=cc241d
|
||||||
|
regular2=98971a
|
||||||
|
regular3=d79921
|
||||||
|
regular4=458588
|
||||||
|
regular5=b16286
|
||||||
|
regular6=689d6a
|
||||||
|
regular7=a89984
|
||||||
|
|
||||||
|
# Bright ANSI (8-15)
|
||||||
|
bright0=928374
|
||||||
|
bright1=fb4934
|
||||||
|
bright2=b8bb26
|
||||||
|
bright3=fabd2f
|
||||||
|
bright4=83a598
|
||||||
|
bright5=d3869b
|
||||||
|
bright6=8ec07c
|
||||||
|
bright7=ebdbb2
|
||||||
|
|
||||||
|
# Selection (FG BG pair)
|
||||||
|
selection-foreground=1d2021
|
||||||
|
selection-background=ebdbb2
|
||||||
|
# Search box (FG BG pairs)
|
||||||
|
search-box-match=ebdbb2 458588
|
||||||
|
search-box-no-match=ebdbb2 cc241d
|
||||||
|
|
||||||
|
[bell]
|
||||||
|
urgent=no
|
||||||
|
notify=no
|
||||||
|
visual=no
|
||||||
|
|
||||||
|
[url]
|
||||||
|
launch=xdg-open {url}
|
||||||
25
dot_config/foot/patch.py
Normal file
25
dot_config/foot/patch.py
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
from pathlib import Path
|
||||||
|
p = Path("/home/rain/.config/foot/foot.ini")
|
||||||
|
text = p.read_text()
|
||||||
|
old_lines = [
|
||||||
|
"# foot does not expand env variables in the `shell=` value, so we have to",
|
||||||
|
"# go through `sh -c` to make the parent's $SHELL take effect. When foot",
|
||||||
|
"# is launched from a fish session, $SHELL is /bin/fish, and foot runs fish.",
|
||||||
|
"# When launched from bash, $SHELL is /bin/bash, and foot runs bash. The",
|
||||||
|
"# default fallback is /bin/bash if $SHELL is unset for any reason.",
|
||||||
|
'shell=sh,-c,"exec ${SHELL:-/bin/bash} -i"',
|
||||||
|
]
|
||||||
|
new_lines = [
|
||||||
|
"# kaiser runs zsh as the login shell. Hardcode /usr/bin/zsh here.",
|
||||||
|
"# foot does NOT expand $SHELL in shell= (it passes the literal string",
|
||||||
|
"# to its child process), so the sh,-c trick makes foot try to exec a",
|
||||||
|
'# binary literally named "${SHELL:-/bin/bash}" and die with',
|
||||||
|
'# "No such file or directory". Point shell= at the binary directly.',
|
||||||
|
"shell=/usr/bin/zsh",
|
||||||
|
]
|
||||||
|
old = "\n".join(old_lines)
|
||||||
|
new = "\n".join(new_lines)
|
||||||
|
assert old in text, "old block not found in foot.ini"
|
||||||
|
text = text.replace(old, new, 1)
|
||||||
|
p.write_text(text)
|
||||||
|
print("OK, new size:", len(text))
|
||||||
22
dot_config/mako/config
Normal file
22
dot_config/mako/config
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# mako gruvbox-material-dark-hard
|
||||||
|
font=Maple Mono NF 11
|
||||||
|
background-color=#1d2021
|
||||||
|
text-color=#ebdbb2
|
||||||
|
border-size=2
|
||||||
|
border-color=#d79921
|
||||||
|
border-radius=0
|
||||||
|
default-timeout=5000
|
||||||
|
padding=10
|
||||||
|
margin=8
|
||||||
|
width=400
|
||||||
|
|
||||||
|
[urgency=high]
|
||||||
|
border-color=#fb4934
|
||||||
|
default-timeout=0
|
||||||
|
|
||||||
|
[urgency=normal]
|
||||||
|
border-color=#d79921
|
||||||
|
|
||||||
|
[urgency=low]
|
||||||
|
border-color=#504945
|
||||||
|
default-timeout=3000
|
||||||
24
dot_config/sway/caffeine.sh
Executable file
24
dot_config/sway/caffeine.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# caffeine.sh — toggle caffeine mode by killing/restarting swayidle
|
||||||
|
# When ON: kill swayidle (no idle lock/screen-off)
|
||||||
|
# When OFF: restart swayidle with normal timeouts
|
||||||
|
|
||||||
|
WALLPAPER="$HOME/.local/share/wallpapers/teach-invaders-gruvbox.png"
|
||||||
|
FLAG="/tmp/caffeine-inhibit"
|
||||||
|
|
||||||
|
if [ -f "$FLAG" ]; then
|
||||||
|
# Turn OFF caffeine — restart swayidle
|
||||||
|
rm -f "$FLAG"
|
||||||
|
killall swayidle 2>/dev/null
|
||||||
|
swayidle -w \
|
||||||
|
timeout 300 "swaylock -f -i $WALLPAPER" \
|
||||||
|
timeout 600 'swaymsg "output * power off"' \
|
||||||
|
resume 'swaymsg "output * power on"' \
|
||||||
|
before-sleep "swaylock -f -i $WALLPAPER" &
|
||||||
|
notify-send -t 2000 "☕ Caffeine OFF" "Idle sleep enabled" 2>/dev/null
|
||||||
|
else
|
||||||
|
# Turn ON caffeine — kill swayidle
|
||||||
|
touch "$FLAG"
|
||||||
|
killall swayidle 2>/dev/null
|
||||||
|
notify-send -t 2000 "☕ Caffeine ON" "Idle sleep disabled" 2>/dev/null
|
||||||
|
fi
|
||||||
48
dot_config/sway/cheatsheet.md
Normal file
48
dot_config/sway/cheatsheet.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# === sway keybinds cheatsheet ===
|
||||||
|
# generated from ~/.config/sway/config — `Super` = the Windows key (Mod4)
|
||||||
|
# reload this view with: Super + /
|
||||||
|
|
||||||
|
# LAUNCHERS
|
||||||
|
Super+Enter open foot terminal
|
||||||
|
Super+D open wofi app launcher
|
||||||
|
Super+E open thunar (file manager)
|
||||||
|
Super+B open firefox
|
||||||
|
Super+/ show this cheatsheet (in foot, via less)
|
||||||
|
Super+Shift+E exit sway (with prompt)
|
||||||
|
|
||||||
|
# WINDOW MANAGEMENT
|
||||||
|
Super+Q kill focused window
|
||||||
|
Super+F fullscreen toggle
|
||||||
|
Super+V split toggle (vertical <-> horizontal)
|
||||||
|
Super+S stacking layout
|
||||||
|
Super+W tabbed layout
|
||||||
|
Super+Space floating toggle
|
||||||
|
|
||||||
|
# FOCUS / MOVE
|
||||||
|
Super+arrows focus window in direction
|
||||||
|
Super+Shift+arrows move window in direction
|
||||||
|
|
||||||
|
# WORKSPACES
|
||||||
|
Super+1 .. Super+0 switch to workspace N (0 = 10)
|
||||||
|
Super+Tab toggle back to previous workspace
|
||||||
|
Super+Shift+1..0 move focused window to workspace N
|
||||||
|
|
||||||
|
# SCREENSHOTS
|
||||||
|
Print region screenshot to file
|
||||||
|
Super+Print full-screen screenshot to file
|
||||||
|
Super+Shift+S region screenshot to clipboard
|
||||||
|
|
||||||
|
# SCRATCHPAD
|
||||||
|
Super+` toggle dropdown foot (sway scratchpad)
|
||||||
|
|
||||||
|
# RESIZE MODE (Super+R enters, Esc/Enter exits)
|
||||||
|
resize mode:
|
||||||
|
arrows shrink/grow 30px in direction
|
||||||
|
Esc / Enter exit resize mode
|
||||||
|
|
||||||
|
# LOCK / IDLE
|
||||||
|
Ctrl+Alt+L lock now
|
||||||
|
5 min idle auto-lock
|
||||||
|
10 min idle auto screen-off
|
||||||
|
|
||||||
|
# TIP: Super+Shift+C reloads this config without logging out.
|
||||||
4
dot_config/sway/cheatsheet.sh
Executable file
4
dot_config/sway/cheatsheet.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# cheatsheet.sh — opens the sway keybind cheatsheet in a new foot terminal
|
||||||
|
# running less. Press q to quit.
|
||||||
|
exec foot sh -c 'exec less -SRFX "$HOME/.config/sway/cheatsheet.md"'
|
||||||
148
dot_config/sway/config
Normal file
148
dot_config/sway/config
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
# === ~/.config/sway/config ===
|
||||||
|
# MINIMAL — single file, no includes. Tier-1+2+3 in one go.
|
||||||
|
# We can split into includes later once this is proven to boot.
|
||||||
|
|
||||||
|
# === variables ===
|
||||||
|
set $mod Mod4
|
||||||
|
set $term foot
|
||||||
|
set $menu wofi --show drun --insensitive -p "launch"
|
||||||
|
set $browser zen
|
||||||
|
set $fileManager thunar
|
||||||
|
|
||||||
|
# === output / input ===
|
||||||
|
# Gruvbox wallpaper — sway's native bg command manages swaybg lifecycle internally
|
||||||
|
output * bg $HOME/.local/share/wallpapers/teach-invaders-gruvbox.png fill
|
||||||
|
|
||||||
|
# Touchpad: tap-to-click, natural scroll, drag
|
||||||
|
input type:touchpad {
|
||||||
|
tap enabled
|
||||||
|
tap_button_map lrm
|
||||||
|
natural_scroll enabled
|
||||||
|
dwt enabled
|
||||||
|
accel_profile adaptive
|
||||||
|
}
|
||||||
|
|
||||||
|
# === window borders (gruvbox-hard) ===
|
||||||
|
default_border pixel 2
|
||||||
|
default_floating_border pixel 2
|
||||||
|
gaps inner 8
|
||||||
|
gaps outer 4
|
||||||
|
smart_borders on
|
||||||
|
smart_gaps on
|
||||||
|
|
||||||
|
# gruvbox-orange focus border (replaces the default "generic blue")
|
||||||
|
client.focused #d79921 #1d2021 #ebdbb2 #d79921 #d79921
|
||||||
|
client.unfocused #3c3836 #1d2021 #a89984 #3c3836 #3c3836
|
||||||
|
client.focused_inactive #504945 #1d2021 #a89984 #504945 #504945
|
||||||
|
client.urgent #fb4934 #1d2021 #ebdbb2 #fb4934 #fb4934
|
||||||
|
|
||||||
|
# === swaybar (replaced by waybar — keeping as fallback) ===
|
||||||
|
# If waybar isn't installed yet, this provides a basic bar.
|
||||||
|
bar {
|
||||||
|
swaybar_command waybar
|
||||||
|
}
|
||||||
|
|
||||||
|
# === autostart (kept tiny, all stderr silenced) ===
|
||||||
|
# Make user-local themes/icons visible to GTK and Qt
|
||||||
|
exec sh -c 'export XDG_DATA_DIRS="$HOME/.local/share:$HOME/.local/share/flatpak/exports/share:/usr/local/share:/usr/share"; export XDG_DATA_HOME="$HOME/.local/share"; export XDG_CONFIG_HOME="$HOME/.config"; systemctl --user import-environment XDG_DATA_DIRS XDG_DATA_HOME XDG_CONFIG_HOME 2>/dev/null; dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway'
|
||||||
|
exec /usr/libexec/polkit-gnome-authentication-agent-1
|
||||||
|
exec clipmenud
|
||||||
|
exec sh -c 'systemctl --user start xdg-desktop-portal xdg-desktop-portal-wlr 2>/dev/null || true'
|
||||||
|
exec sh -c 'gsettings set org.gnome.desktop.interface gtk-theme Gruvbox-Material-Dark-Hard 2>/dev/null; gsettings set org.gnome.desktop.interface icon-theme Gruvbox-Material-Dark 2>/dev/null; gsettings set org.gnome.desktop.interface color-scheme prefer-dark 2>/dev/null; true'
|
||||||
|
exec gnome-keyring-daemon --start --components=secrets
|
||||||
|
exec mako
|
||||||
|
exec wlsunset -l 39.96 -L -82.99
|
||||||
|
exec sworkstyle
|
||||||
|
|
||||||
|
# === idle / lock ===
|
||||||
|
exec swayidle -w \
|
||||||
|
timeout 300 '$HOME/.config/sway/lock-fancy.sh' \
|
||||||
|
timeout 600 'swaymsg "output * power off"' \
|
||||||
|
resume 'swaymsg "output * power on"' \
|
||||||
|
before-sleep '$HOME/.config/sway/lock-fancy.sh'
|
||||||
|
|
||||||
|
# === keybinds ===
|
||||||
|
bindsym $mod+Return exec $term
|
||||||
|
bindsym $mod+d exec $menu
|
||||||
|
bindsym $mod+e exec $fileManager
|
||||||
|
bindsym $mod+b exec $browser
|
||||||
|
bindsym $mod+q kill
|
||||||
|
bindsym $mod+Shift+c reload
|
||||||
|
bindsym Ctrl+Alt+l exec $HOME/.config/sway/lock-fancy.sh
|
||||||
|
bindsym $mod+slash exec $HOME/.config/sway/cheatsheet.sh
|
||||||
|
bindsym $mod+question exec $HOME/.config/sway/cheatsheet.sh
|
||||||
|
bindsym $mod+Shift+e exec swaynag -t warning -m 'Exit Sway?' -B 'Yes, exit Sway' 'swaymsg exit'
|
||||||
|
|
||||||
|
bindsym $mod+Left focus left
|
||||||
|
bindsym $mod+Down focus down
|
||||||
|
bindsym $mod+Up focus up
|
||||||
|
bindsym $mod+Right focus right
|
||||||
|
bindsym $mod+Shift+Left move left
|
||||||
|
bindsym $mod+Shift+Down move down
|
||||||
|
bindsym $mod+Shift+Up move up
|
||||||
|
bindsym $mod+Shift+Right move right
|
||||||
|
|
||||||
|
bindsym $mod+1 workspace number 1
|
||||||
|
bindsym $mod+2 workspace number 2
|
||||||
|
bindsym $mod+3 workspace number 3
|
||||||
|
bindsym $mod+4 workspace number 4
|
||||||
|
bindsym $mod+5 workspace number 5
|
||||||
|
bindsym $mod+6 workspace number 6
|
||||||
|
bindsym $mod+7 workspace number 7
|
||||||
|
bindsym $mod+8 workspace number 8
|
||||||
|
bindsym $mod+9 workspace number 9
|
||||||
|
bindsym $mod+0 workspace number 10
|
||||||
|
bindsym $mod+Tab workspace back_and_forth
|
||||||
|
bindsym $mod+Shift+1 move container to workspace number 1
|
||||||
|
bindsym $mod+Shift+2 move container to workspace number 2
|
||||||
|
bindsym $mod+Shift+3 move container to workspace number 3
|
||||||
|
bindsym $mod+Shift+4 move container to workspace number 4
|
||||||
|
bindsym $mod+Shift+5 move container to workspace number 5
|
||||||
|
bindsym $mod+Shift+6 move container to workspace number 6
|
||||||
|
bindsym $mod+Shift+7 move container to workspace number 7
|
||||||
|
bindsym $mod+Shift+8 move container to workspace number 8
|
||||||
|
bindsym $mod+Shift+9 move container to workspace number 9
|
||||||
|
bindsym $mod+Shift+0 move container to workspace number 10
|
||||||
|
|
||||||
|
bindsym $mod+f fullscreen
|
||||||
|
bindsym $mod+v split toggle splitv
|
||||||
|
bindsym $mod+s layout stacking
|
||||||
|
bindsym $mod+w layout tabbed
|
||||||
|
bindsym $mod+space exec $menu
|
||||||
|
bindsym $mod+Shift+space floating toggle
|
||||||
|
|
||||||
|
bindsym Print exec grim -g "$(slurp)" ~/Pictures/screenshot-$(date +%Y%m%d-%H%M%S).png
|
||||||
|
bindsym $mod+Print exec grim ~/Pictures/screenshot-$(date +%Y%m%d-%H%M%S).png
|
||||||
|
bindsym $mod+Shift+s exec grim -g "$(slurp)" - | wl-copy
|
||||||
|
|
||||||
|
mode "resize" {
|
||||||
|
bindsym Left resize shrink width 30px
|
||||||
|
bindsym Down resize grow height 30px
|
||||||
|
bindsym Up resize shrink height 30px
|
||||||
|
bindsym Right resize grow width 30px
|
||||||
|
bindsym Escape mode "default"
|
||||||
|
bindsym Return mode "default"
|
||||||
|
}
|
||||||
|
bindsym $mod+r mode "resize"
|
||||||
|
|
||||||
|
# === F12 dropdown terminal ===
|
||||||
|
# F12 opens a floating foot. Uses -a dropdown so for_window only floats
|
||||||
|
# the dropdown, not regular foot windows from Super+Enter.
|
||||||
|
# Close it with Super+Q or Ctrl+D.
|
||||||
|
bindsym F12 exec foot -a dropdown
|
||||||
|
bindsym $mod+grave exec foot -a dropdown
|
||||||
|
for_window [app_id="dropdown"] floating enable, sticky enable, resize set width 1100 height 600, move position center
|
||||||
|
|
||||||
|
# === media keys ===
|
||||||
|
bindsym --locked XF86AudioRaiseVolume exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
||||||
|
bindsym --locked XF86AudioLowerVolume exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||||
|
bindsym --locked XF86AudioMute exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||||
|
bindsym --locked XF86AudioMicMute exec wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||||
|
bindsym --locked XF86AudioPlay exec playerctl play-pause 2>/dev/null || true
|
||||||
|
bindsym --locked XF86AudioNext exec playerctl next 2>/dev/null || true
|
||||||
|
bindsym --locked XF86AudioPrev exec playerctl previous 2>/dev/null || true
|
||||||
|
bindsym --locked XF86MonBrightnessUp exec sh -c 'echo $(( $(cat /sys/class/backlight/acpi_video0/brightness) + 1 > $(cat /sys/class/backlight/acpi_video0/max_brightness) ? $(cat /sys/class/backlight/acpi_video0/max_brightness) : $(cat /sys/class/backlight/acpi_video0/brightness) + 1 )) | sudo tee /sys/class/backlight/acpi_video0/brightness'
|
||||||
|
bindsym --locked XF86MonBrightnessDown exec sh -c 'echo $(( $(cat /sys/class/backlight/acpi_video0/brightness) - 1 < 0 ? 0 : $(cat /sys/class/backlight/acpi_video0/brightness) - 1 )) | sudo tee /sys/class/backlight/acpi_video0/brightness'
|
||||||
|
|
||||||
|
# pointer / mouse — the gruvbox-material-gtk repo doesn't ship an xcursor theme,
|
||||||
|
# so leave the default alone. (Cursor shows fine on the default theme.)
|
||||||
18
dot_config/sway/config.d/00-gruvbox.conf
Normal file
18
dot_config/sway/config.d/00-gruvbox.conf
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# === ~/.config/sway/config.d/00-gruvbox.conf ===
|
||||||
|
# gruvbox material dark hard — wired through gsettings so Thunar, Firefox chrome,
|
||||||
|
# and any GTK3/4 app pick it up the moment sway starts.
|
||||||
|
|
||||||
|
# Run gsettings in a sh -c wrapper so we can pipe stderr to /dev/null.
|
||||||
|
# This is necessary because the very first exec block runs before dbus is
|
||||||
|
# always reachable, and gsettings prints a long bar-warning to stderr when
|
||||||
|
# it can't find the bus. We don't want the red bar to surface that.
|
||||||
|
exec_always {
|
||||||
|
gsettings set org.gnome.desktop.interface gtk-theme 'Gruvbox-Material-Dark-Hard' 2>/dev/null
|
||||||
|
gsettings set org.gnome.desktop.interface icon-theme 'Gruvbox-Material-Dark' 2>/dev/null
|
||||||
|
gsettings set org.gnome.desktop.interface cursor-theme 'Gruvbox-Material-Dark' 2>/dev/null
|
||||||
|
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' 2>/dev/null
|
||||||
|
gsettings set org.cinnamon.desktop.interface gtk-theme 'Gruvbox-Material-Dark-Hard' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# gnome-keyring (in case any GTK app needs secret service for ssh-agent bridge)
|
||||||
|
exec gnome-keyring-daemon --start --components=secrets
|
||||||
76
dot_config/sway/config.d/10-keybinds.conf
Normal file
76
dot_config/sway/config.d/10-keybinds.conf
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
# === ~/.config/sway/config.d/10-keybinds.conf ===
|
||||||
|
# sway keybindings. Mint+Cinnamon muscle memory → Super (Mod4).
|
||||||
|
|
||||||
|
# === essentials ===
|
||||||
|
bindsym $mod+Return exec $term
|
||||||
|
bindsym $mod+d exec $menu
|
||||||
|
bindsym $mod+e exec $fileManager
|
||||||
|
bindsym $mod+b exec $browser
|
||||||
|
bindsym $mod+q kill
|
||||||
|
bindsym $mod+Shift+c reload
|
||||||
|
bindsym $mod+Shift+e exec swaynag -t warning \
|
||||||
|
-m 'Exit Sway?' \
|
||||||
|
-B 'Yes, exit Sway' 'swaymsg exit'
|
||||||
|
|
||||||
|
# === move focus ===
|
||||||
|
bindsym $mod+Left focus left
|
||||||
|
bindsym $mod+Down focus down
|
||||||
|
bindsym $mod+Up focus up
|
||||||
|
bindsym $mod+Right focus right
|
||||||
|
bindsym $mod+Shift+Left move left
|
||||||
|
bindsym $mod+Shift+Down move down
|
||||||
|
bindsym $mod+Shift+Up move up
|
||||||
|
bindsym $mod+Shift+Right move right
|
||||||
|
|
||||||
|
# === workspace navigation ===
|
||||||
|
bindsym $mod+1 workspace number 1
|
||||||
|
bindsym $mod+2 workspace number 2
|
||||||
|
bindsym $mod+3 workspace number 3
|
||||||
|
bindsym $mod+4 workspace number 4
|
||||||
|
bindsym $mod+5 workspace number 5
|
||||||
|
bindsym $mod+6 workspace number 6
|
||||||
|
bindsym $mod+7 workspace number 7
|
||||||
|
bindsym $mod+8 workspace number 8
|
||||||
|
bindsym $mod+9 workspace number 9
|
||||||
|
bindsym $mod+0 workspace number 10
|
||||||
|
bindsym $mod+Tab workspace back_and_forth
|
||||||
|
bindsym $mod+Shift+1 move container to workspace number 1
|
||||||
|
bindsym $mod+Shift+2 move container to workspace number 2
|
||||||
|
bindsym $mod+Shift+3 move container to workspace number 3
|
||||||
|
bindsym $mod+Shift+4 move container to workspace number 4
|
||||||
|
bindsym $mod+Shift+5 move container to workspace number 5
|
||||||
|
bindsym $mod+Shift+6 move container to workspace number 6
|
||||||
|
bindsym $mod+Shift+7 move container to workspace number 7
|
||||||
|
bindsym $mod+Shift+8 move container to workspace number 8
|
||||||
|
bindsym $mod+Shift+9 move container to workspace number 9
|
||||||
|
bindsym $mod+Shift+0 move container to workspace number 10
|
||||||
|
|
||||||
|
# === layout ===
|
||||||
|
bindsym $mod+f fullscreen
|
||||||
|
bindsym $mod+v split toggle splitv
|
||||||
|
bindsym $mod+s layout stacking
|
||||||
|
bindsym $mod+w layout tabbed
|
||||||
|
bindsym $mod+space floating toggle
|
||||||
|
bindsym $mod+Shift+space focus mode_toggle
|
||||||
|
|
||||||
|
# === screenshot (grim + slurp) ===
|
||||||
|
bindsym Print exec grim -g "$(slurp)" ~/Pictures/screenshot-$(date +%Y%m%d-%H%M%S).png
|
||||||
|
bindsym $mod+Print exec grim ~/Pictures/screenshot-$(date +%Y%m%d-%H%M%S).png
|
||||||
|
bindsym $mod+Shift+s exec grim -g "$(slurp)" - | wl-copy
|
||||||
|
|
||||||
|
# === resize ===
|
||||||
|
mode "resize" {
|
||||||
|
bindsym Left resize shrink width 30px
|
||||||
|
bindsym Down resize grow height 30px
|
||||||
|
bindsym Up resize shrink height 30px
|
||||||
|
bindsym Right resize grow width 30px
|
||||||
|
bindsym Escape mode "default"
|
||||||
|
bindsym Return mode "default"
|
||||||
|
}
|
||||||
|
bindsym $mod+r mode "resize"
|
||||||
|
|
||||||
|
# === scratchpads (quick terminal / browser) ===
|
||||||
|
# Start a headless foot server, then a dropdown client window. Toggle with $mod+grave.
|
||||||
|
bindsym $mod+grave exec foot --server
|
||||||
|
bindsym $mod+apostrophe exec foot -a dropdown
|
||||||
|
for_window [app_id="dropdown"] floating enable, sticky enable, resize set width 1100 height 600, move position center
|
||||||
15
dot_config/sway/config.d/20-autostart.conf
Normal file
15
dot_config/sway/config.d/20-autostart.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# === ~/.config/sway/config.d/20-autostart.conf ===
|
||||||
|
# background services started when sway comes up.
|
||||||
|
|
||||||
|
# polkit agent — needed for gparted, mount UIs in thunar, etc.
|
||||||
|
exec /usr/libexec/polkit-gnome-authentication-agent-1
|
||||||
|
|
||||||
|
# clipboard — start clipmenud directly (it watches the clipboard internally)
|
||||||
|
# Drop the wl-paste --watch wrapper to avoid bar noise if the socket isn't ready.
|
||||||
|
exec clipmenud
|
||||||
|
|
||||||
|
# xdg-desktop-portal — required for native file/screen sharing in Firefox/Chromium.
|
||||||
|
# Skip if services aren't enabled; the user can enable with:
|
||||||
|
# systemctl --user enable --now xdg-desktop-portal xdg-desktop-portal-wlr
|
||||||
|
# Until then, those systemctl lines are quiet no-ops.
|
||||||
|
exec sh -c 'systemctl --user start xdg-desktop-portal xdg-desktop-portal-wlr 2>/dev/null || true'
|
||||||
17
dot_config/sway/config.d/50-launchers.conf
Normal file
17
dot_config/sway/config.d/50-launchers.conf
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# ~/.config/sway/config.d/50-launchers.conf
|
||||||
|
# Launcher keybinds. The base $menu var in config is the drun launcher.
|
||||||
|
# These add run mode, window switcher, and the powermenu.
|
||||||
|
|
||||||
|
# $mod+grave already used by foot dropdown — don't clobber.
|
||||||
|
# $mod+Tab already used by workspace back_and_forth — don't clobber.
|
||||||
|
# $mod+slash is the cheatsheet — keep it.
|
||||||
|
|
||||||
|
# Exec ad-hoc command (not in $PATH discovery)
|
||||||
|
bindsym $mod+F12 exec wofi --show run --prompt "exec"
|
||||||
|
|
||||||
|
# Sway window switcher (replaces `swayr`-style overview)
|
||||||
|
bindsym $mod+F11 exec wofi --show window
|
||||||
|
|
||||||
|
# Power menu — dmenu mode driven by wofi-powermenu script.
|
||||||
|
# wofi has no custom-mode feature; the script does the dispatch.
|
||||||
|
bindsym $mod+Escape exec $HOME/.local/bin/wofi-powermenu
|
||||||
34
dot_config/sway/lock-fancy.sh
Executable file
34
dot_config/sway/lock-fancy.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# lock-fancy.sh — fancy swaylock: snapshot the screen, dim+blur it, and use as background.
|
||||||
|
# grim + ffmpeg (both already installed). No swaylock-effects overlay needed.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMP=/tmp/lock-bg-483833.png
|
||||||
|
DIM=/tmp/lock-bg-dim-483833.png
|
||||||
|
|
||||||
|
# Snapshot the current screen
|
||||||
|
grim -t png "$TMP" 2>/dev/null
|
||||||
|
|
||||||
|
# Dim + blur via ffmpeg (much faster than ImageMagick)
|
||||||
|
if [ -f "$TMP" ] && command -v ffmpeg >/dev/null; then
|
||||||
|
ffmpeg -loglevel error -y -i "$TMP" -vf "boxblur=12:1,eq=brightness=-0.30:saturation=0.6" -frames:v 1 "$DIM"
|
||||||
|
IMG="$DIM"
|
||||||
|
else
|
||||||
|
# Fallback to the regular wallpaper
|
||||||
|
IMG="$HOME/.local/share/wallpapers/teach-invaders-gruvbox.png"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Launch swaylock
|
||||||
|
swaylock -f -i "$IMG" \
|
||||||
|
--indicator-radius 100 \
|
||||||
|
--indicator-thickness 6 \
|
||||||
|
--ring-color ebdbb2 \
|
||||||
|
--inside-color 1d202180 \
|
||||||
|
--key-hl-color fe8019 \
|
||||||
|
--bs-hl-color fb4934 \
|
||||||
|
--text-color ebdbb2 \
|
||||||
|
--separator-color 00000000 \
|
||||||
|
--fade-in 0.3
|
||||||
|
|
||||||
|
rm -f "$TMP" "$DIM" 2>/dev/null
|
||||||
58
dot_config/sway/toggle-dropdown.sh
Executable file
58
dot_config/sway/toggle-dropdown.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# toggle-dropdown.sh — toggle the dropdown foot terminal
|
||||||
|
# Writes debug info to /tmp/sway-f12.log so we can diagnose from SSH
|
||||||
|
|
||||||
|
LOG=/tmp/sway-f12.log
|
||||||
|
echo "=== $(date) F12/Super+grave pressed ===" >> "$LOG"
|
||||||
|
echo "WAYLAND_DISPLAY=$WAYLAND_DISPLAY" >> "$LOG"
|
||||||
|
echo "USER=$USER XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" >> "$LOG"
|
||||||
|
|
||||||
|
# Find the sway socket
|
||||||
|
SOCK=$(ls -t /run/user/$(id -u)/sway-ipc.*.sock 2>/dev/null | head -1)
|
||||||
|
echo "SOCK=$SOCK" >> "$LOG"
|
||||||
|
|
||||||
|
if [ -z "$SOCK" ]; then
|
||||||
|
echo "ERROR: no sway socket found" >> "$LOG"
|
||||||
|
notify-send -t 2000 "sway: no IPC socket" 2>>"$LOG" || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if a foot window is in the scratchpad (hidden)
|
||||||
|
HIDDEN=$(SWAYSOCK=$SOCK swaymsg -t get_tree 2>>"$LOG" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
try:
|
||||||
|
tree = json.load(sys.stdin)
|
||||||
|
def find_app(node, app_id):
|
||||||
|
if node.get('app_id') == app_id and node.get('name', '').startswith('__i3'):
|
||||||
|
return node
|
||||||
|
for c in node.get('nodes', []) + node.get('floating_nodes', []):
|
||||||
|
r = find_app(c, app_id)
|
||||||
|
if r is not None:
|
||||||
|
return r
|
||||||
|
return None
|
||||||
|
dd = find_app(tree, 'foot')
|
||||||
|
print('hidden' if dd is not None else 'none')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'err:{e}')
|
||||||
|
" 2>>"$LOG")
|
||||||
|
|
||||||
|
echo "HIDDEN=$HIDDEN" >> "$LOG"
|
||||||
|
|
||||||
|
if [ "$HIDDEN" = "hidden" ]; then
|
||||||
|
SWAYSOCK=$SOCK swaymsg '[app_id="foot"] scratchpad show' >>"$LOG" 2>&1
|
||||||
|
echo "toggled: scratchpad show" >> "$LOG"
|
||||||
|
else
|
||||||
|
# Spawn a new foot. Pass through WAYLAND_DISPLAY explicitly.
|
||||||
|
if [ -n "$WAYLAND_DISPLAY" ]; then
|
||||||
|
WAYLAND_DISPLAY=$WAYLAND_DISPLAY foot >>"$LOG" 2>&1 &
|
||||||
|
else
|
||||||
|
# try to find wayland-1 socket
|
||||||
|
if [ -S "/run/user/$(id -u)/wayland-1" ]; then
|
||||||
|
WAYLAND_DISPLAY=wayland-1 foot >>"$LOG" 2>&1 &
|
||||||
|
else
|
||||||
|
foot >>"$LOG" 2>&1 &
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "spawned foot" >> "$LOG"
|
||||||
|
fi
|
||||||
|
echo "=== done ===" >> "$LOG"
|
||||||
29
dot_config/sway/wifi-menu.sh
Executable file
29
dot_config/sway/wifi-menu.sh
Executable file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# wifi-menu.sh — wofi-based WiFi network picker using nmcli
|
||||||
|
# Lists available networks, connects on selection.
|
||||||
|
|
||||||
|
# Get list of networks: SSID, signal, security
|
||||||
|
SELECTED=$(nmcli -t -f SSID,SIGNAL,SECURITY device wifi list --rescan yes 2>/dev/null | \
|
||||||
|
grep -v '^$' | \
|
||||||
|
sort -t: -k2 -nr | \
|
||||||
|
awk -F: '{
|
||||||
|
sig = $2 + 0
|
||||||
|
if (sig > 75) bars = "████"
|
||||||
|
else if (sig > 50) bars = "███░"
|
||||||
|
else if (sig > 25) bars = "██░░"
|
||||||
|
else bars = "█░░░"
|
||||||
|
sec = ($3 != "" && $3 != "--") ? " " : ""
|
||||||
|
printf "%s %s%s\n", bars, $1, sec
|
||||||
|
}' | \
|
||||||
|
wofi --dmenu --insensitive --prompt "WiFi" -W 400 -H 500 2>/dev/null)
|
||||||
|
|
||||||
|
# Exit if nothing selected
|
||||||
|
[ -z "$SELECTED" ] && exit 0
|
||||||
|
|
||||||
|
# Extract SSID (everything after the signal bars + spaces)
|
||||||
|
SSID=$(echo "$SELECTED" | sed 's/^[█░ ]* //; s/ 🔒$//')
|
||||||
|
|
||||||
|
# Connect
|
||||||
|
nmcli device wifi connect "$SSID" 2>&1 | grep -q "successfully" && \
|
||||||
|
notify-send -t 3000 "WiFi" "Connected to $SSID" || \
|
||||||
|
notify-send -t 5000 "WiFi" "Failed to connect to $SSID"
|
||||||
102
dot_config/waybar/config
Normal file
102
dot_config/waybar/config
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
{
|
||||||
|
"layer": "top",
|
||||||
|
"position": "top",
|
||||||
|
"height": 32,
|
||||||
|
"spacing": 0,
|
||||||
|
"modules-left": [
|
||||||
|
"sway/workspaces",
|
||||||
|
"sway/mode"
|
||||||
|
],
|
||||||
|
"modules-center": [
|
||||||
|
"clock",
|
||||||
|
"custom/caffeine"
|
||||||
|
],
|
||||||
|
"modules-right": [
|
||||||
|
"pulseaudio",
|
||||||
|
"battery",
|
||||||
|
"cpu",
|
||||||
|
"memory",
|
||||||
|
"tray",
|
||||||
|
"network"
|
||||||
|
],
|
||||||
|
"sway/workspaces": {
|
||||||
|
"disable-scroll": true,
|
||||||
|
"format": "{name}",
|
||||||
|
"format-icons": {
|
||||||
|
"focused": "\u25cf",
|
||||||
|
"default": "\u25cb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
"format": " {:%a %b %d %H:%M}",
|
||||||
|
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
|
||||||
|
"format-alt": " {:%Y-%m-%d}"
|
||||||
|
},
|
||||||
|
"pulseaudio": {
|
||||||
|
"format": "{icon} {volume}%",
|
||||||
|
"format-muted": "\udb81\udd81 muted",
|
||||||
|
"format-icons": {
|
||||||
|
"default": [
|
||||||
|
"\udb81\udd7f",
|
||||||
|
"\udb81\udd80",
|
||||||
|
"\udb81\udd7e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scroll-step": 5,
|
||||||
|
"on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle",
|
||||||
|
"on-click-right": "pavucontrol"
|
||||||
|
},
|
||||||
|
"battery": {
|
||||||
|
"states": {
|
||||||
|
"good": 80,
|
||||||
|
"warning": 30,
|
||||||
|
"critical": 15
|
||||||
|
},
|
||||||
|
"format": "{icon} {capacity}%",
|
||||||
|
"format-charging": "\udb80\udc84 {capacity}%",
|
||||||
|
"format-plugged": "\udb80\udc84 {capacity}%",
|
||||||
|
"format-icons": [
|
||||||
|
"\udb80\udc8e",
|
||||||
|
"\udb80\udc7a",
|
||||||
|
"\udb80\udc7b",
|
||||||
|
"\udb80\udc7c",
|
||||||
|
"\udb80\udc7d",
|
||||||
|
"\udb80\udc7e",
|
||||||
|
"\udb80\udc7f",
|
||||||
|
"\udb80\udc80",
|
||||||
|
"\udb80\udc81",
|
||||||
|
"\udb80\udc82",
|
||||||
|
"\udb80\udc79"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cpu": {
|
||||||
|
"format": "\udb83\udee0 {usage}%",
|
||||||
|
"tooltip": true
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"format": "\udb80\udf5b {}%",
|
||||||
|
"tooltip-format": "{used:0.1f}G / {total:0.1f}G"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"format-wifi": "\udb82\udd28 {essid}",
|
||||||
|
"format-ethernet": "\udb80\ude00 {ipaddr}",
|
||||||
|
"format-disconnected": "\udb82\udd2d disconnected",
|
||||||
|
"format-linked": "\udb82\udd2a {ifname}",
|
||||||
|
"tooltip-format": "{ifname} \u2014 {ipaddr}",
|
||||||
|
"on-click": "$HOME/.config/sway/wifi-menu.sh"
|
||||||
|
},
|
||||||
|
"custom/caffeine": {
|
||||||
|
"format": "{icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"default": "\udb80\udd76",
|
||||||
|
"active": "\u2615"
|
||||||
|
},
|
||||||
|
"exec": "if [ -f /tmp/caffeine-inhibit ]; then echo '{\"alt\":\"active\",\"text\":\"caffeine\"}'; else echo '{\"alt\":\"default\",\"text\":\"caffeine\"}'; fi",
|
||||||
|
"exec-interval": 2,
|
||||||
|
"return-type": "json",
|
||||||
|
"on-click": "$HOME/.config/sway/caffeine.sh"
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
"spacing": 8
|
||||||
|
}
|
||||||
|
}
|
||||||
92
dot_config/waybar/style.css
Normal file
92
dot_config/waybar/style.css
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
/* === waybar — gruvbox-material-dark-hard, polished === */
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: "Maple Mono NF";
|
||||||
|
font-size: 14px;
|
||||||
|
min-height: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* transparent bar so the desktop bleeds through at the edges */
|
||||||
|
window#waybar {
|
||||||
|
background-color: rgba(29, 32, 33, 0.92);
|
||||||
|
color: #ebdbb2;
|
||||||
|
border-bottom: 1px solid #3c3836;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.hidden { opacity: 0.2; }
|
||||||
|
|
||||||
|
/* workspaces */
|
||||||
|
#workspaces button {
|
||||||
|
padding: 0 12px;
|
||||||
|
background: transparent;
|
||||||
|
color: #a89984;
|
||||||
|
box-shadow: inset 0 -2px transparent;
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
#workspaces button:hover {
|
||||||
|
background: #3c3836;
|
||||||
|
color: #ebdbb2;
|
||||||
|
}
|
||||||
|
#workspaces button.focused {
|
||||||
|
color: #fabd2f;
|
||||||
|
box-shadow: inset 0 -2px #fabd2f;
|
||||||
|
}
|
||||||
|
#workspaces button.urgent {
|
||||||
|
color: #fb4934;
|
||||||
|
animation: blink 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mode {
|
||||||
|
color: #fb4934;
|
||||||
|
background: #282828;
|
||||||
|
padding: 0 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock {
|
||||||
|
color: #ebdbb2;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-left: 1px solid #3c3836;
|
||||||
|
border-right: 1px solid #3c3836;
|
||||||
|
}
|
||||||
|
#clock:hover { color: #fabd2f; }
|
||||||
|
|
||||||
|
/* right-side modules — shared layout, individual color */
|
||||||
|
#pulseaudio, #battery, #cpu, #memory, #network, #tray, #custom-caffeine {
|
||||||
|
padding: 0 12px;
|
||||||
|
border-left: 1px solid #3c3836;
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
#pulseaudio:hover, #battery:hover, #cpu:hover, #memory:hover, #network:hover, #tray:hover, #custom-caffeine:hover {
|
||||||
|
background: #3c3836;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio { color: #b8bb26; }
|
||||||
|
#pulseaudio.muted { color: #928374; }
|
||||||
|
#battery { color: #d79921; }
|
||||||
|
#battery.charging { color: #b8bb26; }
|
||||||
|
#battery.good { color: #b8bb26; }
|
||||||
|
#battery.warning { color: #fe8019; }
|
||||||
|
#battery.critical {
|
||||||
|
color: #fb4934;
|
||||||
|
animation: blink 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
#cpu { color: #83a598; }
|
||||||
|
#memory { color: #d3869b; }
|
||||||
|
#network { color: #fabd2f; }
|
||||||
|
#network.disconnected { color: #fb4934; }
|
||||||
|
#tray { padding: 0 10px; }
|
||||||
|
|
||||||
|
#custom-caffeine { color: #a89984; }
|
||||||
|
#custom-caffeine.active { color: #fabd2f; }
|
||||||
|
#custom-caffeine.active:hover { background: #3c3836; }
|
||||||
|
|
||||||
|
#sway-workspaces { margin: 0 4px; }
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
to { opacity: 0.3; }
|
||||||
|
}
|
||||||
19
dot_config/wofi/config
Normal file
19
dot_config/wofi/config
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# ~/.config/wofi/config — gruvbox launcher defaults
|
||||||
|
# Loaded by wofi before style.css. CLI flags still win.
|
||||||
|
|
||||||
|
[window]
|
||||||
|
location=top
|
||||||
|
width=620
|
||||||
|
height=420
|
||||||
|
|
||||||
|
[prompt]
|
||||||
|
prompt=go
|
||||||
|
insensitive=true
|
||||||
|
|
||||||
|
[search]
|
||||||
|
matching=fuzzy
|
||||||
|
sort_order=default
|
||||||
|
|
||||||
|
[keybindings]
|
||||||
|
return=activate
|
||||||
|
escape=close
|
||||||
12
dot_config/wofi/powermenu.config
Normal file
12
dot_config/wofi/powermenu.config
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# ~/.config/wofi/powermenu.config — plain INI, not rasi
|
||||||
|
# wofi's config format is INI. There is no rasi-style `configuration { }`
|
||||||
|
# block. The icon theme comes from gsettings / dconf, not from here.
|
||||||
|
|
||||||
|
location=top
|
||||||
|
yoffset=32
|
||||||
|
width=420
|
||||||
|
height=280
|
||||||
|
prompt=power
|
||||||
|
insensitive=true
|
||||||
|
hide_scroll=true
|
||||||
|
matching=exact
|
||||||
57
dot_config/wofi/style.css
Normal file
57
dot_config/wofi/style.css
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* wofi gruvbox-material-dark-hard — extended rice */
|
||||||
|
window {
|
||||||
|
margin: 0px;
|
||||||
|
border: 2px solid #d79921;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #1d2021;
|
||||||
|
background-image: linear-gradient(to bottom, #1d2021, #282828);
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
|
||||||
|
font-family: "Maple Mono NF";
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px 10px 0 0;
|
||||||
|
color: #ebdbb2;
|
||||||
|
background-color: #282828;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inner-box {
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#outer-box {
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#scroll {
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border: none;
|
||||||
|
color: #ebdbb2;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entry {
|
||||||
|
transition: background-color 120ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entry:selected {
|
||||||
|
background-color: #3c3836;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entry:selected #text {
|
||||||
|
color: #fabd2f;
|
||||||
|
}
|
||||||
58
run_once_40-install-sway.sh.tmpl
Normal file
58
run_once_40-install-sway.sh.tmpl
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# =============================================================================
|
||||||
|
# run_once_40-install-sway.sh.tmpl
|
||||||
|
# Install the sway + wofi + foot + supporting tooling desktop stack.
|
||||||
|
#
|
||||||
|
# Gated on .sway (set in .chezmoi.yaml.tmpl). When false (Pis, headless
|
||||||
|
# boxes, etc.), this script exits 0 without doing anything.
|
||||||
|
#
|
||||||
|
# To opt a new box in: `touch ~/.config/chezmoi/features/sway` then
|
||||||
|
# `chezmoi apply`. To opt out: `touch ~/.config/chezmoi/features/no-sway`.
|
||||||
|
#
|
||||||
|
# Idempotent: skips if sway is already installed.
|
||||||
|
# =============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
log() { printf '\033[1;34m[sway]\033[0m %s\n' "$*"; }
|
||||||
|
|
||||||
|
# --- 0. Gate on the .sway flag ---
|
||||||
|
{{ if not .sway -}}
|
||||||
|
log "sway not enabled for this host (.sway=false). Skipping."
|
||||||
|
log "To enable: touch ~/.config/chezmoi/features/sway && chezmoi apply"
|
||||||
|
exit 0
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
# --- 1. Install packages ---
|
||||||
|
SWAY_PKGS=(sway wofi foot swaybg swaylock swayidle grim slurp waybar wl-clipboard)
|
||||||
|
|
||||||
|
{{ if eq .os_family "arch" -}}
|
||||||
|
# mako is in arch [extra]
|
||||||
|
SWAY_PKGS+=(mako)
|
||||||
|
{{ else if eq .os_family "debian" -}}
|
||||||
|
# mako isn't packaged on debian. Use dunst (lightweight notification daemon,
|
||||||
|
# widely compatible with sway/waybar setups).
|
||||||
|
SWAY_PKGS+=(dunst)
|
||||||
|
{{ else -}}
|
||||||
|
log "WARNING: sway packages not configured for os_family={{ .os_family }}"
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
log "installing sway stack: ${SWAY_PKGS[*]}"
|
||||||
|
|
||||||
|
{{ if eq .os_family "arch" -}}
|
||||||
|
sudo pacman -S --needed --noconfirm "${SWAY_PKGS[@]}"
|
||||||
|
{{ else if eq .os_family "debian" -}}
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
sudo apt-get install -y --no-install-recommends "${SWAY_PKGS[@]}"
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
log "sway stack installed"
|
||||||
|
sway --version 2>&1 | head -1
|
||||||
|
foot --version 2>&1 | head -1
|
||||||
|
wofi --version 2>&1 | head -1
|
||||||
|
|
||||||
|
# --- 2. Mark the box so subsequent chezmoi applies know sway is enabled ---
|
||||||
|
mkdir -p ~/.config/chezmoi/features
|
||||||
|
touch ~/.config/chezmoi/features/sway
|
||||||
|
log "marked box: ~/.config/chezmoi/features/sway"
|
||||||
|
|
||||||
|
log "sway stack install complete"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue