Nimbin[12]?Sway / SwBr / config.advanced.example

SwBr git · main

SwBr - status bar for sway

sway wayland c bar · first commit 2026-08-27 · last commit 2026-10-05 (4 days ago) · synced 3 days ago · upstream: github.com/nimbin2/SwBr

C 95.9% Markdown 3.7%
git clone https://git.christianimmanuel.de/sway/SwBr.gitwget https://git.christianimmanuel.de/sway/SwBr/archive/SwBr.tar.gz
config.advanced.example 22 KB · 421 lines raw
# SwBr config  —  ~/.config/swbr/config
# One key=value per line. '#' starts a comment. Blank lines are ignored.
# Every key here also works on the command line (key=value or --key=value);
# command-line values win over the file. See `swbr --help` for the list.
#
# Inline comments after a value are stripped, but a '#' inside quotes is not,
# so foreground="#19cb00" inside a command is safe.
#
# All sizes are LOGICAL pixels: swbr multiplies them by the output scale,
# so the bar keeps its size on a HiDPI screen. ui_scale scales the text on
# top of that, and height=0 derives the height from the font.

# --- placement ---
layer=top          # background | bottom | top | overlay
                   # top floats above tiled windows but below fullscreen ones;
                   # overlay stays above fullscreen too
position=top       # top | bottom
height=0           # 0 = derive from the font size
exclusive=0        # 0 = float above the windows, they keep the whole screen
                   # 1 = reserve the space, windows tile below the bar
margin=0           # gap to the screen edge
side_margin=0      # gap left and right
min_width=800      # 0 = span the whole output. Otherwise the bar floats and
                   # sizes itself to its content: never narrower than this,
                   # never wider than the screen. Cells appearing (charging,
                   # docker) grow it instead of being cut off
shrink_px=24       # it grows at once but ignores getting narrower by less than
                   # this, so 99% -> 100% or a temperature losing a digit does
                   # not move the whole (centred) bar
shrink_s=30        # a bigger narrowing has to hold this long first
align_x=center     # where the floating bar sits: center | left | right
radius=10          # corner radius. The two corners that touch the screen edge
                   # stay square, so the bar sits flush against it
outputs=           # comma separated output names, empty = one bar per output

# --- workspaces ---
ws_names=0         # 0 = number only ("3" out of "3:web"), 1 = the full name
ws_pad=11
ws_gap=4
ws_min_w=0
ws_inset=0         # gap above and below the buttons. 0 = the button spans
                   # the full bar height, top to bottom
ws_radius=0        # 0 = square corners. -1 = follow radius, or a full pill
                   # when ws_inset > 0
ws_border=0        # outline thickness in px around every button. 0 = none,
                   # which is the plain look: the gap between buttons is the
                   # only division
ws_slots=10        # always show the numbers 1..10, open or not. A free number
                   # is the same button in the same place, just faint, and
                   # clicking one opens that workspace. It also means the bar
                   # is the same width folded and open. 0 = only what is open
ws_empty_alpha=35  # how visible a free number is, percent
ws_click=1
scroll_workspace=0
mode_show=1        # show the binding mode (resize, ..)

# --- text ---
# By default swbr uses the desktop's monospace font (via fontconfig).
# font=DejaVu Sans Mono
# font_alt=Noto Sans Symbols 2   # for glyphs the main font lacks
ui_scale=1.0       # master text size. 1.3 = bigger, 0.85 = smaller
text_px=19         # status text
ws_px=19           # workspace labels
text_y=-2          # nudge every baseline, logical px, negative = up
pad_x=12           # padding at the left end
pad_right=20       # padding at the right end, so the last cell can breathe
scroll_speed=45    # text cells: logical px per second while hovered
scroll_pause=900   # ms held at each end before scrolling

