Skip to main content

SCREENSHOTS

An app with no <screenshots> renders an empty frame in Bazaar, GNOME Software and Discover. Screenshots are also the one part of AppStream metadata that goes stale on its own: the app changes, the picture does not.

So CI generates them from the real app and references them from main. Nobody takes them by hand.

The shape​

.github/workflows/screenshots.yml runs on push to main
│ builds the app, then for each screen:
▼
tuna-os/flatpak-index/.github/actions/capture-screenshots
│ Xvfb + the app's own window + ImageMagick
▼
docs/screenshots/NN-name.png committed back to main
│ referenced by
▼
data/<app-id>.metainfo.xml <screenshot><image>raw.githubusercontent…/main/…

The workflow re-commits on every push to main, and the metainfo points at main. The pictures in the software centre follow the app with no further upkeep.

Using the shared action​

- uses: tuna-os/flatpak-index/.github/actions/capture-screenshots@main
with:
command: ./target/release/myapp
name: 01-main
out-dir: docs/screenshots # default
geometry: 1000x700 # default, Flathub's maximum
settle: "6" # seconds to let the window paint

It drives a real X server and photographs the application's own window. It is toolkit-agnostic: GTK, Qt, Electron and plain Xt apps all work, without an in-process harness written per toolkit.

It fails the job. It never publishes a bad image. It covers each case: the app exits before it maps a window, maps no window at all, or paints a blank one. In every failure it writes nothing, because a blank PNG left on disk looks like a real screenshot.

An app that renders its own screens more precisely should keep that setup. tuna-installer-kde renders each wizard step from the real QML module with only main.cpp swapped. That beats a photo of a live window because it can reach states a cold start cannot. Use the shared action when there is no such harness.

What to capture​

Follow Flathub's quality guidelines:

  • 3–6 screenshots for a typical app; one is the bare minimum.
  • Window only, no desktop background, default theme.
  • 1000×700 maximum (2000×1400 for HiDPI). The action defaults to 1000×700 and fits the window to it.
  • Captions: one sentence, no trailing period. Describe what the image shows, not the filename. Three captions from filenames were wrong; one described a language picker that does not exist.
  • The first entry should be type="default".

Checking it​

enrich-index.py reports any published app whose catalogue declares no screenshots:

curl -sSfL -o served.json https://tunaos.org/flatpak/index/static
./scripts/enrich-index.py served.json --check

Screenshot-less apps come back as ~ warnings, not ! problems: such an app is installable and correctly described, but poorly presented. The daily check-metadata.yml run surfaces them.