fix(windows): correct settings path so UI scaling works on Windows#2443
Conversation
Qt 6 changed QStandardPaths::ConfigLocation on Windows to map to %LOCALAPPDATA% (AppData\Local) instead of %APPDATA% (AppData\Roaming) as it did in Qt 5. The previous fix used APPDATA, so the pre-QApplication settings read was still finding the wrong directory — QT_SCALE_FACTOR was never set and UI Scale remained broken on Windows. Fixes the remaining Windows regression after aethersdr#2432. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d triple-nested location Qt 6's ConfigLocation on Windows resolves to AppConfigLocation (%LOCALAPPDATA%/OrgName/AppName). AppSettings was appending "/AetherSDR" on top of that, producing a triple-nested path: %LOCALAPPDATA%\AetherSDR\AetherSDR\AetherSDR\AetherSDR.settings main.cpp read from %LOCALAPPDATA%\AetherSDR\AetherSDR.settings (two levels up), never found UiScalePercent, and never set QT_SCALE_FACTOR — so UI scaling had no effect on Windows despite the setting being saved. Switch AppSettings to GenericConfigLocation (%LOCALAPPDATA% on Windows, ~/.config on Linux/macOS — no org/app suffix), matching the log-dir path already used in main.cpp. Add a one-time migration that moves the settings file from the old triple-nested path on first launch so existing users don't lose their settings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@AetherClaude Verified that file was migrated out of the triple nest condition .. Flagging a possible concern that there's a settings file double nested that's remaining. Beyond the scope for this fix, though. |
|
Good catch — I tracked down the root cause of the leftover double-nested file. Two more callers use
On Linux/macOS, Agreed it's out of scope for this PR — the UI-scaling fix here is self-contained and the PR title/migration both target |
|
@AetherClaude please follow up with a separate PR "Happy to follow up with a separate PR that switches both call sites to GenericConfigLocation + "/AetherSDR" and migrates ChannelStrip.settings (plus any firmware/ contents) the same way AppSettings does, if that sounds right." |
There was a problem hiding this comment.
Thanks @chibondking — clean diagnosis and fix. The GenericConfigLocation switch matches what LogManager, BandStackSettings, MidiSettings, WsjtxClient, etc. already use, so this also brings AppSettings into line with the rest of the codebase. The new path, the migration, and the LOCALAPPDATA fix in main.cpp all hang together correctly for Windows.
One thing worth flagging:
The same triple-nesting bug existed on macOS, and the migration doesn't cover it.
Per Qt 6's qstandardpaths_mac.mm, ConfigLocation on macOS appends <OrgName>/<AppName> (same as AppConfigLocation). With OrgName == AppName == "AetherSDR":
- Old
AppSettingswrote to:~/Library/Preferences/AetherSDR/AetherSDR/AetherSDR/AetherSDR.settings main.cppQ_OS_MAC branch reads from:~/Library/Preferences/AetherSDR/AetherSDR.settings
So macOS had the same UI-scale-never-applies bug, and after this PR new writes correctly land at the short path — but any existing settings at the old triple-nested location are silently abandoned, since migrateSettingsPath() is #ifdef Q_OS_WIN. The migration logic is platform-agnostic in shape; just dropping the #ifdef (or adding a Q_OS_MAC arm with the same AppConfigLocation + "/AetherSDR/AetherSDR.settings" lookup) would catch macOS too. Something like:
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
const QString oldPath =
QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
+ "/AetherSDR/AetherSDR.settings";
if (QFile::exists(oldPath)) { ... }
#endifNot a blocker for the Windows fix you're targeting, but worth doing in this PR while the migration code is fresh — otherwise any macOS user who built from source loses their saved state on next launch.
Everything else looks good: scope is tight (3 files, all related), comments explain the why, the early QFile::exists(m_filePath) guard makes the migration idempotent, and the LOCALAPPDATA env-var change in main.cpp correctly mirrors GenericConfigLocation's Windows mapping.
Qt 6 ConfigLocation on macOS also resolves to AppConfigLocation (~/Library/Preferences/AetherSDR/AetherSDR), producing the same triple-nested path as Windows. Widen the #ifdef to cover both platforms so existing macOS settings are migrated instead of silently abandoned. Requested in PR review by ten9876. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@AetherClaude fix added for osx. |
|
Claude here — sharp empirical diagnosis, CJ. Inspecting the actual file location on Windows is the only way that triple-nested ConfigLocation-with-org-and-app behavior becomes visible; pure code review of #2432 missed it because main.cpp's path looked like it should match AppSettings's path on a quick read. The bonus catch on macOS (same triple-nesting, silent fix for users who'd given up on the slider) is icing. Migration is idempotent and atomic, Linux unchanged, GenericConfigLocation is the right primitive for this. Merged. 73, Jeremy KK7GWY & Claude (AI dev partner) |


Summary
QStandardPaths::ConfigLocationon Windows Qt 6 resolves toAppConfigLocation(%LOCALAPPDATA%/OrgName/AppName). AppSettings was appending/AetherSDRon top of that, producing a triple-nested path:%LOCALAPPDATA%\AetherSDR\AetherSDR\AetherSDR\AetherSDR.settingsmain.cppreadUiScalePercentfrom%LOCALAPPDATA%\AetherSDR\AetherSDR.settings(two levels up), never found the value, and never setQT_SCALE_FACTOR— so UI scaling had zero effect on Windows despite the setting being saved correctlyAppSettingstoGenericConfigLocation(%LOCALAPPDATA%on Windows,~/.configon Linux/macOS — no org/app suffix), consistent with the log-dir path already used inmain.cppmigrateSettingsPath()that moves the file from the old triple-nested path on first launch so existing Windows users don't lose their settingsHow it was diagnosed
Confirmed the actual settings file location on a Windows machine:
The file contained
<UiScalePercent>175</UiScalePercent>-- proving the setting was saved, just never read back by main.cpp at startup.Test plan
~/.config/AetherSDR/AetherSDR.settings)Generated with Claude Code