Skip to content

v4.0.1

Choose a tag to compare

@github-actions github-actions released this 17 Mar 21:52
· 80 commits to master since this release

What's Changed

What's New

Battery Monitoring

  • Instant charger detection — event-driven architecture using WMI events (Windows) and Darwin notifications (macOS) for immediate plug/unplug response,
    with lightweight polling as fallback
  • Smarter notification rules — full battery alerts only fire when charger is plugged in; unplugging above threshold no longer triggers spurious
    notifications
  • Clear time estimates — "45m to full charge" (charging) / "3h 20m of battery remaining" (discharging) instead of ambiguous "45m remaining"
  • Contextual status messages — replaced generic jokes with battery-aware fallbacks like "Charging — estimating time to full..." when OS can't provide
    an estimate

Sound System

  • Custom sounds library — import your own .wav, .mp3, .m4a, .ogg, .flac, or .aac files; they're copied to the app's data directory and persist across
    sessions
  • Editor's Choice sounds — 6 curated music clips bundled with the app (Rock N Roll, Admonition, Snowy Glow, Legacy)
  • Full playback for custom sounds — imported and bundled sounds play once in full instead of being clipped; built-in tones still loop
  • Delete imported sounds — remove custom sounds from the library via the X button in the sound picker

DND / Focus Mode

  • macOS Tahoe support — DND detection works on macOS 16 via Control Center accessibility fallback
  • DND indicator in UI — banner shows between battery info and quick settings when Focus mode is active
  • Near real-time monitoring — Darwin notification polling every 5s (zero-cost memory read) with 2-minute fallback

Logging

  • Structured logs at every key point: power line changes, battery level changes, notification publish/suppress/deliver decisions, DND suppression state

Code Quality

  • Centralized hardcoded paths into Constants.AppName, Constants.AppDataDirectory, Constants.AppTempDirectory
  • Centralized asset URIs into AssetUris (Logo48, Logo128, LogoIco, ForAsset, ForSound)
  • Sealed 15 non-derived classes for performance
  • Refactored high-complexity methods: UpdateCheckIcons, CheckBatteryAndPowerStatus, IsMacDoNotDisturbActive
  • Added 1-second regex timeouts across all Regex calls (ReDoS prevention)
  • Subprocess commands resolved to absolute paths via Constants.ResolveCommand() (avoids PATH injection)
  • Debouncer: exception handling in timer callback + race condition fix (invoke inside lock)
  • AppSettings: error paths now call Reset() instead of Save() to properly restore defaults
  • Removed dead code: unused logger, no-op event unsubscription, stale IDE mappings

CI/CD

  • Fixed signtool not found — locates it from Windows SDK path
  • Secrets passed via env: blocks (not expanded in run: blocks)
  • Graceful skip when signing secrets aren't configured
  • Certificate/keychain cleanup via try/finally and trap EXIT
  • Binary validation before signing (fail fast with clear error)
  • Post-sign verification (codesign --verify --deep --strict)
  • Timestamp URL upgraded to HTTPS
  • Version read from csproj via MSBuild (no hardcoded fallback)
  • Velopack CLI pinned to 0.0.1298
  • Linux builds disabled in CI
  • bump-version.sh fixed for macOS (grep/sed compatibility)

Security

  • Settings encryption documented accurately: DPAPI on Windows, AES-256-GCM on macOS/Linux
  • CustomSoundsLibrary.Import(): extension allowlist, 50MB limit, symlink rejection, atomic write, collision handling

Full Changelog: v3.1.1...v4.0.0