Files
nvrlandClaude Opus 5.5 9af24ccf87 theme: workspaces drift behind the hull instead of over the bar
The hull moves to the top layer, with its transparent opening and empty input
region, so windows sliding out of the opening during a workspace switch pass
behind the frame like things behind a porthole rim rather than drawing over
the bar. A layer rule keeps the bar and the rail above it on that layer.

The animation tree is redone around that: workspaces drift 18% vertically
and fade on a slow, jolt-free "drift" curve; the SUPER+S scratchpad slides in
whole from under the bar, the same gesture as the dashboard and popouts;
windows and layers keep their calm resolve and fade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 21:13:11 +02:00

125 lines
3.9 KiB
QML

import QtQuick
import QtQuick.Shapes
import Quickshell
import Quickshell.Wayland
import "root:/config"
// The hull: one surface for the bar, the rail and the thin band down the left
// and along the bottom, with the desktop as a rounded opening cut out of it.
// The idea is caelestia's screen border; the reading is the wallpaper's — you
// are inside the ship, and the windows sit in the porthole.
//
// The hull lives on the top layer, over every window, and its opening is
// transparent with no input region, so it covers nothing inside the opening
// and catches no clicks. Being above the windows is the point: a workspace
// switch slides windows *behind* the frame, the way things pass behind the
// rim of a porthole, instead of drawing over the bar. A fullscreen window
// still covers it, since Hyprland draws fullscreen above the top layer.
// hypr/lua/rules/layers.lua orders it under the bar and the rail.
//
// The bar and the rail draw no surface of their own and ignore exclusive
// zones, so every piece is placed from the screen edge. The four zones are
// reserved here instead, by windows that draw nothing — that way the usable
// area is exactly the opening, whichever surface the compositor arranges
// first.
Scope {
id: root
required property var modelData
PanelWindow {
id: hull
screen: root.modelData
WlrLayershell.layer: WlrLayer.Top
WlrLayershell.namespace: "takemi-frame"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
exclusionMode: ExclusionMode.Ignore
anchors {
top: true
bottom: true
left: true
right: true
}
color: "transparent"
mask: Region {}
// The opening, in window coordinates.
readonly property real x0: Theme.frame
readonly property real y0: Theme.barHeight
readonly property real x1: width - Theme.railWidth
readonly property real y1: height - Theme.frame
readonly property real r: Theme.frameRadius
readonly property string opening: {
const x0 = hull.x0, y0 = hull.y0, x1 = hull.x1, y1 = hull.y1, r = hull.r;
return `M ${x0 + r} ${y0} H ${x1 - r} A ${r} ${r} 0 0 1 ${x1} ${y0 + r}`
+ ` V ${y1 - r} A ${r} ${r} 0 0 1 ${x1 - r} ${y1}`
+ ` H ${x0 + r} A ${r} ${r} 0 0 1 ${x0} ${y1 - r}`
+ ` V ${y0 + r} A ${r} ${r} 0 0 1 ${x0 + r} ${y0} Z`;
}
Shape {
anchors.fill: parent
preferredRendererType: Shape.CurveRenderer
// The hull itself: the whole screen, minus the opening.
ShapePath {
fillColor: Theme.hull
fillRule: ShapePath.OddEvenFill
strokeColor: "transparent"
PathSvg {
path: `M 0 0 H ${hull.width} V ${hull.height} H 0 Z ` + hull.opening
}
}
// The rim — a hairline round the opening, the lit edge of the
// porthole in the wallpaper.
ShapePath {
fillColor: "transparent"
strokeColor: Theme.rim
strokeWidth: 1
PathSvg {
path: hull.opening
}
}
}
}
ExclusionZone {
anchors.top: true
exclusiveZone: Theme.barHeight
}
ExclusionZone {
anchors.right: true
exclusiveZone: Theme.railWidth
}
ExclusionZone {
anchors.bottom: true
exclusiveZone: Theme.frame
}
ExclusionZone {
anchors.left: true
exclusiveZone: Theme.frame
}
component ExclusionZone: PanelWindow {
screen: root.modelData
WlrLayershell.layer: WlrLayer.Bottom
WlrLayershell.namespace: "takemi-frame-zone"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
mask: Region {}
implicitWidth: 1
implicitHeight: 1
}
}