Skip to content

fix(windows): correct settings path so UI scaling works on Windows#2443

Merged
ten9876 merged 3 commits into
aethersdr:mainfrom
chibondking:fix/ui-scale-win-localappdata
May 7, 2026
Merged

fix(windows): correct settings path so UI scaling works on Windows#2443
ten9876 merged 3 commits into
aethersdr:mainfrom
chibondking:fix/ui-scale-win-localappdata

Conversation

@chibondking

Copy link
Copy Markdown
Collaborator

Summary

  • QStandardPaths::ConfigLocation on Windows Qt 6 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 UiScalePercent from %LOCALAPPDATA%\AetherSDR\AetherSDR.settings (two levels up), never found the value, and never set QT_SCALE_FACTOR — so UI scaling had zero effect on Windows despite the setting being saved correctly
  • Switch AppSettings to GenericConfigLocation (%LOCALAPPDATA% on Windows, ~/.config on Linux/macOS — no org/app suffix), consistent with the log-dir path already used in main.cpp
  • Add a one-time migrateSettingsPath() that moves the file from the old triple-nested path on first launch so existing Windows users don't lose their settings

How it was diagnosed

Confirmed the actual settings file location on a Windows machine:

%LOCALAPPDATA%\AetherSDR\AetherSDR\AetherSDR\AetherSDR.settings  <- where AppSettings wrote
%LOCALAPPDATA%\AetherSDR\AetherSDR.settings                       <- where main.cpp read

The file contained <UiScalePercent>175</UiScalePercent> -- proving the setting was saved, just never read back by main.cpp at startup.

Test plan

  • Build and run on Windows -- change UI scale, restart, confirm the window actually resizes
  • Verify existing Windows settings are migrated (old triple-nested file disappears, new path has the settings)
  • Confirm Linux behavior is unchanged (path stays ~/.config/AetherSDR/AetherSDR.settings)

Generated with Claude Code

chibondking and others added 2 commits May 7, 2026 00:49
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>
@chibondking

Copy link
Copy Markdown
Collaborator Author

@AetherClaude Verified that file was migrated out of the triple nest condition
Screenshot 2026-05-07 014008

.. Flagging a possible concern that there's a settings file double nested that's remaining. Beyond the scope for this fix, though.
Screenshot 2026-05-07 014021

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Good catch — I tracked down the root cause of the leftover double-nested file. Two more callers use QStandardPaths::AppConfigLocation directly:

  • src/core/ChannelStripPresets.cpp:220 → writes ChannelStrip.settings
  • src/core/FirmwareStager.cpp:24 → writes the firmware/ staging dir

On Linux/macOS, AppConfigLocation resolves to ~/.config/AetherSDR/ so they correctly land as siblings of AetherSDR.settings (matching the comment at ChannelStripPresets.cpp:219). On Windows Qt 6, it resolves to %LOCALAPPDATA%/AetherSDR/AetherSDR/ — the double-nested path you're seeing. Of those two, ChannelStrip.settings is almost certainly the file in your second screenshot; firmware/ would only appear if you've staged a firmware update.

Agreed it's out of scope for this PR — the UI-scaling fix here is self-contained and the PR title/migration both target AetherSDR.settings only. 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.

@chibondking

Copy link
Copy Markdown
Collaborator Author

@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."

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 AppSettings wrote to: ~/Library/Preferences/AetherSDR/AetherSDR/AetherSDR/AetherSDR.settings
  • main.cpp Q_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)) { ... }
#endif

Not 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>
@chibondking

Copy link
Copy Markdown
Collaborator Author

@AetherClaude fix added for osx.

@ten9876 ten9876 merged commit 73c52c9 into aethersdr:main May 7, 2026
5 checks passed
@ten9876

ten9876 commented May 7, 2026

Copy link
Copy Markdown
Collaborator

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants