1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
# breaktimer
Break reminder for Linux/Wayland. A small Bash daemon that nudges you to take
micro-pauses while working at the PC, with desktop notifications, sounds, and a
[Waybar](https://github.com/Alexays/Waybar) module showing a live countdown.
Notifications and tooltips are in Italian.
## How it works
State machine: **working β micro-pause β working**, and every 4th block a
**long pause** instead. The countdown freezes when you pause manually and
outside your work-hours window, so breaks never eat into work time and the
Waybar number stays honest.
| Phase | Default | Notification |
|-----------|---------|--------------------------|
| working | 30 min | β |
| breaking | 3 min | "πΆ Micro-pausa" |
| longbreak | 10 min | "βΈοΈ Pausa lunga" (every 4th) |
## Dependencies
- `dunst` (or any `notify-send` provider)
- `pipewire` β `pw-play`, falls back to `paplay` (PulseAudio)
- coreutils, Bash
- [Waybar](https://github.com/Alexays/Waybar) (optional, for the bar module)
- A Nerd Font for the Waybar glyphs (optional)
## Install
The Waybar config calls the scripts from `~/bin`. Put both there and make them
executable:
```bash
mkdir -p ~/bin
cp breaktimer.sh waybar-breaktimer.sh ~/bin/
chmod +x ~/bin/breaktimer.sh ~/bin/waybar-breaktimer.sh
```
Make sure `~/bin` is on your `PATH` (or call the scripts by full path).
### Sounds
Defaults use the [Modern Minimal UI](https://github.com/cadecomposer/modern-minimal-ui-sounds) sound set at:
```
~/.local/share/sounds/modern-minimal-ui-sounds/stereo/
```
Three events map to `message-new-instant.oga` (micro), `alarm-clock-elapsed.oga`
(long), `service-login.oga` (back to work). Don't have that set? Either install
it there, or set `SOUND_*` (or `SYS_SOUND_*`) in `~/.config/breaktimer.conf`
(see Configuration below) to point at any `.oga`/`.wav` you like (e.g. the freedesktop
sounds in `/usr/share/sounds/freedesktop/stereo/`). A missing file is simply
silent β no error.
## Usage
```bash
breaktimer.sh start # start the daemon in the background
breaktimer.sh stop # stop it
breaktimer.sh restart # stop + start
breaktimer.sh pause # freeze the countdown
breaktimer.sh resume # unfreeze
breaktimer.sh toggle # pause/resume in one command
breaktimer.sh status # print state, phase, seconds remaining
breaktimer.sh config # print the effective settings
```
(`breaktimer.sh run` is the internal loop β don't call it directly; it will
refuse if a daemon is already running.)
Auto-start on login by adding `breaktimer.sh start` to your compositor's
autostart (e.g. Hyprland `exec-once`, Sway `exec`). `start` is idempotent:
`run_loop` claims the PID file atomically (`noclobber`), so a second `start` β
or a fast double-login β can't spawn a duplicate daemon; the loser aborts and a
stale PID file from a previous session is taken over, not duplicated.
## Configuration
Defaults live at the top of `breaktimer.sh`. To change them without editing a
tracked file, write `~/.config/breaktimer.conf` (or
`$XDG_CONFIG_HOME/breaktimer.conf`). It is sourced as shell, so it is a list of
assignments, and it need only name what it changes:
```bash
MICRO_MIN=25
BREAK_MIN=5
WORK_START="08:30"
SOUND_MICRO="$HOME/Music/notify/pausetta.opus"
```
| variable | default | meaning |
|---|---|---|
| `MICRO_MIN` | 30 | minutes of work between breaks |
| `BREAK_MIN` | 3 | length of a micro-pause |
| `LONG_MIN` | 10 | length of a long pause |
| `LONG_EVERY` | 4 | a long pause instead of every Nth micro-pause |
| `WORK_START` | 09:00 | countdown freezes before this |
| `WORK_STOP` | 18:30 | countdown freezes after this |
| `URGENCY_MICRO` | normal | notify-send urgency for a micro-pause |
| `URGENCY_LONG` | critical | notify-send urgency for a long pause |
| `SOUND_MICRO` | unset | sound for a micro-pause, falls back to `SYS_SOUND_MICRO` |
| `SOUND_LONG` | unset | sound for a long pause, falls back to `SYS_SOUND_LONG` |
| `SOUND_BACK` | unset | sound for going back to work, falls back to `SYS_SOUND_BACK` |
Check what is in effect:
```bash
breaktimer.sh config
```
The file is read when the daemon starts, so a change takes effect on
`breaktimer.sh restart`. A syntax error in it is reported on stderr, but the
script can carry on with the defaults; run `breaktimer.sh config` to confirm
the values actually in effect.
The check for all of this is `./test-breaktimer-config.sh`.
## Waybar integration
Three pieces:
- **`waybar-breaktimer.sh`** β emits JSON (`{text, class, tooltip}`) that Waybar
renders. Reads the daemon's state files; no recalculation.
- **`waybar-breaktimer.config.jsonc`** β the `custom/breaktimer` module.
- **`breaktimer.css`** β phase colors (Catppuccin).
### 1. Add the module
Paste the inner block of `waybar-breaktimer.config.jsonc` into your
`~/.config/waybar/config` modules, then add `"custom/breaktimer"` to one of your
`modules-left/center/right` arrays:
```jsonc
"custom/breaktimer": {
"exec": "~/bin/waybar-breaktimer.sh",
"return-type": "json",
"interval": 5,
"on-click": "~/bin/breaktimer.sh toggle", // left-click: pause/resume
"on-click-right": "~/bin/breaktimer.sh restart", // right-click: restart
"tooltip": true
}
```
### 2. Add the styling
Append `breaktimer.css` to `~/.config/waybar/style.css`. It colors the module by
phase:
| Class | Color | Meaning |
|-------------|--------|-------------------|
| `working` | green | working |
| `breaking` | blue | micro-pause |
| `longbreak` | purple | long pause |
| `paused` | yellow | manually paused |
| `stopped` | grey | daemon not running |
### 3. Reload
```bash
breaktimer.sh start
killall -SIGUSR2 waybar # reload Waybar
```
Left-click the module to pause/resume, right-click to restart.
## License
GPLv2 β see [LICENSE](LICENSE). Copyright (C) 2026 Danilo M.
|