import QtQuick import Quickshell import Quickshell.Wayland import "." as M // Shared hover/OSD panel PanelWindow — slides down from the bar on hover or // external trigger. Parent module computes showPanel and reads panelHovered. PanelWindow { id: root required property bool showPanel required property real anchorX required property color accentColor property string panelNamespace: "nova-panel" property real contentWidth: 220 property bool animateHeight: false property bool panelHovered: false default property alias content: panelContent.children screen: QsWindow.window?.screen ?? null visible: _winVisible color: "transparent" property bool _winVisible: false WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.exclusiveZone: 0 WlrLayershell.namespace: root.panelNamespace anchors.top: true anchors.left: true margins.top: 0 margins.left: Math.max(0, Math.min(Math.round(anchorX - implicitWidth / 2), (screen?.width ?? 1920) - implicitWidth)) implicitWidth: panelContent.width implicitHeight: panelContent.height Behavior on implicitHeight { enabled: root.animateHeight NumberAnimation { duration: 100 easing.type: Easing.OutCubic } } onShowPanelChanged: { if (showPanel) { _winVisible = true; hideAnim.stop(); showAnim.start(); } else { showAnim.stop(); hideAnim.start(); } } ParallelAnimation { id: showAnim NumberAnimation { target: panelContent property: "opacity" to: 1 duration: 120 easing.type: Easing.OutCubic } NumberAnimation { target: panelContent property: "y" to: 0 duration: 150 easing.type: Easing.OutCubic } } ParallelAnimation { id: hideAnim NumberAnimation { target: panelContent property: "opacity" to: 0 duration: 150 easing.type: Easing.InCubic } NumberAnimation { target: panelContent property: "y" to: -panelContent.height duration: 150 easing.type: Easing.InCubic } onFinished: root._winVisible = false } HoverHandler { onHoveredChanged: root.panelHovered = hovered } M.PopupBackground { x: panelContent.x y: panelContent.y width: panelContent.width height: panelContent.height opacity: panelContent.opacity * Math.max(M.Theme.barOpacity, 0.85) accentColor: root.accentColor } Column { id: panelContent width: root.contentWidth opacity: 0 y: -height } }