Ask the window how tall it is, and say when the column belongs below

D-N7 puts the develop column under the photograph on a tall window, and the
axis it turns on is aspect rather than width: a 960-wide portrait tablet is
expanded by width and wants the dock, a 1500-wide landscape desktop is
expanded by width and does not. So this cannot be folded into the layout
class, and it is not remembered per class either — closing the column in
landscape closes the dock in portrait, because it is the same column.

`window-resized` reported width alone and now reports both, from a
`shell-height` that subtracts the safe-area insets exactly as `shell-width`
subtracts them: on Android the strips the status and navigation bars occupy
are on the axis being measured, so the aspect of the window and the aspect of
the space the interface actually gets are not the same number.

`column_below` is the decision, with two thresholds rather than one. It is
read on every resize event, and a single threshold means a window dragged
along its own diagonal crosses it several times a second while the pointer is
still down. Entering at 1.25 and leaving at 1.15 is a dead band no plausible
drag re-crosses.

The comment on EXPANDED_MIN_WIDTH claimed a tablet in portrait gets the
compact layout. It does not — its panel is about 960 logical pixels across,
which clears 820 — and that mistaken example is the one D-N2 reasoned from.
Corrected in the same breath, since this is the commit that says what
portrait actually changes.
This commit is contained in:
2026-09-07 20:00:50 +02:00
parent 30468c4c69
commit 5f0b11c1f4
2 changed files with 181 additions and 11 deletions
+37 -5
View File
@@ -1107,6 +1107,23 @@ export component AppWindow inherits Window {
/// smaller fault than one briefly clipped.
in property <length> panel-max-width: 520px;
/// TRACES: FR-UI-1
/// Whether the develop column sits under the photograph rather than beside
/// it (D-N7).
///
/// **Not a layout class.** The class is decided by the window's width and
/// says how much room there is; this is decided by its aspect and says
/// which way round that room is, so a 960-wide portrait window is
/// `expanded` *and* docked while a 1500-wide landscape one is `expanded`
/// and not. Nothing here reads it but the develop view's frame, and
/// nothing remembers it: closing the column in landscape closes the dock
/// in portrait, because it is the same column.
///
/// From Rust for the reason `panel-max-width` above is — the frame reads
/// it to lay itself out, so deriving it from `root.width` in the frame
/// would be a property that both feeds and follows the layout.
in property <bool> column-below: false;
// --- local adjustments (FR-DEV-3) ---------------------------------------
/// The false-coloured region map, drawn over the photograph.
@@ -1316,7 +1333,7 @@ in property <bool> panel-visible: true;
callback back-requested() -> bool;
callback canvas-resized(int, int);
callback window-resized(length);
callback window-resized(length, length);
/// The width the interface actually has to lay out in.
///
@@ -1326,8 +1343,24 @@ in property <bool> panel-visible: true;
property <length> shell-width:
root.width - root.safe-area-insets.left - root.safe-area-insets.right;
// One-way: report width outward, never read layout back into it.
changed shell-width => { root.window-resized(self.shell-width); }
/// The height it has, for the same reason and with the same caveat.
///
/// Reported alongside the width because the develop view's frame is
/// decided by the *aspect* of what the interface actually gets, not of the
/// window (D-N7) — and on Android those differ by the height of the status
/// and navigation bars, which is exactly the axis being measured.
property <length> shell-height:
root.height - root.safe-area-insets.top - root.safe-area-insets.bottom;
// One-way: report the size outward, never read layout back into it. Two
// handlers because Slint has no single "geometry changed" hook — the same
// shape as `canvas-resized`'s px-w/px-h below.
changed shell-width => {
root.window-resized(self.shell-width, self.shell-height);
}
changed shell-height => {
root.window-resized(self.shell-width, self.shell-height);
}
// Everything the interface draws lives inside this, for two reasons that
// happen to want the same element.
@@ -1351,8 +1384,7 @@ in property <bool> panel-visible: true;
x: root.safe-area-insets.left;
y: root.safe-area-insets.top;
width: root.shell-width;
height: root.height - root.safe-area-insets.top
- root.safe-area-insets.bottom;
height: root.shell-height;
// Deliberately does *not* focus itself.
//