Watch
1
0
Fork
You've already forked souveraine
0

split chooser, home reaches the compositor, idle-inhibit comment was backwards

This commit is contained in:
Fimeg 2026-08-05 14:52:48 -04:00
commit b0688bc30b
4 changed files with 130 additions and 12 deletions

View file

@ -230,8 +230,14 @@ PanelWindow {
GlobalStates.overviewOpen = false
GlobalStates.dockRevealed = false
GlobalStates.oskOpen = false
Quickshell.execDetached(["hyprctl", "dispatch",
"hl.dsp.focus({ workspace = 1 })"])
// The compositor's own verb, not `hyprctl dispatch` — that binary
// is not running under viewtop, so this call went nowhere and Home
// silently stopped existing. Square one has to be reachable: it is
// the state you get back to when everything else is confusing, and
// a phone whose Home does nothing is one wrong gesture from being
// stuck. `workspace` is served on the control socket and takes the
// zone to go to.
ViewtopControl.zone(Config.options.navigation?.homeZone ?? 1)
}
// Commit an upward gesture. `stage` is the stage the drag settled on

View file

@ -48,6 +48,8 @@ Scope {
// a blank sheet nobody can explain.
property int target: 0
property bool sheetOpen: false
// Split has pinned a window and is waiting for the other half to be filled.
property bool choosing: 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.
@ -64,6 +66,7 @@ Scope {
function dismiss() {
scope.sheetOpen = false;
scope.choosing = false;
scope.target = 0;
}
@ -98,6 +101,12 @@ Scope {
// The window is gone or moved; the sheet has nothing left to be
// about. Kept open for `pose`-style verbs would mean a sheet
// pointing at a window that is no longer where it was.
//
// Except mid-Split: that `place` is the *first half* of a flow, and
// dismissing on it would close the sheet before the chooser could
// ask which window fills the other half.
if (scope.choosing)
return;
if (intent === "close" || intent === "kill" || intent === "place")
scope.dismiss();
}
@ -137,8 +146,68 @@ Scope {
Behavior on opacity { NumberAnimation { duration: 120 } }
}
// The chooser for Split's other half. Sits in the bottom half —
// where the window it is choosing for will land — so the gesture
// reads as "put something here" rather than as a menu that happens
// to be on screen.
ColumnLayout {
visible: scope.choosing
anchors.horizontalCenter: parent.horizontalCenter
y: parent.height * 0.58
spacing: 14
StyledText {
Layout.alignment: Qt.AlignHCenter
text: ViewtopControl.windows.length > 1
? "fill the other half"
: "nothing else is open"
color: "#e6ffffff"
font.pixelSize: Appearance.font.pixelSize.normal
}
Repeater {
model: ViewtopControl.windows.filter(w => w.id !== scope.target)
delegate: Rectangle {
required property var modelData
Layout.alignment: Qt.AlignHCenter
implicitWidth: 220
implicitHeight: 56
radius: 14
color: pick.pressed
? Appearance.colors.colLayer2
: Appearance.colors.colLayer1
border.width: 1
border.color: Appearance.colors.colLayer1Active
StyledText {
anchors.centerIn: parent
// The compositor answers with ids, not titles —
// `workspaces` carries {id, workspace}. A title
// needs foreign-toplevel, which is a separate
// lookup; showing the id is honest until then.
text: "window " + parent.modelData.id
color: Appearance.colors.colOnLayer1
font.pixelSize: Appearance.font.pixelSize.small
}
MouseArea {
id: pick
anchors.fill: parent
onClicked: {
ViewtopControl.place(parent.modelData.id, 0,
win.height / 2, win.width, win.height / 2);
scope.choosing = false;
scope.dismiss();
}
}
}
}
}
// The row. Above centre so a thumb does not cover the window.
RowLayout {
visible: !scope.choosing
anchors.horizontalCenter: parent.horizontalCenter
y: parent.height * 0.38
spacing: 28
@ -159,16 +228,18 @@ Scope {
SheetButton {
icon: "splitscreen"
label: "Split"
// Split pins this window to one half and the other half
// wants a chooser — open apps from the overview, or the
// app list. That chooser is the missing half and it has no
// verb yet, so this places the window and says so rather
// than pretending the flow is finished.
// Pin this window to the top half, then offer the other
// half to something already open. Casey's shape: "the
// second waiting one possibly having a button to add an
// already opened one from the multitasking section".
//
// The list is queried, not assumed — a chooser offering a
// window that has since closed would `place` a dead id and
// refuse, which reads as the button being broken.
onTapped: {
ViewtopControl.place(scope.target, 0, 0, win.width, win.height / 2);
refusal.text = "pinned to the top half — chooser for the other half is not built yet";
refusal.opacity = 1;
refusalFade.restart();
ViewtopControl.refreshWindows();
scope.choosing = true;
}
}