fix(settings): make the Font row actually change the font
It shipped doing nothing. Measured on the built binary: picking a face
persisted the pref and changed ZERO of 600600 pixels in the settings
label column. The row was a control that lied.
Two measurements say why, and both were run against this Qt build rather
than reasoned about:
- `ApplicationWindow.font.family` propagates through Qt Quick CONTROLS
only. In a standalone scene with a family set on the window, a
`Label` resolved to it and a sibling `Text` stayed on the
APPLICATION font. This tree is 1082 plain `Text` items against 13
that name a family, so the app's typeface IS the application font.
- The application font is read when an item is CONSTRUCTED. Driving
PySide6 against the same Qt, `QGuiApplication::setFont` updated
`QGuiApplication::font()` and left an already-built `Text` on its old
family.
Together those close the door on changing it live, so the ordering in
main() is the feature: FontPreload.qml registers the bundled faces (a
family does not exist until its file is loaded, and `load()` returns
with its FontLoaders already in the database), the application font is
set from the persisted choice, and only then does Main.qml build the UI.
Swap any two of those and the setting silently does nothing again.
The row now says "(requires restart)", the same wording Interface size
two rows above already uses, in all eight catalogues.
"System" resolves to "" and takes no branch, so anyone who never opens
the row gets exactly the font this app rendered before — verified by
capturing the window on both settings: 0 log lines and an untouched
frame for System, 27065 changed pixels for Montserrat.
NOT ADDRESSED, and worth its own decision: those 1082 Text items have
never used the bundled Inter either. `Main.qml` has always named it, but
that only ever reached the Controls, so the app renders in whatever Qt
picks. Making "System" mean Inter is a one-line change and a visible
one, so it is left alone here.
cc
This commit is contained in:
7 files changed
+143
-46
No files matched your search
@@ -0,0 +1,43 @@
|
||||
// FontPreload — registers the bundled typefaces BEFORE any Text exists.
|
||||
//
|
||||
// WHY THIS FILE IS A SEPARATE DOCUMENT, loaded before Main.qml.
|
||||
//
|
||||
// A plain `Text` does NOT inherit a font from its parents, and it does NOT
|
||||
// follow `ApplicationWindow.font` — that property propagates through Qt Quick
|
||||
// CONTROLS only. Proven on this Qt build with a standalone scene: with a
|
||||
// family set on the ApplicationWindow, a `Label` resolved to it and a `Text`
|
||||
// sibling stayed on the APPLICATION font. This tree has 1082 plain `Text`
|
||||
// items and 13 that name a family, so "the app's typeface" IS the application
|
||||
// font, and nothing else.
|
||||
//
|
||||
// And the application font is only read when an item is CONSTRUCTED. Also
|
||||
// proven, with PySide6 against this same Qt: calling QGuiApplication::setFont
|
||||
// at runtime updated `QGuiApplication::font()` and left an already-built
|
||||
// `Text` on its old family. So the font has to be set before the UI is built,
|
||||
// which means the families have to be REGISTERED before that — and a family
|
||||
// is only registered once something loads its file.
|
||||
//
|
||||
// Hence this document: `QQmlApplicationEngine::load` returns with its
|
||||
// FontLoaders already in the font database (verified: the family is present
|
||||
// the instant load() returns), so main.rs can set the application font in the
|
||||
// gap between this document and Main.qml.
|
||||
//
|
||||
// It is deliberately NON-VISUAL — a QtObject, not a Window — so loading it
|
||||
// adds a root object and nothing else.
|
||||
//
|
||||
// The five faces are settings_qt::APP_FONT_VALUES, in that order. Inter is
|
||||
// here too: it is the app's own face, named by Main.qml for the Controls, and
|
||||
// it needs registering for exactly the same reason.
|
||||
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
readonly property FontLoader inter: FontLoader { source: "assets/fonts/Inter_18pt-Regular.ttf" }
|
||||
readonly property FontLoader interMedium: FontLoader { source: "assets/fonts/Inter_18pt-Medium.ttf" }
|
||||
readonly property FontLoader interSemiBold: FontLoader { source: "assets/fonts/Inter_18pt-SemiBold.ttf" }
|
||||
readonly property FontLoader interBold: FontLoader { source: "assets/fonts/Inter_18pt-Bold.ttf" }
|
||||
readonly property FontLoader lineSeed: FontLoader { source: "assets/fonts/LINESeedJP-Regular.ttf" }
|
||||
readonly property FontLoader montserrat: FontLoader { source: "assets/fonts/Montserrat-VariableFont_wght.ttf" }
|
||||
readonly property FontLoader notoSans: FontLoader { source: "assets/fonts/NotoSans-VariableFont_wdth,wght.ttf" }
|
||||
readonly property FontLoader sourceSans3: FontLoader { source: "assets/fonts/SourceSans3-VariableFont_wght.ttf" }
|
||||
}
|
||||
+10
-28
@@ -179,36 +179,18 @@ ApplicationWindow {
|
||||
// own loader into every row it renders in.
|
||||
FontLoader { id: lineSeed; source: "assets/fonts/LINESeedJP-Regular.ttf" }
|
||||
|
||||
// ── Settings > Appearance > Typography & Language > Font ───────────────
|
||||
// The app-wide typeface. Every Text in the tree that does not name a
|
||||
// family of its own inherits THIS one, which is why the setting lives on
|
||||
// the ApplicationWindow and applies live with no restart.
|
||||
// Settings > Appearance > Typography & Language > Font — the CONTROLS half.
|
||||
//
|
||||
// The catalog is settings_qt::APP_FONT_VALUES and the index rides
|
||||
// `QbzShell.appFontIndex` — a property of its own rather than a read out
|
||||
// of settingsJson, so the root window does not parse the whole settings
|
||||
// document to find one integer.
|
||||
// The app's own text does not come from here: a plain `Text` takes the
|
||||
// APPLICATION font at construction, which main() sets before this document
|
||||
// is even loaded (see qml/FontPreload.qml for the measurements). What this
|
||||
// line still owns is Qt Quick Controls, which follow ApplicationWindow.font
|
||||
// and would otherwise sit on Inter while every label around them moved.
|
||||
//
|
||||
// LAZY, exactly like the lyrics panel's own picker
|
||||
// (shell/LyricsLinesView.qml:66-80): a family nobody selected is never
|
||||
// loaded, and a family that has not FINISHED loading falls back to Inter
|
||||
// rather than rendering the app in a wrong face for a frame.
|
||||
FontLoader { id: appMontserrat; source: QbzShell.appFontIndex === 2 ? "assets/fonts/Montserrat-VariableFont_wght.ttf" : "" }
|
||||
FontLoader { id: appNoto; source: QbzShell.appFontIndex === 3 ? "assets/fonts/NotoSans-VariableFont_wdth,wght.ttf" : "" }
|
||||
FontLoader { id: appSource; source: QbzShell.appFontIndex === 4 ? "assets/fonts/SourceSans3-VariableFont_wght.ttf" : "" }
|
||||
readonly property string appFontFamily: {
|
||||
if (QbzShell.appFontIndex === 1)
|
||||
return lineSeed.status === FontLoader.Ready ? lineSeed.name : ""
|
||||
if (QbzShell.appFontIndex === 2)
|
||||
return appMontserrat.status === FontLoader.Ready ? appMontserrat.name : ""
|
||||
if (QbzShell.appFontIndex === 3)
|
||||
return appNoto.status === FontLoader.Ready ? appNoto.name : ""
|
||||
if (QbzShell.appFontIndex === 4)
|
||||
return appSource.status === FontLoader.Ready ? appSource.name : ""
|
||||
return ""
|
||||
}
|
||||
font.family: window.appFontFamily !== ""
|
||||
? window.appFontFamily
|
||||
// "" = System, i.e. leave Qt's own choice alone, which is what this app
|
||||
// rendered before the setting existed.
|
||||
font.family: QbzShell.appFontFamily !== ""
|
||||
? QbzShell.appFontFamily
|
||||
: (interRegular.status === FontLoader.Ready ? interRegular.name : "Sans Serif")
|
||||
|
||||
// Phase 23: every domain singleton boots (registers its Qt-thread
|
||||
|
||||
@@ -246,7 +246,7 @@ Column {
|
||||
// means the window default, which is Inter (Main.qml).
|
||||
SettingRow {
|
||||
label: QbzSession.tr("Font", QbzSession.trRev)
|
||||
description: QbzSession.tr("The typeface used across the app. Only fonts shipped with QBZ are offered, so the choice looks the same on every machine.", QbzSession.trRev)
|
||||
description: QbzSession.tr("The typeface used across the app. Only fonts shipped with QBZ are offered, so the choice looks the same on every machine (requires restart)", QbzSession.trRev)
|
||||
QbzSelect {
|
||||
menuWidth: 200
|
||||
options: root.doc.appFonts || []
|
||||
|
||||
Reference in new issue
Block a user