# ---------------------------------------------------------------------------
# CELLS — the right hand side
#
#   cell=NAME          declares a cell. The order of these lines is the order
#                      the cells appear in, left to right.
#   NAME.cmd=...       shell command; whatever it prints is the cell text.
#                      Print nothing and the cell disappears, separator too.
#   NAME.interval=2    seconds between runs. 0 = run once at start,
#                      -1 = keep the command running and take every line.
#   NAME.fmt=%s C      %s is replaced by the output. No printf escaping:
#                      a % in here is just a %.
#   NAME.color=        text colour        NAME.bg=        cell background
#   NAME.warn=>70:cecb00                  NAME.crit=<12:ff2222
#                      recolour when the first number in the output is at or
#                      above (>) / at or below (<) the threshold
#   NAME.min_w=280     keep this width even when the text is shorter
#   NAME.max_w=0       clip beyond this width
#   NAME.align=right   left | center | right, inside min_w
#   NAME.sep=0         do not draw a separator after this cell — that is how
#                      two cells are combined into one group
#   NAME.empty=TEXT    drawn instead of hiding when the command prints
#                      nothing — keeps the cell's area clickable
#   NAME.gap=          space after this cell, overrides cell_gap. 0 glues it
#                      to the next one: equal bg colours merge into one box
#   NAME.pad=0         padding inside the cell, left and right
#   NAME.slim=auto     folded strip: auto | tick | bar | clock | presence |
#                      off. presence = a plain block in the running colour,
#                      present only while the program is
#   NAME.slim_color=   override this cell's colour on the strip. Without it
#                      the strip reuses the colour the cell's own text has,
#                      so a cyan clock stays cyan when folded
#   NAME.slim_color2=  second colour: the minutes of a clock cell
#   NAME.slim_min=0    the value range a gauge maps, so a temperature or a
#   NAME.slim_max=100  load average can be a gauge as well as a percent
#   NAME.markup=1      the output may use <span foreground="#rrggbb">..</span>
#   NAME.button2=CMD   click the cell (1 left, 2 middle, 3 right, 4/5 wheel)
# ---------------------------------------------------------------------------

cell_gap=14
cell_inset=3       # gap above and below a cell background
cell_radius=5      # corner radius of a cell background
separator=│
separator_color=3a4654ff

# --- messages ---------------------------------------------------------------
# Anything can shout at the bar:
#     swbr --msg "warn: backup running"
#     swbr --msg "error: disk full"
#     swbr --msg clear
#     echo "info: hello" > $XDG_RUNTIME_DIR/swbr.fifo
# While a message is up it takes over the cmus cell, so the title turns into
# the warning and turns back into the title afterwards. Click it to dismiss.
msg_target=cmus
redraw_ms=250      # or refresh=0.25, the same thing in seconds. Try 1000 if
                   # you would rather the bar redrew once a second.
                   # Cell updates are held this long and merged into one
                   # frame. Every frame is a round trip through the
                   # compositor, and ten cells on their own timers otherwise
                   # wake the bar three times a second. Anything from sway --
                   # a workspace switch, urgency -- skips the hold and is
                   # drawn on the next frame
msg_timeout=8      # seconds; 0 = stays until cleared
msg_flash=1        # folded bar turns fully into the message colour
msg_info=89afc4
msg_warn=cb9b00
msg_error=e0533c

# --- cmus: two cells glued into one box -------------------------------------
# The title is a text cell: cut with ".." and scrolls while hovered. The
# controls are their OWN cell so a long title can never truncate them away,
# and they keep a fixed clickable area when nothing plays (empty=).
# Both share one background: same bg + gap=0 merges them into a single box.
# Note: the U+23Fx media glyphs (pause, stop) are missing from most mono
# fonts, so the icon is derived here from glyphs that actually exist.
cell=cmus
cmus.source=cmus   # swbr runs cmus-remote itself: no script, and playing vs
                   # paused is read from cmus rather than guessed
cmus.cmus_fmt=%n   # just Artist — Title; %i is the icon, %a %t %s also work
cmus.interval=2
cmus.scroll=1      # text cell: cut with ".." and scroll it while hovered
cmus.min_w=210     # fixed slot, so nothing else on the bar ever shifts
cmus.align=left
cmus.pad=10        # breathing room inside the background box
cmus.bg=ffffff14   # a faint lighter panel, not a solid block
cmus.gap=0         # glued to the controls: one continuous background
cmus.sep=0
cmus.slim=off      # the title says nothing at five pixels
cmus.button1=pgrep -x cmus >/dev/null && cmus_control toggle || foot -e cmus
cmus.button2=cmus_control toggle
cmus.button4=cmus_control prev
cmus.button5=cmus_control next

