
Most status bars for tiling window managers are configured in a small language of their own. webbar begins from a different premise: the bar is a web page. Each monitor's bar is an ordinary HTML and CSS document rendered inside a borderless, transparent window, and its entire appearance is editable as plain CSS — which reloads the moment the file is saved.
The project targets i3. A single process drives one bar per monitor, and all of them share one web engine so the memory cost stays modest. A small Python backend supplies live data — workspaces, system metrics, a system tray — and relays interactions back to the window manager.
Each bar is a GTK window carrying the DOCK type hint, undecorated and kept above other windows. An RGBA visual is requested so the window can be genuinely transparent, with a compositor performing the blending. So that i3 reserves space for the bar rather than tiling windows beneath it, the extended-window-manager strut hints are set on the window's X11 identifier; in practice they are applied with xprop once the window is realised, which proved more dependable than writing the cardinal arrays through the GTK bindings directly.
The window hosts a WebKit view that loads the page from a local file. Because every bar shares a single web context, the incremental cost of an additional monitor is small.
Workspace state is read over i3's IPC socket directly rather than by invoking a helper process on each change. The event socket is registered in the GLib main loop's own poll set, so that arriving events wake the loop and refresh the bar at once; earlier designs that polled, or that read on a background thread, introduced perceptible and inconsistent latency.
Indicator modules follow the familiar convention of small scripts that print a single line, each on its own interval. They are run asynchronously, so a sampler that takes a second to measure processor load never blocks the interface — a subtlety that, when first overlooked, was the source of a recurring stutter.
Communication from the page back to Python uses a WebKit message handler. A click on a workspace asks i3 to switch to it; a click on the power-profile indicator cycles the active profile; a click on a tray icon activates its application.
Because the bar is a document, its look lives entirely in one HTML file. Colours are declared as CSS custom properties and the layout is flexbox. A directory watcher reloads every bar when the file changes, so iterating on the design is immediate rather than a restart-and-check cycle.
Workspaces are drawn with the workspace's emoji or glyph as a large translucent backdrop and the number layered over it; the workspace visible on each monitor is marked with an accent underline, and an urgent workspace draws attention with an animated outline. Processor, memory and swap usage appear as small meter bars whose width tracks their value.

A module is any executable that writes one line to standard output. The bundled set reads system state from the kernel where it can — processor load from /proc/stat, memory from /proc/meminfo, temperature from the thermal zones — and falls back to common userspace tools otherwise. Adding one is a matter of placing a script in the scripts directory and naming it in the module list:
scripts/mem#!/bin/sh # a module prints one line; webbar shows it on an interval awk '/^MemTotal:/{t=$2} /^MemAvailable:/{a=$2} \ END{ if(t>0) printf "%d%%",(t-a)*100/t }' /proc/meminfo
The system tray is implemented as a StatusNotifier host in pure Python over DBus, adding no packages beyond those already required. Applications that speak the StatusNotifier or AppIndicator protocols register their icons, which are rendered as ordinary images in the bar; older XEmbed-only tray applications fall outside its scope.
webbar is released under the MIT licence. The source, with installation and configuration notes, is available on GitHub.