Follow the canvas from one display to the next
The rest of FR-DSP-8. The develop session now carries the space its canvas is encoded into, and `render` composes for it instead of for sRGB — which is the whole of the change to the pixel path, because the output space was always a parameter of composition and always entered the structure hash. A display change is a recomposition. The space is set on the way into every render rather than pushed when the window moves, so a photograph opened while the window already sits on the second monitor is right on its first frame instead of flashing the wrong colour until the next poll. Which display that is comes from sampling the window's position and scale factor twice a second — Slint reports neither a move nor a display change — and re-surveying only when they differ. Settings shows what came back under ABOUT: the display, the space, why, and the other monitors, because the failure FR-DSP-8 names is one that is invisible from the display you are reading the page on. Fractional scaling: the canvas is now rendered at the physical pixel size of the box it occupies rather than the logical one, so the compositor presents it 1:1. At 1.25 it was previously handed 1600 samples to fill 2000 device pixels, and the softness that produces reads like a bad demosaic rather than like a scaling bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+18
-5
@@ -275,6 +275,13 @@ export component AppWindow inherits Window {
|
||||
in property <string> adapter: "detecting…";
|
||||
in property <string> backend: "—";
|
||||
in property <int> fps: 0;
|
||||
/// TRACES: FR-DSP-8
|
||||
/// The display showing the canvas and the colour transform it is getting.
|
||||
/// Shown under ABOUT in Settings; see `settings.slint` for why the second
|
||||
/// one is a sentence rather than a name.
|
||||
in property <string> display-name: "detecting…";
|
||||
in property <string> display-colour: "detecting…";
|
||||
in property <string> display-others: "";
|
||||
/// TRACES: FR-UI-2
|
||||
/// Set from `CARGO_PKG_VERSION`, so the About line cannot disagree with
|
||||
/// the binary it is part of.
|
||||
@@ -1264,6 +1271,9 @@ in property <bool> panel-visible: true;
|
||||
fps: root.fps;
|
||||
layout-class: root.layout-class;
|
||||
app-version: root.app-version;
|
||||
display-name: root.display-name;
|
||||
display-colour: root.display-colour;
|
||||
display-others: root.display-others;
|
||||
|
||||
original-budget: root.settings-original-budget;
|
||||
original-unlimited: root.settings-original-unlimited;
|
||||
@@ -1695,11 +1705,14 @@ in property <bool> panel-visible: true;
|
||||
// that far. Below 1:1 it stays smooth, where filtering is
|
||||
// what keeps the image from aliasing.
|
||||
//
|
||||
// This matters even at moderate zoom on a HiDPI display:
|
||||
// the canvas is rendered at *logical* size and Slint scales
|
||||
// it up by the device pixel ratio, so the buffer is
|
||||
// resampled on its way to the screen whatever the pipeline
|
||||
// did.
|
||||
// TRACES: FR-DSP-8
|
||||
// The canvas is rendered at the *physical* pixel size of
|
||||
// the box this image occupies, so `contain` presents it
|
||||
// 1:1 and neither filter is reached at all until the
|
||||
// photographer zooms. That is the point: on a fractionally
|
||||
// scaled desktop the buffer used to be a logical-sized one
|
||||
// that the compositor stretched, and no choice of filter
|
||||
// recovers detail that was never rendered.
|
||||
image-rendering: root.magnified
|
||||
? ImageRendering.pixelated
|
||||
: ImageRendering.smooth;
|
||||
|
||||
Reference in New Issue
Block a user