cell=cmusui
cmusui.source=cmus  # the same source, laid out as just the icon
cmusui.cmus_fmt=%i  # ▶ while playing, ⏸ while paused, following the real state
cmusui.interval=2
cmusui.empty=♪     # cmus not running: still a button, click it to start
cmusui.min_w=38    # never shrinks, never truncates
cmusui.align=center
cmusui.pad=4
cmusui.bg=ffffff14
cmusui.color=e8b81a
cmusui.slim=media  # folded: a full block while playing, a short dim one when
                   # paused, nothing at all when cmus is stopped.
                   # source=cmus knows which, so slim_on is not needed.
cmusui.slim_w=26   # wider than the other ticks, so it is easy to find and hit
cmusui.button1=pgrep -x cmus >/dev/null && cmus_control toggle || foot -e cmus
cmusui.button2=cmus_control toggle
cmusui.button4=cmus_control prev
cmusui.button5=cmus_control next

# --- volume ----------------------------------------------------------------
cell=volume
volume.cmd=alsa_control volume get
volume.interval=2
volume.button2=alsa_control mute toggle
volume.slim=bar
volume.slim_w=56   # folded: a gauge needs room for its ten blocks, and this
                   # cell is only two characters wide. Wins over slim_align,
                   # growing about the middle so it stays where the text was
volume.slim_color=a9d8f5   # light baby blue, its own thing on the strip

# --- docker and mpv share one group: docker.sep=0 joins them ---------------
cell=docker
docker.cmd=pgrep -x dockerd >/dev/null || exit 0; docker ps --format '{{.Image}}' | sed 's/:.*//' | xargs
docker.interval=10
docker.color=19cb00
docker.sep=0
docker.slim=presence   # folded: a block in the running colour, there only
                       # while dockerd is, so a glance says it is up

cell=mpv
mpv.source=window  # asks sway which workspaces have an mpv window, no jq and
                   # no swaymsg. %n the name, %w the workspaces, %c how many
mpv.program=mpv    # matched against app_id, the X11 class, then the title
mpv.src_fmt=<span foreground="#19cb00">%n </span><span foreground="#3E98E7">[%w]</span>
mpv.interval=3
mpv.slim=presence      # same for mpv: started something in the background?
mpv.slim_color=3ea6ff  # its own colour, so you can tell the two apart

# --- clock -----------------------------------------------------------------
cell=clock
clock.cmd=date '+<span foreground="#00ffff">%H:%M</span>  %a %d.%m'
clock.interval=5
clock.hover_click=1  # the calendar opens on a click and stays until you
                   # click again, rather than following the pointer
clock.hover_cal=1  # the panel: this month, with today in the hl colour.
                   # Built in, so the columns line up whatever the font and
                   # nothing is spawned. hover_cmd=cal would work too
# clock.hover_cmd=cal  # the panel: this month, from cal(1). Run once when
                   # the hover starts, not on a timer
clock.slim=clock   # twelve dots for the hour, in the same cyan the clock
                   # uses in the full bar (taken from its own markup)
clock.slim_color2=2f7f9f   # the minutes bar, and the morning hours. Every dot
                   # up to the hour is lit, so you count bars: 2 at 02:00 and
                   # still 2 at 02:55. Main colour after noon, this one
                   # before, so 13:00 and 1:00 differ

# --- cpu load and temperature, joined --------------------------------------
cell=cpu
cpu.cmd=cpu_in_percent
cpu.fmt=%s%
cpu.interval=2
cpu.color=e1eeff
cpu.warn=>70:cecb00
cpu.crit=>80:cc0403
cpu.min_w=52
cpu.slim=bar       # a gauge in the folded strip, 0..100%
cpu.sep=0

cell=temp
temp.cmd=t=$(cpu_temp); [ "${t%%.*}" -ge 70 ] 2>/dev/null && printf '%s°C' "$t"
temp.interval=5
temp.warn=>70:cecb00
temp.crit=>85:cc0403
temp.slim=bar      # a gauge too, but degrees are not percent:
temp.slim_min=40   # so map 40..100 C onto the gauge
temp.slim_max=100

# --- battery ---------------------------------------------------------------
# The draw and the time left live in the hover panel now, so they are there
# when you want them and not taking width when you do not. Uncomment this if
# you would rather have them in the bar all the time.
# cell=power
# power.source=battery
# power.src_fmt=%w %h
# power.color=b3c0cd
# power.slim=off
# power.sep=0

