Compare commits

...

2 commits

Author SHA1 Message Date
af9ca8f212 quickshell: restore the full-width bar surface
Reverting the diagnostic. The narrow surface is still the right destination
but it needs the frame band drawn without adding a second full-screen
surface, which is what the reverted attempt got wrong.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 12:34:05 +01:00
9a873dacae Revert "quickshell: bar surface is the bar column, frame moves to its own background layer"
This reverts commit 89eaeca2f9.
2026-09-02 12:33:21 +01:00

View file

@ -1474,31 +1474,24 @@ in
// the grab — it self-clears and instantly closes the panel. // the grab — it self-clears and instantly closes the panel.
WlrLayershell.keyboardFocus: (launcherPanel.open || bar.activeDropdown !== null) && !bar.screenshotPinned ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None WlrLayershell.keyboardFocus: (launcherPanel.open || bar.activeDropdown !== null) && !bar.screenshotPinned ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
// Vertical bar on the left edge. // Vertical bar on the left edge. The surface still covers the
// whole screen (the frame band and every panel are drawn into
// it); only the reserved strip is the bar itself.
anchors { anchors {
top: true top: true
left: true left: true
bottom: true bottom: true
} }
// True while something is drawn outside the bar column and the // Screen-sized: the frame band and every panel are drawn into
// surface therefore has to span the screen. // this one surface. That AREA is this shell's main cost —
readonly property bool surfaceWide: bar.activeDropdown !== null // Hyprland blurs this namespace, and blur is recomputed
|| launcherPanel.visible || toastItem.visible // whenever what's behind the surface changes, which with a
// game underneath is every pixel every frame. Shrinking it to
// THE performance knob for this whole shell. Hyprland blurs // the bar column measured 57% -> 38% GPU. Doing that for real
// this namespace, and blur behind a surface is recomputed // needs the frame band drawn somewhere that is NOT another
// whenever what is BEHIND it changes — which, with a game // full-screen surface; see the wallpaper window.
// running underneath, is every pixel of the screen every implicitWidth: bar.screen.width
// frame. At 3440x1440 that measured ~a third of the card and
// halved framerates; at 46px it is free. So the surface is the
// bar column at rest and only grows while a panel, the toast
// or the launcher is actually on screen, where a momentary
// cost doesn't matter.
//
// exclusiveZone stays fixed at barWidth, so windows never
// reflow when this resizes.
implicitWidth: bar.surfaceWide ? bar.screen.width : Theme.barWidth
exclusiveZone: Theme.barWidth exclusiveZone: Theme.barWidth
color: "transparent" color: "transparent"
@ -1986,9 +1979,9 @@ in
// buries a full corner radius inside the bar column. // buries a full corner radius inside the bar column.
readonly property real surfLeftX: Theme.barWidth - meltInto / 2 readonly property real surfLeftX: Theme.barWidth - meltInto / 2
property vector4d cutout: Qt.vector4d( property vector4d cutout: Qt.vector4d(
(Theme.barWidth + bar.screen.width - Theme.frameWidth) / 2, (Theme.barWidth + bar.width - Theme.frameWidth) / 2,
bar.height / 2, bar.height / 2,
(bar.screen.width - Theme.frameWidth - Theme.barWidth) / 2, (bar.width - Theme.frameWidth - Theme.barWidth) / 2,
bar.height / 2 - Theme.frameWidth) bar.height / 2 - Theme.frameWidth)
property vector4d panel: chrome.visible property vector4d panel: chrome.visible
? Qt.vector4d(surfLeftX + chrome.width / 2, (panelTop + panelBottom) / 2, ? Qt.vector4d(surfLeftX + chrome.width / 2, (panelTop + panelBottom) / 2,
@ -2053,7 +2046,7 @@ in
NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo } NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo }
} }
x: Math.round((bar.screen.width - openW) / 2) x: Math.round((bar.width - openW) / 2)
y: bar.height - Theme.frameWidth - openH y: bar.height - Theme.frameWidth - openH
width: openW width: openW
height: openH height: openH
@ -6811,64 +6804,6 @@ in
} }
} }
// ── Screen frame band, on its OWN background-layer surface.
//
// This used to be drawn into the bar's surface, and it is the
// reason that surface had to be screen-sized — which is what
// made blur behind it cost a third of the GPU. The frame is
// static decoration that never takes input, so it belongs
// below windows: no blur rule matches this namespace, nothing
// ever repaints it, and gaps_out keeps it visible.
//
// Hidden (the shader, not the window — mapping and unmapping a
// layer surface on every panel open would flicker) while the
// bar's own surface is wide, because chromeSdf then draws the
// frame itself and melts panels into it. Two translucent
// copies of the same band would read as a darker strip.
PanelWindow {
id: frameWin
screen: bar.screen
WlrLayershell.namespace: "quickshell-frame"
WlrLayershell.layer: WlrLayer.Background
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
exclusionMode: ExclusionMode.Ignore
anchors { top: true; left: true; right: true; bottom: true }
color: "transparent"
mask: Region {} // decoration only, never takes a click
ShaderEffect {
// Offset past the bar column so this and the bar never
// composite on top of each other.
x: Theme.barWidth
width: frameWin.width - Theme.barWidth
height: frameWin.height
visible: !bar.surfaceWide
// Push the cutout's left edge well off-item so only
// straight edges reach the bar column — a rounded
// corner landing here would leave a nub beside the bar.
readonly property real cutLeft: -2 * Theme.radius
readonly property real cutRight: width - Theme.frameWidth
property vector4d cutout: Qt.vector4d(
(cutLeft + cutRight) / 2,
height / 2,
(cutRight - cutLeft) / 2,
height / 2 - Theme.frameWidth)
// No panels down here — the bar's surface owns those.
property vector4d panel: Qt.vector4d(0, 0, 0, 0)
property vector4d toast: Qt.vector4d(0, 0, 0, 0)
property vector4d launcher: Qt.vector4d(0, 0, 0, 0)
property vector4d fillColor: Qt.vector4d(Theme.barBg.r, Theme.barBg.g, Theme.barBg.b, Theme.barBg.a)
property vector4d borderColor: Qt.vector4d(Theme.base03.r, Theme.base03.g, Theme.base03.b, 1)
property vector2d res: Qt.vector2d(width, height)
property real cutoutR: Theme.radius
property real panelR: Theme.radius
property real meltK: Theme.radius / 2
property real borderW: Theme.borderWidth
fragmentShader: "file://${chromeShader}"
}
}
// ── OSD: volume / brightness level, shown inline in the bar's // ── OSD: volume / brightness level, shown inline in the bar's
// empty middle — the gap between the two clusters exists for // empty middle — the gap between the two clusters exists for
// this. Volume is reactive: Pipewire reports changes from any // this. Volume is reactive: Pipewire reports changes from any