4.4 KiB
Waybar Time Tracker
A small, dependency-free Python time tracker for Waybar with a start/stop button and timesheet generation.
Features
- Start / stop button in Waybar: click the module to toggle tracking.
- Live elapsed time shown in the bar while running.
- Persistent JSON storage in
~/.local/share/time_track/data.json(override withTIME_TRACK_DIR). - Timesheet generation in Markdown, grouped by task and by day.
- Optional server sync of completed entries, using environment-only configuration.
Files
| File | Purpose |
|---|---|
time_track.py |
Main CLI and Waybar interface |
waybar-config.json |
Example Waybar custom module configuration |
waybar-config.jsonc |
Same example, with comments (for Waybar JSONC configs) |
style.css |
Example CSS for the running/idle states |
Installation
-
Make sure
time_track.pyis executable:chmod +x /path/to/time_track/time_track.py -
Add the custom module from
waybar-config.json(orwaybar-config.jsonc) to your Waybar config (~/.config/waybar/configor~/.config/waybar/config.jsonc). -
Add the CSS from
style.cssto your Waybar stylesheet (~/.config/waybar/style.css). -
Update the paths in the config to point to wherever you placed
time_track.py.
Why the module might not show
If the Waybar module appears but has no text, check that "format" is not empty. When return-type is "json", Waybar replaces "{}" with the text field emitted by the script. An empty format ("") makes the module invisible. Use "format": "{}" or omit the field entirely.
CLI usage
# Start a session (will prompt for a task; empty is allowed)
./time_track.py toggle
# Start a session without a prompt, using a specific task
./time_track.py toggle "client-a"
# Stop the active session (same as ./time_track.py stop)
./time_track.py toggle
# Emit Waybar JSON (used by the module)
./time_track.py status
# Show the active session
./time_track.py current
# Stop the active session
./time_track.py stop
# Show recent entries
./time_track.py log
./time_track.py log 25
# Generate a Markdown timesheet
./time_track.py timesheet week
./time_track.py timesheet month
# Sync completed entries (after setting the environment variables below)
./time_track.py sync
Optional server sync
Sync is disabled unless all configuration is provided through the process environment. No server URL, token, or device identifier is written to a configuration file.
export TIME_TRACK_SERVER_URL="https://time-track.example.com"
export TIME_TRACK_SERVER_TOKEN="your-api-token"
export TIME_TRACK_DEVICE_ID="laptop-2026"
./time_track.py sync
sync sends a POST request to ${TIME_TRACK_SERVER_URL}/api/v1/sync/time-track with Authorization: Bearer <token> and a 15-second timeout. Its JSON request body is:
{
"device_id": "laptop-2026",
"entries": [
{
"id": "6cf5c9f0-7f65-4fcd-a76f-02cc2a9f3ca3",
"task": "client-a",
"start": "2026-09-14T09:00:00",
"end": "2026-09-14T10:00:00",
"duration": 3600
}
]
}
Only finished entries are sent. Each completed entry receives a stable UUID. On first load after upgrading, historic entries are assigned UUIDs and the local data file is updated, so repeating a sync submits the same entry IDs for server-side idempotency. The active session is never uploaded.
Waybar behavior
- Left click: start or stop a session.
- When starting, a task prompt appears. The launcher order is
wofi,rofi,bemenu,dmenu, thenzenity, then a terminal fallback. - Existing tasks are shown as a dropdown/list. Type a new task or pick an existing one.
- Press Enter with no input to start with an empty task.
- Press Escape / Cancel to abort starting.
- When starting, a task prompt appears. The launcher order is
- Right click: print the current week's Markdown timesheet to stdout (useful bound to a notification or terminal).
- The module updates every 5 seconds while running.
Task prompting requirements
For the click-to-start prompt to work from Waybar you need one of these installed:
| Launcher | Notes |
|---|---|
wofi |
Best for Wayland; shows previous tasks as a dropdown and allows typing new ones |
rofi |
Works on X11 and Wayland |
bemenu |
Wayland/X11 dmenu alternative |
dmenu |
Classic suckless dmenu |
zenity |
GTK entry dialog (no dropdown, but supports empty input) |
If none are installed, the script falls back to a terminal prompt when run from a TTY.