# The marker at the end tells the folded strip which way it is going:
# + charging, - discharging, = full. In the full bar it reads as ⚡ or nothing.
cell=battery
battery.source=battery  # reads /sys itself: 83+ filling, 83- draining, no
                   # sign when full
# battery.bat_path=/sys/class/power_supply/BAT1   # if yours is not BAT0, or
                   # you have two. Left out, swbr takes the first thing with a
                   # capacity file, preferring one called BAT*
# battery.src_fmt=%c%i %w %h   # %c capacity, %i sign, %w watts now, %h hours
                   # left, %s the word. This one reads "83- 21.5W 1.7h"
# battery.cmd=...   # setting a command switches the cell back to your own
                   # script; source= and cmd= are the two ways, never both
battery.hover=%w  %h %e # the panel: 21.5W  1.7h left, or "0.3h to full" on
                        # the cable. %e says which way the clock runs; with
                        # nothing to report it falls back to the word Full
                        # or Discharging
battery.hover_click=1   # opens on a click and stays until you click again,
                        # rather than following the pointer
battery.hover_slim=0    # 1 = folded, resting on it opens the bar so the
                        # panel has somewhere to go. 0 = no hover when folded
battery.interval=10
battery.color=e1eeff
battery.warn=<30:cecb00
battery.crit=<12:ff2222
battery.slim=bar
battery.slim_w=56  # same again: wide enough to count the blocks

# --- shouting when it is going flat -----------------------------------------
battery.alert=30,20,10,5,1 # percentages. Each fires once on the way down and
                   # rearms when the charge comes back above it, or when the
                   # cable goes in — no counter file, no repeats at 19%
battery.alert_msg=BATTERY %c%%   # taken over the bar like any other message;
                   # the last level is sent as an error, the rest as warnings
battery.alert_tone=250     # Hz. A sine with soft edges, written straight to
battery.alert_ms=1050       # the player — no click, unlike a test tone.
battery.alert_beeps=2      # 0 Hz for silence
battery.alert_gain=35      # how loud the tone itself is, percent of full
                   # scale. Costs nothing and touches no mixer, so try this
                   # before alert_vol_min below. 80 is loud but still clean
battery.alert_play=aplay -q -f cd -
                   # on pipewire/pulse instead:
                   # paplay --raw --rate=44100 --format=s16le --channels=2

# An alert nobody hears is not an alert. If the mixer is below this, swbr
# raises it for the tone and puts it straight back — even if the alert is
# killed half way through. ALSA has no per-stream level, so this is the master
# control: music gets louder too, for the second or two the tone lasts.
# 0 = never touch the mixer.
battery.alert_vol_min=50
battery.alert_vol_get=amixer -M get Master | grep -o '[0-9]*%' | head -1
battery.alert_vol_set=amixer -M -q set Master %v%
                   # any pair of commands works: the first prints a number,
                   # the second takes %v. Your own alsa_control, pactl,
                   # wpctl -- whatever you already use
                   # A muted output stays muted: swbr cannot tell deliberate
                   # silence from an accident. Append `unmute` to the set
                   # command if you would rather it spoke anyway
battery.alert_cmd=[ %c -le 1 ] && poweroff
                   # run at every level, and ONLY at a level: the guard can
                   # only ever be true if 1 is in the list above, which is why
                   # it is. %c is the percentage. Check it works without
                   # waiting for a flat battery:  swbr --alert-test
                   # poweroff needs root — give your user a sudo rule for it,
                   # or the command silently does nothing

# --- folding ---------------------------------------------------------------
# Put the pointer over the bar and press the key: the bar rolls up into a thin
# strip. Press it again to roll it back out.
hide_key=space     # matched by physical key, not by layout
hover_keys=1       # grab the keyboard while the pointer is over the bar.
                   # That is what makes hide_key work without clicking first.
collapsed_px=5
anim_ms=120
slim_align=1       # folded: each mark takes its cell's whole place, same
                   # left edge and same width, so toggling changes the height
                   # of the bar and nothing else.
                   # 0 = pack them against the right edge instead
