A polished Windows 11 desktop widget that sits top-right, shows time-dependent tasks with countdowns, highlights the active task, plays an alert sound on task switches, and persists everything to a local SQLite database.
| Tool | Version |
|---|---|
| Windows 11 (or Windows 10 1903+) | — |
| Visual Studio 2022 17.8+ | with Windows App SDK workload |
| .NET 8 SDK | included with VS 2022 |
| Windows App SDK 1.5 | installed via NuGet (automatic) |
git clone https://github.com/you/TopRightTasks.git
cd TopRightTasks
File → Open → Project/Solution → src/TopRightTasks.sln
Visual Studio does this automatically on first build, or:
dotnet restore src/TopRightTasks.sln
Place any WAV file at:
src/TopRightTasks/Assets/alert.wav
A free 1-second chime is enough. The file is marked CopyToOutputDirectory = PreserveNewest in the csproj.
If the file is missing the sound is silently skipped — everything else works normally.
To generate a simple sine-wave beep (PowerShell, no external tools required):
[System.Media.SystemSounds]::Beep.Play()
# Or use Audacity / any DAW to export a short WAVAlternatively, set a custom path via Settings → Alert sound at runtime.
Press F5 (Debug) or Ctrl+F5 (without debugger).
The widget appears top-right, always-on-top, borderless.
dotnet publish src/TopRightTasks/TopRightTasks.csproj -c Release -r win-x64 --self-contained false
%LOCALAPPDATA%\TopRightTasks\tasks.db
SQLite; schema is created automatically on first run.
dotnet test tests/TopRightTasks.UnitTests/TopRightTasks.UnitTests.csproj
Or use Test Explorer in Visual Studio (Ctrl+E, T).
Tests cover:
TimeFormatterTests— formatting logic for all time rangesRecurrenceExpanderTests— daily, weekly, custom-days, recurrence-end cap, disabled tasksOverlapDetectionTests— exact, partial, adjacent, contained, cross-day, recurring overlapsSchedulerTests— sorting, active detection, extend, delete rebuilds
Click + in the header → fill Title, Start/End date+time, optional color and recurrence.
Toggle Recurring → choose Daily, Weekly (pick days), or Custom days.
Optionally set a Repeat until date; leave blank for infinite.
If a new task conflicts with an existing one, a warning appears:
Overlaps with "Morning Meeting" (03/12/2026 08:30–09:30). Resolve or check 'Allow overlap'.
Check Allow overlap (not recommended) to force-save anyway.
Click Extend on the active task row → pick +10 min, +30 min, +1 hour, or enter a custom number of minutes.
The change is persisted to SQLite immediately.
- Launch at Windows startup — writes/removes
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\TopRightTasks - Alert sound path — browse to any WAV file; leave blank to use
Assets/alert.wav
The widget remembers where you dragged it between sessions (win_x, win_y in the settings table).
On first launch it positions itself top-right on the primary monitor.
Event-driven timer, not polling. On startup (and after any CRUD operation), SchedulerService calls RecurrenceExpander.Expand for every task over a one-year horizon, producing a flat sorted list of TaskOccurrence objects held in memory. It then inspects the next start/end boundary in that list and schedules the DispatcherTimer to fire at precisely that moment (capped at 1 second so the clock always updates). When the timer fires, the service re-evaluates which occurrence is currently active and raises ActiveTaskChanged only when the active task actually changes — triggering the sound and UI highlight. No database reads occur during normal ticking.
Why it's efficient: the hot path (each second) is a single LINQ scan of the in-memory list — O(n) where n is the number of upcoming occurrences shown. The expensive recurrence expansion (O(tasks × days_in_horizon)) only runs on load and after CRUD changes, which are infrequent human actions. For typical use (< 50 tasks, 1-year horizon, mostly daily/weekly) expansion completes in well under a millisecond.
| # | Action | Expected |
|---|---|---|
| 1 | Launch app cold | Widget appears top-right, clock ticks, no crash |
| 2 | Add one-time task 1 min in future | Task appears in list with "in 1 minute" label |
| 3 | Wait for task start | Label changes to "X remaining", accent glow appears, sound plays once |
| 4 | Click Extend → +10 min | End time updates; remaining time increases by 10 min |
| 5 | Add second task overlapping first | Warning bar appears with conflicting task name and time |
| 6 | Check "Allow overlap", Save | Both tasks coexist; no crash |
| 7 | Add daily recurring task | Appears multiple times in upcoming list (one per day) |
| 8 | Add weekly task (Mon, Wed) | Only Mon/Wed occurrences shown |
| 9 | Open Settings → enable auto-start, save | Registry key present under HKCU\...\Run |
| 10 | Close and reopen app | Tasks persist; window reopens at saved position |
| 11 | Delete task | Task removed from list and DB immediately |
| 12 | Edit task (change title/time) | Changes reflected in list; overlap check runs |
| 13 | Recurring task with "repeat until" date | Occurrences stop after that date |
| 14 | Run unit tests | All tests pass (green) |
| 15 | Browse to custom WAV in settings | New sound plays on next task switch |