Skip to content

fix(android): use 14.67 body size - #290

Merged
JumpLink merged 5 commits into
mainfrom
fix/android-body-size
Nov 12, 2026
Merged

JumpLink merged 5 commits into
mainfrom
fix/android-body-size

Conversation

@JumpLink

@JumpLink JumpLink commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

Body, HtmlView and list text were 15 while the gjsify theme (GTK 11 pt at 96 dpi) uses 14.67.
The first commit aligned app.css and the vendored adwaita.css.

Second commit: stop re-declaring the ramp

app.css kept its own .title-* and .body font sizes on top of the theme it imports, and the
vendored adwaita.css was a snapshot old enough to predate the theme's current sizes — so the app
rendered a ramp matching neither GTK nor the theme.

Now the vendored copy is resynced from gjsify (which gained the full libadwaita ramp in
gjsify/gjsify#2583) and app.css keeps only what is really app-specific: the 12/12 margins and an
explicit HtmlView size. One source for the ramp, so the next theme change arrives with the
dependency bump instead of needing a second edit here.

Visible side effect of the resync, worth knowing before merge: .adw-preferences-group-title
11 → 14.67 and .adw-preferences-group-description 12 → 14.67. The old values came from the stale
snapshot; gjsify's canonical theme wins. Checked on the device in light, dark and at
font_scale 1.3 — no clipping, the groups just read at the size GTK uses.

Device verification

Galaxy S9, Android 10, density 3.5, built against a locally linked gjsify that carries #2583.
Line pitch measured by row projection of the screenshots:

before after
editor gutter pitch 73 px 61 px
tutorial code block pitch 73 px 61 px
prose pitch 62 px 62 px (unchanged)
code : prose 1.18 0.98 (GTK reference 1.00)

Matrix walked: light and dark, default palette plus a custom primary and a custom accent,
font_scale 1.0 and 1.3, portrait and landscape plus a live rotation, Learn/Code/Debug/Play,
keyboard open in the editor, Preferences, About and Details.

Checks: check:format, check:lint, check:versions all green.

Needs a gjsify release containing gjsify/gjsify#2583 — this PR was verified against a
gjsify link build, not a published version, so the dependency bump has to land before or with it.

Second and third commit: the app's half of the interface scale

The prose pitch row above (62 px before, 62 px after) was the honest answer at the time and also
the clue: the tutorial's body text was not following the theme at all. The MDX compiler puts
paragraph on every prose block, it is not an Adwaita class, so the gjsify theme does not carry
it — on GTK an undeclared label inherits the document font and looks right, on NativeScript it
falls through to the Android default text size, which no stylesheet reaches. Same shape as the
editor find in #2583, and the same fix: packages/app-android/app/app.css now states 14.67 for
.paragraph and for .gtksource-view (the class GtkSourceView puts on itself, whose driver
needs a declared size or keeps its own DEFAULT_FONT_SIZE).

With that, every text surface is reachable from the stylesheet, which is what the interface scale
needs. gjsify's new @gjsify/adwaita-nativescript/app-scale (third commit of gjsify/gjsify#2583)
multiplies every length in the sheet — font sizes and paddings, min-heights, radii, icon boxes —
by one factor. This PR is the app's half:

  • InterfaceScaleService owns the stored value: gschema key interface-scale as a string, either
    auto or a factor such as 1.25. A stored factor that is not offered maps to its nearest entry.
  • It hands the processed stylesheet to registerAppScaleCss via import appCss from "./app.css?inline" — ?inline, not ?raw, so Tailwind is expanded and the @imports inlined —
    and applies before themeService.init, which reappends the sheet whenever it rewrites the theme.
  • The Preferences row is a combo: "Automatic (114%)" first, then 100% to 150% in tenths. Picking
    Automatic again is the reset, so the group needs no second button. The row only exists where a
    scale service is passed in, so the GNOME and web dialogs are unchanged.
  • Text and spacing follow immediately; icon sizes are baked at render time and follow after a
    restart, which the group description states.

Device verification

Galaxy S9, density 3.5, 411.4 dp wide → derived factor 1.143. Measured at fresh starts:

100% auto (114%) 150%
editor gutter pitch 61 px 68 px 90 px
selected tab pill 136 px 156 px 205 px
header bar height 163 px 186 px 245 px
tutorial prose pitch 66 px 74 px —

The prose row before the .paragraph fix: 62 px at 100% and 63 px at auto, while the title-2
next to it grew 54 → 61. After it, the text band is 49 → 57 px tall and the pitch 66 → 74.

No double scaling with the system font size: at font_scale 1.3 and auto the editor pitch is
85 px against 68 px.

Matrix walked again on the final build: light and dark, default palette plus a custom accent,
font_scale 1.0 and 1.3, portrait and landscape plus a live rotation, all four pages, keyboard
open in the editor, Preferences, About and its Details page. No clipping.

Known limitation, not fixed here: the generated .blp sets margin-top/bottom: 12 directly on
each prose label, and in NativeScript a value set on the view wins over CSS, so those block margins
stay at 12 dip while the text grows. The native overflow menu and the combo's AlertDialog are
Android popups and follow the system font scale, not the app scale.

Checks

gjsify run check (all tsc projects), check:format, check:lint, check:versions and the i18n
gates green; catalogues regenerated with the new msgids and the German one filled.
check:metainfo fails locally on a weblate 403 (url-not-reachable), environmental.

Ordering, unchanged but now larger: app-android imports
@gjsify/adwaita-nativescript/app-scale, a subpath 0.64.27 does not publish. CI here fails until a
gjsify release carries #2577, #2579 and #2583 together, and the dependency bump lands with it.

`app.css` re-declared `.title-*` and `.body` font sizes on top of the
imported Adwaita theme, and the vendored `adwaita.css` was a snapshot
old enough to predate the theme's current sizes. The app therefore
rendered a ramp that matched neither GTK nor the theme it imports.

Resync the vendored copy from gjsify and keep only what is genuinely
app-specific in `app.css`: the 12/12 margins and the `HtmlView` size.
The ramp now comes from one place, so the next theme change arrives
with the dependency bump instead of needing a second edit here.

Measured on a Galaxy S9 (density 3.5, font_scale 1.0): code to prose
line pitch 1.18 -> 0.98, against 1.00 on the GTK build.
@JumpLink
JumpLink force-pushed the fix/android-body-size branch from 999000c to a010631 Compare November 10, 2026 23:21
Two text surfaces got their size from somewhere no stylesheet can
reach, so neither the theme nor anything layered on top of it could
move them:

- The code editor. `@gjsify/gtksource-nativescript` applies the
  resolved CSS `font-size` to the native `EditText` and falls back to
  its own `DEFAULT_FONT_SIZE` when no rule declares one. Nothing did.
- The tutorial prose. The MDX compiler puts `paragraph` on every prose
  block; it is not an Adwaita class, so the theme does not carry it. On
  GTK an undeclared label inherits the document font and looks right,
  on NativeScript it falls through to the Android default text size.

Both now state 14.67, the `.body` size they were meant to match.
On a phone the app draws every size for a 360 dp window, so on a wider
screen it reads smaller than the same app does on the desktop. gjsify's
new `@gjsify/adwaita-nativescript/app-scale` multiplies every length in
the stylesheet by one factor; this is the app's half of it.

`InterfaceScaleService` owns the stored value: the string key
`interface-scale`, either `auto` or a factor such as `1.25`. It hands
the PROCESSED stylesheet to `registerAppScaleCss` — `?inline`, not
`?raw`, so Tailwind is expanded and the `@import`s are inlined — and
applies before the theme service, which reappends the sheet whenever it
rewrites the theme.

The Preferences row is a combo: "Automatic (114%)" first, then 100% to
150% in tenths. Picking Automatic again IS the reset, so the group needs
no second button. A stored factor that is not offered shows as its
nearest entry. The row only exists where a scale service is passed in,
so GNOME and web keep the dialog they had.

Text and spacing follow immediately; icon sizes are baked at render time
and follow after a restart, which the group description says.
@JumpLink
JumpLink merged commit f4e3829 into main Nov 12, 2026
3 checks passed
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.

1 participant