i3 Desktop Part 10: A Pomodoro Timer in the Bar
The Pomodoro timer is a good example of the kind of feature that belongs in this desktop.
It is small. It is local. It is useful while working. It does not need an account, a browser tab, or a separate app window. It just needs to start, show the remaining time, notify me when finished, and stay out of the way.
The script is .local/bin/i3-pomodoro.
The i3blocks config runs it as the pomodoro block:
~/.local/bin/i3-pomodoro status
That block updates every second and also listens for a refresh signal.
The states
The timer keeps its state under XDG_RUNTIME_DIR/i3-pomodoro, falling back to /tmp if needed. The state file stores:
- status
- mode
- duration
- end time
- remaining time
- whether the finish notification has already been sent
The status can be idle, running, paused, or done.
The mode can be focus, break, long break, or custom.
This is enough to support the behaviour I actually need without turning the timer into a project.
The display
The bar text changes based on state.
Idle shows POM idle in a muted colour. A focus timer shows POM MM:SS. A break shows BRK MM:SS. A long break shows LBRK MM:SS. A custom timer shows TMR MM:SS.
Paused timers include pause. Finished timers show done and use the warning/error colour.
The colour changes are useful at a glance:
- normal focus time uses the main text colour
- breaks use green
- the last minute uses yellow
- done uses red
- idle uses muted grey
That is all I need from a timer display.
The menu
The menu is rofi-based, like the rest of the desktop.
It offers:
- start 25 minute focus
- start 5 minute break
- start 15 minute long break
- custom timer
- pause or resume when relevant
- reset
- status
Custom timer opens another small menu with common durations: 10, 15, 20, 25, 30, 45, and 60 minutes.
Clicking the bar with left or right click opens the menu. Middle click toggles pause and resume.
That makes the timer usable from both keyboard and mouse without adding more global shortcuts.
Notifications
When a timer finishes, it sends a dunst notification.
The script makes sure the finish notification is only sent once. That matters because the bar polls every second. Without a marker in state, a done timer could notify repeatedly.
After a timer completes, it stays in the done state until I reset or start another timer. That is intentional. If I am away from the desk when the notification fires, the bar still tells me the timer is finished when I come back.
Why not use an app
There are many Pomodoro apps. Most are more polished than this script.
But I do not want another app for this. I want a timer that lives where my attention already is: the i3bar. I want it controlled with the same menu style as the rest of the desktop. I want its state to disappear when the session ends. I want the implementation to be simple enough that I can change the durations or labels without learning a new system.
That is the advantage of building it into the desktop.
It is not a productivity methodology. It is just a small timer that makes focus blocks easy to start and easy to see.