signals=1          # the folded strip still says something: every workspace
                   # keeps a fixed slot on the left (slot 3 is always
                   # workspace 3), the clock becomes twelve dots, and cells
                   # with a percentage become little gauges
slim_ws_slots=10   # only for slim_align=0, the packed strip: this many
                   # slots. Lined up, the strip is exactly the open bar's own
                   # buttons — same set, same place, same width — so set
                   # ws_slots above to choose how many
slim_bar_segs=10   # folded gauges are split into this many blocks, so four
                   # lit blocks reads as forty percent without measuring it.
                   # 0 = one solid bar. Halves itself in a cell too narrow to
                   # show the dividers — give that cell a slim_w instead
slim_bar_gap=2     # px between those blocks
slim_bar_pad=3     # px either side of a folded gauge. A gauge takes its
                   # whole cell, so without this it runs edge to edge
slim_ws_w=0        # folded slot width in px. 0 = each slot copies its own
                   # button in the open bar, so nothing moves or resizes
start_collapsed=0  # 1 = start folded. Command line: swbr --slim
# Without the mouse. Bind either one to a key in your sway config:
#   bindsym $mod+b exec swbr --toggle      (also --fold / --unfold)
#   bindsym $mod+b exec pkill -USR1 swbr

# --- mouse: anywhere on the bar, folded or not ------------------------------
# Cell bindings win where a cell is; these catch everywhere else, which is the
# reliable way to control music while the bar is folded down to a few pixels.
# Same buttons your old sway bar block used.
button2=cmus_control toggle
button6=cmus_control prev
button7=cmus_control next

# ---------------------------------------------------------------------------
# LAYOUT — one line that places everything. Keep it last: it assigns group,
# order and separators, overriding pos= and sep= above.
#
#   ||   splits groups. One part = left only, two = left and right,
#        three = left, center, right.
#   ,    separates items.
#   (..) glues items together with no separator between them.
#   names are cell names plus the built-ins "workspaces" and "mode".
# ---------------------------------------------------------------------------
bar={workspaces,mode||(cmus,cmusui),volume,(docker,mpv),clock,(cpu,temp),battery}

# --- colors: #rrggbb or #rrggbbaa ------------------------------------------
bg=26313fe6         # the bar itself
text=e1eeffff       # default cell colour      alias: statusline
dim=5a6b7aff
accent=89afc4ff     # visible-but-not-focused workspace tick
hl=cb9b00ff         # focused workspace tick in the folded strip
urgent=e0533cff
ws_sort=1          # order them by number. sway lists them grouped by output,
                   # so two monitors otherwise give 1 2 5 8 3 10
ws_other=1         # 1 = also show the workspaces of your other monitors, as
                   # short pills on the baseline so they are clearly not this
                   # screen's
ws_cpu=1           # a dot on each workspace button showing how much
                   # processor time the windows on it are using. Folded, the
                   # workspace slot fills from the bottom instead
ws_cpu_interval=3  # seconds between samples
# tree_min_s=5     # the load dots and source=window cells need sway's tree.
                   # It is fetched only when sway reports a change, and never
                   # more often than this. no_tree=1 stops asking entirely
ws_cpu_idle=0.01   # in cores. Under this a workspace counts as doing
                   # nothing and stays blank. Above it, but under ws_cpu_min,
                   # one faint dot: a player, a polling script, something
                   # small but alive
ws_cpu_min=0.25    # where the real scale starts, in cores: 1.0 is one core
                   # kept busy
ws_cpu_full=4      # four cores fills the column. A share of the whole
                   # machine was the wrong unit: on sixteen threads two busy
                   # cores are twelve percent, which rounds to nothing

running=3ddc84ff   # folded strip: this program is up, and where a charging
                   # gauge's pips ramp to
slim_warm=e8963cff # where the direction pips start: orange into red while
                   # draining, orange into green while charging
ws_bg=00000000      # inactive button: nothing, the bar shows through
ws_fg=b3c0cdff
ws_focused_bg=cb9b00ff   # the appwheel orange
ws_focused_fg=141414ff
ws_visible_bg=3c4a5cff
ws_visible_fg=e1eeffff
ws_urgent_bg=e0533cff
ws_urgent_fg=141414ff
mode_bg=cb9b00ff
mode_fg=141414ff