When explorer.exe restarts it destroys the taskbar, which destroys our embedded child window outright (IsWindow returns false) and leaves the UI thread parked in GetMessage with no window to recreate in place. The tray icon and widget vanish until the app is manually relaunched (see issue #34).
A dedicated watchdog thread (independent of the now-dead message loop) polls the Shell_TrayWnd handle and, when it changes, relaunches the widget as a fresh process that re-embeds into the new taskbar. The relaunched child is flagged via an environment variable so it waits on the single-instance mutex until the previous instance exits, and a throttle backs off if explorer is crash-looping.
The PR added the translation file only; register it in the
localization module (enum, codes, native name, string lookups,
pt locale detection) and add the context menu entry and command
handler. Also trim trailing whitespace and align field order
with the other language files.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The PR added IDM_LANG_RUSSIAN to the context menu but not to the
WM_COMMAND handler, so selecting it did nothing. Also reorder
second_suffix to match the Strings field order used by the other
language files.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix: pause usage polling on auth errors
- Show the same auth warning state for expired, invalid, or missing credentials
- Replace the widget auth text with a warning symbol and updated the toast notification
- Stop usage polling and countdown timers while auth is required
- Reuse the configured poll interval to watch credential file metadata instead of polling the API
- Auto-recover when credentials change, while still supporting manual refresh and restart flows
Updated translations
- Add `show_widget` field to Strings struct and all 6 language files
- Replace hardcoded "Show Widget" in window.rs with strings.show_widget
- Translate session_window ("5시간") and weekly_window ("7일") for Korean
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Korean language support with full UI translations including
menu items, update messages, and time format suffixes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added a native system tray icon that shows current 5-hour usage as a percentage badge.
- Added tray icon tooltip support showing both 5h and 7d countdown/usage values.
- Added tray icon interactions: left-click toggles the taskbar widget, right-click opens the context menu.
- Anchored widget to the bottom of the taskbar
- Added embedded app icon loading so tray fallback uses the app's own icon.
- Updated countdown timer logic to stop cases where 61m is shown
- Updated README.md
wsl.exe -l -q can hang indefinitely on some systems (e.g. WSL
installed but not fully configured), which blocks the poll thread
forever and prevents any usage data from loading.
Adds a run_with_timeout helper (5s deadline) and uses it for both
list_wsl_distros and read_wsl_credentials. The refresh paths
already had timeouts — these two were missed.
- Added ability to drag widget to desired position
- Using C:\Users\CraigConstable\AppData\Roaming\ClaudeCodeUsageMonitor\settings.json to store position and update frequency
- Updated README.md
- Added new function to find the claude CLI
- Using `claude -p .` to force OAuth refresh as `claude auth status` did not work
- Fixed handling of 'Start with Windows'
- Widened text display to fit values like '80% . 44m' (thank you @wangsu)
- Removed custom OAuth token refresh logic that was inadvertently invalidating Claude Code's refresh token via token rotation
- Removed hardcoded OAuth constants (token URL, client ID, scopes) no longer needed
- Removed in-memory token cache (CachedTokens, TOKEN_CACHE) no longer needed
- Delegate token refresh to the Claude CLI (claude auth status) so it manages its own credentials and writes updated tokens to disk
- Re-read credentials file after CLI refresh to pick up the fresh access token
- Simplified Credentials struct by removing unused refresh_token field
- Seconds countdown below 61s - shows 1m at 61s, then 60, 59... 0 counting down each second, then now when reset time passes
- Fast polling at reset - when either timer shows now, polls the API every 5s to pick up fresh rate limit data
- Auto-restores normal polling - stops the 5s fast poll as soon as fresh data comes back with a new reset time
- Token auto-refresh - when the OAuth token is expired, the app uses the refresh token to get a new access token in-memory (no disk writes)
- Show '...' on error - any poll failure shows the refresh indicator instead of cryptic error text
- Exponential backoff retry - on failure, retries at 30s, 60s, 120s... up to the poll interval, then restores normal interval on success
- Countdown guard - the countdown timer no longer overwrites '...' with stale cached data during error state
- Cleaned up error handling - removed Display impl, error message formatting, extract_error_message, and simplified try_model to return Option<UsageData>