# wlr-break-timer A fully automated break timer for wlroots-based desktop environments (SwayWM, etc.) that helps maintain healthy work habits by tracking work duration and break periods. ## Features - **Zero user interaction required** - Automatically tracks work/break cycles. - **Dual break timers** - Independent short breaks (20m work β†’ 20s break) and long breaks (45m work β†’ 5m break). - **Automatic idle detection** - Uses swayidle to detect when you're away from the computer. - **Pause/Unpause** - Manually pause the timer when needed (paused time doesn't count toward work duration). - **Self-managing log** - Automatically trims old events to keep log size minimal. - **Waybar integration** - Shows countdown timers in your status bar with context menu. - **No dependencies** - Only requires Python 3 (pre-installed on most Linux systems). - **No daemon process** - Swaylock is the only long-running process. Other scripts are executed to modify or read the log file. ## How It Works 1. **swayidle** monitors keyboard/mouse activity via Wayland protocols 2. When idle timeout is reached, `break-event` logs an `idle_start` event 3. When you return, `break-event` logs an `idle_end` event 4. `break-status` parses the log to calculate active time and break status 5. Waybar polls `break-status` every second to display current timers ### Timer Logic - **Short breaks**: After 20 minutes of active work, you need a 20 second break - **Long breaks**: After 45 minutes of active work, you need a 5 minute break - **Automatic credit**: Idle periods β‰₯ break duration automatically count as breaks taken - **Smart reset**: Long breaks also reset the short break timer (since they encompass it) - **Auto-trim**: When a long break is completed, all log entries before it are deleted ## Installation 1. **Copy scripts to your PATH:** ```bash chmod +x break-event break-status cp break-event break-status ~/.local/bin/ ``` 2. **Create configuration directory:** ```bash mkdir -p ~/.config/break-timer cp config.example.json ~/.config/break-timer/config.json ``` 3. **Edit configuration** (optional): ```bash nano ~/.config/break-timer/config.json ``` 4. **Add to Sway config** (`~/.config/sway/config`): ``` exec swayidle -w \ timeout 5 'break-event idle_start' \ resume 'break-event idle_end' \ before-sleep 'break-event idle_start' \ after-resume 'break-event idle_end' ``` 5. **Add to Waybar config** (`~/.config/waybar/config`): ```json { "modules-right": ["custom/break-timer"], "custom/break-timer": { "exec": "break-status", "return-type": "json", "interval": 1, "format": "πŸ• {}", "tooltip": true, "menu": "on-click", "menu-file": "/path/to/menu.xml", "menu-actions": { "skip-long": "break-event skip_long", "toggle-pause": "break-event toggle-pause" } } } ``` 6. **Add Waybar styling** (`~/.config/waybar/style.css`): ```css #custom-break-timer.normal { color: #a6e3a1; } #custom-break-timer.warning { color: #f9e2af; } #custom-break-timer.overdue { color: #f38ba8; font-weight: bold; } #custom-break-timer.break { color: #89b4fa; } #custom-break-timer.paused { color: #cba6f7; font-style: italic; } ``` 7. **Reload Sway and Waybar:** ```bash swaymsg reload killall waybar && waybar & ``` ## Configuration Edit `~/.config/break-timer/config.json`: ```json { "short_break": { "interval": "20m", // Work duration before short break "duration": "20s" // Required short break length }, "long_break": { "interval": "45", // Work duration before long break "duration": "5m" // Required long break length }, } ``` ## Status Display The Waybar module shows: - **Working**: `15:30 / 45:20` - Time until short break (15min 30sec) and long break (45min 20sec) - **Short break**: `SB 1:45` - Time remaining in short break - **Long break**: `LB 8:30` - Time remaining in long break - **Overdue**: `BREAK! -2:30 / 5:00` - You've exceeded a break time - **Paused**: `⏸ PAUSED` - Timer is paused, no activity is being tracked ### Color Coding - **Green (normal)**: Plenty of time until next break - **Yellow (warning)**: Break due in less than 5 minutes - **Red (overdue)**: Break time has passed, you should take a break! - **Blue (break)**: Currently in a break period - **Purple (paused)**: Timer is paused ## Using the Context Menu Right-click the break timer widget in Waybar to access the context menu: - **Skip Long Break**: Reset all timers (useful if you just returned from a break not tracked by the timer) - ** Toggle Pause**: Pause or unpause the timer. While paused: - No activity is tracked - Idle detection is disabled (idle events are not logged) - The widget shows "⏸ PAUSED" in purple - Only the "Unpause Timer" menu option is shown ## Log Management - **Location**: `$XDG_RUNTIME_DIR/break-timer/activity.log` (usually `/run/user/1000/break-timer/`) - **Format**: Simple text - ` ` - **Auto-trim**: Automatically cleaned when long breaks complete - **Size**: Typically <10KB, contains only relevant recent events - **Persistence**: Cleared on logout/reboot (starts fresh each session) ## Troubleshooting ### Waybar shows "???" - Check if `break-status` is executable: `chmod +x ~/.local/bin/break-status` - Test manually: `break-status` should output JSON - Check log exists: `ls $XDG_RUNTIME_DIR/break-timer/` ### Timers don't update - Verify swayidle is running: `ps aux | grep swayidle` - Check if events are being logged: `cat $XDG_RUNTIME_DIR/break-timer/activity.log` - Test event logging: `break-event idle_start` then `break-event idle_end` ### Timers seem wrong - Check your configuration: `cat ~/.config/break-timer/config.json` - View raw log: `cat $XDG_RUNTIME_DIR/break-timer/activity.log` - Delete log to reset: `rm $XDG_RUNTIME_DIR/break-timer/activity.log` ## Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ swayidle β”‚ Monitors compositor for keyboard/mouse activity β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚ timeout β†’ idle_start β”‚ resume β†’ idle_end β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ break-event │────────▢│ activity.log β”‚ β”‚ - Append timestamp β”‚ writes β”‚ (event log) β”‚ β”‚ - Auto-trim old β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–² β”‚ reads β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β” β”‚ Waybar │────────▢│ break-status β”‚ β”‚ (polls 1s) β”‚ calls β”‚ - Parse log β”‚ β”‚ β”‚ β”‚ - Calculate timers β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - Output JSON β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## Similar Projects - [Workrave](https://workrave.org/) - The original, and a great app, but does not have very robust Wayland support at the time this tool was created. - [BreakTimer](https://breaktimer.app/) - Very nice interface, but only supports a single timer. - [ianny](https://github.com/zefr0x/ianny) - Supports Wayland, but otherwise I have not explored deeply. ## License MIT