Skip to content

[Bug]: on Linux, captions follow the zoom and the 3D rotation — Windows and macOS keep them in place #397

Description

@EtienneLescot

Search existing issues

  • I have searched the existing issues

Describe the bug

On Linux, captions move and grow with the zoom, and drift again when a 3D rotation preset is applied. On Windows and macOS the same project renders them nailed in place. The divergence is in the native compositor, and it is one line of arithmetic.

Captions are not a layer of their own — they are projected into text annotations (captionCuesToTextRegions), and SceneAnnotation's coordinate contract is explicit about the space those live in (src/native/sceneDescription.ts:102-106):

x/y/w/h are fractions of the SCREEN layer's rect, not of the output frame … And they are deliberately NOT affected by the zoom crop: the overlay is a sibling of the element carrying the zoom transform, so annotations hold still while the content zooms underneath them.

plan_frame hands each backend both rects for exactly that reason — s_dst, the screen box (which the zoom moves and grows), and s_ann, the same box before the zoom's remap_box (frame_geometry.rs:725-736).

Windows and macOS anchor annotations on s_ann:

Linux anchors them on s_dstcompositor_linux.rs:1327-1332:

let dst = [
    g.s_dst[0] + a.x * g.s_dst[2],
    g.s_dst[1] + a.y * g.s_dst[3],
    a.w * g.s_dst[2],
    a.h * g.s_dst[3],
];

and sizes the text off the same wrong rect — compositor_linux.rs:1478:

font_size_px: text.font_size_rel * (g.s_dst[3] * rh),

So under a zoom the caption band is translated, scaled, and its font grows — at scale 2.5 the band runs past the frame edge and the text is clipped.

Why the 3D rotation shows it too. A rotation preset is a property of a zoom region, so applying iso/left/right brings the zoom box with it. The band therefore moves — and it stays axis-aligned while the screen quad tilts, so it does not even land on the tilted plane. Two symptoms, one cause.

How it got here

s_ann was introduced by 81839f0 ("fix(compositor): annotations et sous-titres ne suivent plus le zoom"), which fixed the very same user report — "les sous-titres étaient zoomés avec le screen recording" — after #179 moved the zoom from the source cut into the box. That commit touched exactly two files: compositor_macos.rs and compositor_windows.rs. The Linux backend was ported from the pre-fix macOS code (bbf61ad, "draw text annotations in compositor_linux") and reproduced the old formula.

Nothing caught it. frame_geometry.rs's the_annotation_anchor_ignores_the_zoom proves plan_frame computes s_ann correctly on every platform — it says nothing about what a backend does with it. And tests/compose_linux.rs, the only place that renders Linux frames, is opt-in (OPENSCREEN_LINUX_COMPOSE=1 + a fixture) and had no annotation-placement case.

Expected behavior

On Linux, exactly as on Windows and macOS: a caption stays where the user put it and keeps its size, whatever the zoom scale, the zoom focus, or the 3D rotation preset is doing underneath it — in the preview and in the export alike.

To Reproduce

  1. On Linux, record or import a clip and generate captions.
  2. Add a zoom region (scale 2 or more) overlapping the captions; optionally give it a 3D rotation preset.
  3. Scrub the playhead into the zoom region.
  4. The caption band moves and grows with the zoom; at a high scale it runs past the frame edge and the text is clipped. Exporting reproduces it exactly. The same project on Windows or macOS keeps the band in place.

Additional context

Both the preview and the export show it, and for the same reason: since the native compositor became the sole pixel source of the preview (PreviewCanvas.tsx:393-400"Sole pixel source … No more dual preview path"), annotation pixels are painted by compose_frame in both paths, from the scene that buildSceneDescription produces once. AnnotationOverlay.tsx now draws only the selection chrome. So there is no longer a DOM overlay quietly rendering the correct placement over a wrong one — what the Linux compositor computes is what the user sees while editing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstatus: fixed in mainWork is merged into main but may not be in a downloadable release yet.status: pending releaseMerged change is waiting for a packaged desktop release.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions