pragma ComponentBehavior: Bound import Quickshell import Quickshell.Hyprland import Quickshell.Wayland import QtQuick import qs.widgets.theme // Debug stage: a bare, chrome-less staging area in the middle of ONE monitor // (the secondary by default), used to look at a widget in isolation before it // has a home in the bar or a launcher. // // DebugWindow { // VitalBar { width: 220; value: 0.4 } // } // // Children are reparented into the centred slot, which sizes itself to them — // so they must carry their own size (implicit or explicit). Do NOT anchor a // child to the slot (`anchors.fill: parent`): the slot measures its children, // so that is a binding loop. // // Nothing is drawn around them — no panel, no background, no dim: whatever is // staged is exactly what appears. Only the staged widgets take pointer input // (`mask`), so the rest of the monitor stays clickable, and the window never // takes keyboard focus. Toggle: SUPER CTRL D. Scope { id: root // Monitor to stage on. Falls back to the LAST connected screen when the // name matches nothing, so a single-monitor session still gets a stage. property string screenName: "HDMI-A-1" property bool active: true default property alias content: slot.data // Quickshell.screens is a QML list, not a JS array — no .find() on it. readonly property var targetScreen: { const screens = Quickshell.screens; if (screens.length === 0) return null; for (let i = 0; i < screens.length; i++) { if (screens[i].name === root.screenName) return screens[i]; } return screens[screens.length - 1]; } function toggle() { root.active = !root.active; } GlobalShortcut { name: "debug" description: "Toggle the debug widget stage" onPressed: root.toggle() } PanelWindow { id: win screen: root.targetScreen visible: root.active && root.targetScreen !== null WlrLayershell.layer: WlrLayer.Overlay // A HUD, not a modal: never steal the keyboard from the focused window. WlrLayershell.keyboardFocus: WlrKeyboardFocus.None // Ignore the dense bar's exclusive zone so "centred" means the centre of // the monitor, not the centre of what is left below the bar. exclusionMode: ExclusionMode.Ignore color: "transparent" anchors { top: true left: true right: true bottom: true } // Everything outside the staged widgets is click-through. mask: Region { item: slot } Item { id: slot anchors.centerIn: parent width: Math.max(childrenRect.width, placeholder.visible ? placeholder.implicitWidth : 0) height: Math.max(childrenRect.height, placeholder.visible ? placeholder.implicitHeight : 0) } // Sits beside the slot, not inside it, so it never counts itself. Without // it an unsized child looks identical to a broken window. Text { id: placeholder visible: slot.children.length === 0 anchors.centerIn: parent text: "NO WIDGETS STAGED" color: Theme.muted font.family: Theme.microFont font.pixelSize: 8 font.letterSpacing: 1.2 } } }