# Idle Detection for WindowWatcher ## Summary Add idle detection to WindowWatcher so it automatically pauses the active TaskTracker task when the user is away, and resumes it when they return. ## Behavior - **Detection method:** `GetLastInputInfo` Win32 API — returns time of last keyboard/mouse input - **Idle threshold:** Configurable via `IdleTimeoutMs` (default: 300,000ms = 5 minutes) - **Checked on existing poll cycle** — no new timers or threads ### State Machine ``` ACTIVE ──(idle > threshold)──► IDLE ▲ │ └──(input detected)──────────────┘ ``` ### On Idle Transition 1. `GET /api/tasks/active` to find the current task 2. `PUT /api/tasks/{id}/pause` with note "Auto-paused: idle timeout" 3. Store paused task ID locally ### On Resume Transition 1. Check if stored task ID is still in Paused status 2. If yes: `PUT /api/tasks/{id}/resume` with note "Auto-resumed: user returned" 3. Clear stored task ID ## Files Changed | File | Change | |------|--------| | `NativeMethods.cs` | Add `GetLastInputInfo` + `LASTINPUTINFO` struct | | `Worker.cs` | Add idle state tracking, check idle time each poll, call pause/resume APIs | | `WindowWatcherOptions.cs` | Add `IdleTimeoutMs` (default: 300000) | | `appsettings.json` | Add `IdleTimeoutMs` setting | ## Edge Cases - **No active task when idle fires:** Log, skip pause, don't store task ID - **Task manually changed while idle:** On resume, verify stored task is still paused before resuming - **API unreachable:** Log warning, retry on next poll cycle. Maintain idle state locally ## Out of Scope - Session lock/unlock detection - New context event types - Tray menu UI changes