Compare commits

..

3 commits

Author SHA1 Message Date
Lukas Brübach
ecc3ecd4ea [Fonts] Make the editor's fallback and Reset preview-independent
- Add ThemeManager::defaultAppFont(), which resolves an unset role against the
  startup font instead of currentFonts, and use it in FontGridWidget::loadFonts
  so the grid never shows the live preview as the theme's default.
- Reload the live theme in PaletteEditorDialog::onReset before re-reading the
  grid, so Reset restores the saved fonts before loadFonts resolves fallbacks.
2026-11-01 13:59:16 +01:00
Lukas Brübach
c0aeaf72e8 [Fonts] Add per-purpose font section to palette editor 2026-11-01 13:53:56 +01:00
Lukas Brübach
c63a359c3d [Fonts] Restore the startup font when a config has no InterfaceDefault
- Capture the untouched application font next to the default palette and use
  it in previewFonts' else branch, so a config without InterfaceDefault
  restores the startup font instead of leaving the last preview applied.
- Drop the unpolish/polish loop from previewFonts: QApplication::setFont
  already notifies every widget, and the loop ran on every editor auto-apply.
2026-11-01 13:53:21 +01:00
4 changed files with 32 additions and 16 deletions

View file

@ -76,9 +76,11 @@ void FontGridWidget::loadFonts(const FontConfig &cfg)
auto role = static_cast<AppFont::Role>(fontEnum.value(i)); auto role = static_cast<AppFont::Role>(fontEnum.value(i));
const FontRow &row = fontRows[role]; const FontRow &row = fontRows[role];
// Roles absent from the file resolve to the theme's effective font, so // Roles absent from the file resolve to the startup font, not to the
// unset roles visibly show the system default instead of blanks. // live preview: appFont() would return the previewed config, so Reset
const QFont font = cfg.fonts.value(role, themeManager->appFont(role)); // and a first load would both show the edited font instead of the
// theme's real default.
const QFont font = cfg.fonts.value(role, themeManager->defaultAppFont(role));
row.familyCombo->setCurrentFont(font); row.familyCombo->setCurrentFont(font);
int size = font.pointSize(); int size = font.pointSize();

View file

@ -392,6 +392,10 @@ void PaletteEditorDialog::onReset()
{ {
workingConfig[loadedScheme] = savedConfig[loadedScheme]; workingConfig[loadedScheme] = savedConfig[loadedScheme];
paletteGrid->loadPalette(savedConfig[loadedScheme]); paletteGrid->loadPalette(savedConfig[loadedScheme]);
// Restore the live theme before re-reading the grid: loadFonts resolves
// unset roles, and the preview has currentFonts pointing at the edited
// config until the theme is reloaded.
themeManager->reloadCurrentTheme();
fontGrid->loadFonts(savedFontConfig); fontGrid->loadFonts(savedFontConfig);
seedAccentFromScheme(loadedScheme); seedAccentFromScheme(loadedScheme);
} }

View file

@ -127,9 +127,9 @@ static QString usableDefaultStyle(const QString &style)
ThemeManager::ThemeManager(QObject *parent) : QObject(parent) ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
{ {
defaultStyleName = usableDefaultStyle(qApp->style()->objectName()); defaultStyleName = usableDefaultStyle(qApp->style()->objectName());
// Capture the untouched application palette before any theme is applied. // Capture the untouched application palette and font before any theme is
// applied.
defaultPalette = qApp->palette(); defaultPalette = qApp->palette();
// Capture the untouched application font before any theme font is applied.
defaultFont = qApp->font(); defaultFont = qApp->font();
ensureThemeDirectoryExists(); ensureThemeDirectoryExists();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
@ -534,18 +534,15 @@ void ThemeManager::previewFonts(const FontConfig &cfg)
{ {
currentFonts = cfg; currentFonts = cfg;
// QApplication::setFont already sends a font change to every widget, so a
// repolish pass is not needed for fonts (unlike the palette path).
const auto it = cfg.fonts.constFind(AppFont::InterfaceDefault); const auto it = cfg.fonts.constFind(AppFont::InterfaceDefault);
if (it != cfg.fonts.constEnd()) { if (it != cfg.fonts.constEnd()) {
qApp->setFont(it.value()); qApp->setFont(it.value());
} else {
// Repolish every widget immediately so the preview applies without // A config without InterfaceDefault means "no override": restore the
// waiting for natural expose events, mirroring applyStyleAndPalette. // startup font instead of leaving the last preview applied.
QStyle *style = qApp->style(); qApp->setFont(defaultFont);
for (QWidget *widget : qApp->allWidgets()) {
style->unpolish(widget);
style->polish(widget);
widget->update();
}
} }
emit fontsChanged(); emit fontsChanged();
@ -663,6 +660,14 @@ QFont ThemeManager::appFont(AppFont::Role role) const
return qApp->font(); return qApp->font();
} }
QFont ThemeManager::defaultAppFont(AppFont::Role /*role*/) const
{
// No per-role scaling and no preview: an unset role resolves to the font
// captured at startup, which is what the theme falls back to once the
// editor closes.
return defaultFont;
}
void ThemeManager::themeChangedSlot() void ThemeManager::themeChangedSlot()
{ {
QString themeName = SettingsCache::instance().getThemeName(); QString themeName = SettingsCache::instance().getThemeName();

View file

@ -49,8 +49,8 @@ private:
// switching away from a custom palette restores the original colours. // switching away from a custom palette restores the original colours.
QPalette defaultPalette; QPalette defaultPalette;
// Pristine application font captured at startup, before any theme font is // Pristine application font captured at startup, before any theme font is
// applied. Used to restore the original font when a theme supplies none, // applied. Restored when a theme (or a preview) supplies no InterfaceDefault
// mirroring defaultPalette above. // font, so switching away from a themed font cannot leave it behind.
QFont defaultFont; QFont defaultFont;
QString currentThemePath; QString currentThemePath;
std::array<QBrush, Role::MaxRole + 1> brushes; std::array<QBrush, Role::MaxRole + 1> brushes;
@ -152,6 +152,11 @@ public:
/** @brief Resolves an application font role: the theme's stored [Fonts] /** @brief Resolves an application font role: the theme's stored [Fonts]
* value when present, otherwise the application font. */ * value when present, otherwise the application font. */
QFont appFont(AppFont::Role role) const; QFont appFont(AppFont::Role role) const;
/** @brief Resolves an application font role against the startup font only,
* ignoring any previewed config in currentFonts. Editors that show
* "what this role resolves to" must use this, because appFont()
* reflects a live preview while the editor is open. */
QFont defaultAppFont(AppFont::Role role) const;
QBrush &getBgBrush(Role zone); QBrush &getBgBrush(Role zone);
QBrush getExtraBgBrush(Role zone, int zoneId = 0); QBrush getExtraBgBrush(Role zone, int zoneId = 0);