sheet: let zoom reach a window
pose has been in the wire since 2026-08-05 with no caller — poseActiveZone was the only one, and TASK-60 deleted it. Zoom composes pixels the client already drew; Resize places a new rectangle and the client relays out inside it.
This commit is contained in:
parent
f06bb8394e
commit
75cb392924
1 changed files with 67 additions and 0 deletions
|
|
@ -59,6 +59,20 @@ Scope {
|
|||
// tapping Resize twice in two visits should continue the cycle, not restart
|
||||
// it and appear to do nothing.
|
||||
property int sizeStep: 0
|
||||
// Which pose Zoom last applied, on the scope for the same reason as
|
||||
// `sizeStep`: the cycle has to survive the sheet closing.
|
||||
property int poseStep: 0
|
||||
|
||||
// Whether the subject has left its zone's confinement, as the compositor
|
||||
// last reported it. Read, never remembered — a shell that kept its own idea
|
||||
// of this would draw Unfloat on a window something else had already put
|
||||
// back.
|
||||
readonly property bool targetFloating: {
|
||||
for (const w of ViewtopControl.windows)
|
||||
if (w.id === scope.target)
|
||||
return w.floating === true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// How long a hold on Close means kill. Longer than a tap could ever be,
|
||||
// short enough that a stuck app does not feel like a negotiation.
|
||||
|
|
@ -364,6 +378,59 @@ Scope {
|
|||
}
|
||||
}
|
||||
|
||||
SheetButton {
|
||||
icon: "zoom_out_map"
|
||||
label: "Zoom"
|
||||
// The `pose` verb, reaching a window for the first time.
|
||||
//
|
||||
// `pose` has existed in the wire and the compositor since
|
||||
// 2026-08-05 — it genuinely scales content, not only moves
|
||||
// it — and **nothing in the shell has ever called it**.
|
||||
// `poseActiveZone` did, and TASK-60 deleted that wrapper as
|
||||
// the shell's half of the two-writer bug, which took the
|
||||
// only caller with it. Casey, 2026-08-16: *"I can move
|
||||
// windows but the zooming them in and out didn't work
|
||||
// yet."* It did not work because nobody asked.
|
||||
//
|
||||
// Distinct from Resize, and the difference is load-bearing:
|
||||
// Resize `place`s a different *rectangle* and the client
|
||||
// relays out inside it. Zoom composes the pixels it already
|
||||
// drew — the client is never told, its layout does not
|
||||
// move, and the compositor maps input back through the
|
||||
// inverse so a shrunken window is still touchable where it
|
||||
// is drawn.
|
||||
//
|
||||
// Identity is a step in the cycle rather than a separate
|
||||
// Reset: a pose the user cannot get out of with the button
|
||||
// they got into it with is a trap.
|
||||
onTapped: {
|
||||
scope.poseStep = (scope.poseStep + 1) % 3;
|
||||
const scale = [1.0, 0.85, 0.7][scope.poseStep];
|
||||
ViewtopControl.pose(scope.target, scale, 0.0, 0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
SheetButton {
|
||||
icon: scope.targetFloating ? "picture_in_picture_off"
|
||||
: "picture_in_picture"
|
||||
label: scope.targetFloating ? "Unfloat" : "Float"
|
||||
// A float leaves the zone's confinement — it stops being
|
||||
// the zone's business, so the strip no longer counts it
|
||||
// when deciding whether a zone still holds anything.
|
||||
//
|
||||
// Which is exactly why the label has to flip: a float is
|
||||
// the one window you can no longer find by remembering
|
||||
// which zone you left it on, so the way back out must be
|
||||
// the same button, in the same place, saying so.
|
||||
onTapped: {
|
||||
if (scope.targetFloating)
|
||||
ViewtopControl.unfloat(scope.target);
|
||||
else
|
||||
ViewtopControl.float(scope.target);
|
||||
ViewtopControl.refreshWindows();
|
||||
}
|
||||
}
|
||||
|
||||
SheetButton {
|
||||
icon: "splitscreen"
|
||||
label: "Split"
|
||||
|
|
|
|||
Loading…
Reference in a new issue