Fix: Never pair exclusionMode with exclusiveZone

Quickshell's exclusiveZone setter flips exclusionMode back to Normal as a
side effect, so a window declaring both is at the mercy of which property
the QML engine applies last. The 2026-09-14 Qt update changed that order
and every full-screen overlay slid under the bar.

Each overlay now declares ExclusionMode.Ignore alone. The capture picker
was the visible failure: it started under the bar, the full-output freeze
frame was squeezed into a shorter box, and every selection landed one
bar-height off in the real capture.

tests/quickshell/exclusion-idiom-contract fails any file that pairs them.
This commit is contained in:
Gabriel Brown
2026-09-14 14:36:24 -04:00
parent c1bbc69c8a
commit cceb7a707b
13 changed files with 61 additions and 12 deletions
@@ -27,9 +27,13 @@ PanelWindow {
right: true
}
// Fullscreen overlays must not reserve space, or every window on the
// workspace gets resized as the picker opens and closes.
exclusiveZone: 0
// Ignore, and nothing else: reserve no space (or every window on the
// workspace resizes as the picker opens and closes) and respect nobody's
// (or the window starts under the bar, the full-output freeze frame is
// squeezed into a shorter box, and every selection lands one bar-height
// off in the real capture). Never pair this with exclusiveZone; see
// tests/quickshell/exclusion-idiom-contract.
exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "qs-capture" // matched by a layerrule in hypr/rules.lua
WlrLayershell.layer: WlrLayer.Overlay
@@ -57,7 +57,6 @@ PanelWindow {
anchors { top: true; bottom: true; left: true; right: true }
color: "transparent"
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
// The `^qs-popover` prefix rule in hypr/rules.lua blurs what is behind
@@ -55,7 +55,6 @@ PanelWindow {
color: "transparent"
// A dock that reserved space would not be intellihiding.
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
// Matched by the `qs-dock` layer rule in hypr/rules.lua — do not rename.
@@ -40,7 +40,6 @@ PanelWindow {
anchors { top: true; bottom: true; left: true; right: true }
color: "transparent"
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
// Blurred by the `^qs-popover` rule in hypr/rules.lua; the scrim is painted
@@ -44,7 +44,6 @@ PanelWindow {
// Reserve nothing and respect nothing: the glow is drawn over the whole
// output including under the bar and the dock, which is what makes it
// visible from wherever the eyes happen to be.
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
color: "transparent"
@@ -29,7 +29,6 @@ PanelWindow {
screen: root.modelData
anchors.bottom: true
margins.bottom: Theme.dockIconSize + Theme.dockPadding * 2 + Theme.barGap * 3
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
implicitWidth: root.desiredWidth
implicitHeight: 64
@@ -22,7 +22,6 @@ PanelWindow {
}
color: "transparent"
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
// Matched by the `qs-overlay` layer rule in hypr/rules.lua — do not rename.
@@ -22,7 +22,6 @@ Variants {
implicitWidth: 260
implicitHeight: 172
color: "transparent"
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
mask: Region {}
@@ -383,6 +383,13 @@ Lua-configured Hyprland, prints the refusal to stdout, and exits 0. `eval` exits
0 on syntax and runtime errors too. The only trustworthy signal that a write
landed is reading the value back.
**`exclusionMode: ExclusionMode.Ignore` goes alone.** Quickshell's `exclusiveZone`
setter flips `exclusionMode` back to `Normal` as a side effect, so a window that
declares both is at the mercy of which property the QML engine applies last.
The 2026-09-14 Qt update changed that order and every full-screen overlay slid
under the bar. `tests/quickshell/exclusion-idiom-contract` fails any file that
pairs them.
**The Settings window is tiled.** `implicitWidth` is a hint; the layout decides,
and it ranges from a half-screen split to the full display. `SliderRow` stacks
its control under the label below 520px. Test narrow.
@@ -78,7 +78,6 @@ PanelWindow {
anchors { top: true; bottom: true; left: true; right: true }
color: "transparent"
exclusiveZone: 0
exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "qs-popover-welcome"