diff --git a/modules/Flyout.qml b/modules/Flyout.qml index 78810ef..fe0f9ac 100644 --- a/modules/Flyout.qml +++ b/modules/Flyout.qml @@ -8,9 +8,23 @@ PanelWindow { required property var screen - visible: M.FlyoutState.visible && M.FlyoutState.screen === root.screen + visible: _winVisible color: "transparent" + property bool _winVisible: false + property bool _shown: M.FlyoutState.visible && M.FlyoutState.screen === root.screen + + on_ShownChanged: { + if (_shown) { + _winVisible = true; + hideAnim.stop(); + showAnim.start(); + } else { + showAnim.stop(); + hideAnim.start(); + } + } + WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.exclusiveZone: 0 WlrLayershell.namespace: "nova-flyout" @@ -18,32 +32,54 @@ PanelWindow { anchors.top: true anchors.left: true - // Flush below bar, centered on hovered item margins.top: 0 - margins.left: Math.max(0, Math.min(Math.round(M.FlyoutState.itemX - implicitWidth / 2), screen.width - implicitWidth)) + margins.left: Math.max(0, Math.min( + Math.round(M.FlyoutState.itemX - implicitWidth / 2), + screen.width - implicitWidth + )) implicitWidth: label.implicitWidth + M.Theme.barPadding * 2 implicitHeight: label.implicitHeight + M.Theme.barPadding * 2 - // Background matching bar style — square top corners so it looks - // flush / attached to the bar above, rounded bottom corners only - Rectangle { - anchors.fill: parent - color: M.Theme.base00 - opacity: Math.max(M.Theme.barOpacity, 0.85) - topLeftRadius: 0 - topRightRadius: 0 - bottomLeftRadius: M.Theme.radius - bottomRightRadius: M.Theme.radius + ParallelAnimation { + id: showAnim + NumberAnimation { target: content; property: "opacity"; to: 1; duration: 120; easing.type: Easing.OutCubic } + NumberAnimation { target: content; property: "y"; to: 0; duration: 150; easing.type: Easing.OutCubic } } - Text { - id: label - anchors.centerIn: parent - text: M.FlyoutState.text.replace(/\n/g, "
") - textFormat: Text.RichText - color: M.Theme.base05 - font.pixelSize: M.Theme.fontSize - font.family: M.Theme.fontFamily + ParallelAnimation { + id: hideAnim + NumberAnimation { target: content; property: "opacity"; to: 0; duration: 150; easing.type: Easing.InCubic } + NumberAnimation { target: content; property: "y"; to: -content.height; duration: 150; easing.type: Easing.InCubic } + onFinished: root._winVisible = false + } + + Item { + id: content + anchors.left: parent.left + anchors.right: parent.right + height: root.implicitHeight + opacity: 0 + y: -height + + Rectangle { + anchors.fill: parent + color: M.Theme.base00 + opacity: Math.max(M.Theme.barOpacity, 0.85) + topLeftRadius: 0 + topRightRadius: 0 + bottomLeftRadius: M.Theme.radius + bottomRightRadius: M.Theme.radius + } + + Text { + id: label + anchors.centerIn: parent + text: M.FlyoutState.text.replace(/\n/g, "
") + textFormat: Text.RichText + color: M.Theme.base05 + font.pixelSize: M.Theme.fontSize + font.family: M.Theme.fontFamily + } } } diff --git a/modules/Osd.qml b/modules/Osd.qml index 9e7a47a..49ee87d 100644 --- a/modules/Osd.qml +++ b/modules/Osd.qml @@ -4,16 +4,28 @@ import Quickshell.Wayland import "." as M // OSD overlay — slides out from the bar, centered on screen. -// Attached to the bar (square top corners, flush below it). PanelWindow { id: root required property var screen - // Stay visible while animating out - visible: M.OsdState.visible || hideAnim.running + visible: _winVisible color: "transparent" + property bool _winVisible: false + property bool _shown: M.OsdState.visible + + on_ShownChanged: { + if (_shown) { + _winVisible = true; + hideAnim.stop(); + showAnim.start(); + } else { + showAnim.stop(); + hideAnim.start(); + } + } + WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.exclusiveZone: 0 WlrLayershell.namespace: "nova-osd" @@ -28,18 +40,6 @@ PanelWindow { implicitWidth: 200 implicitHeight: 48 - // Slide + fade animation state - property bool _shown: M.OsdState.visible - on_ShownChanged: { - if (_shown) { - hideAnim.stop(); - showAnim.start(); - } else { - showAnim.stop(); - hideAnim.start(); - } - } - ParallelAnimation { id: showAnim NumberAnimation { target: content; property: "opacity"; to: 1; duration: 150; easing.type: Easing.OutCubic } @@ -50,6 +50,7 @@ PanelWindow { id: hideAnim NumberAnimation { target: content; property: "opacity"; to: 0; duration: 250; easing.type: Easing.InCubic } NumberAnimation { target: content; property: "y"; to: -content.height; duration: 250; easing.type: Easing.InCubic } + onFinished: root._winVisible = false } Item { @@ -60,7 +61,6 @@ PanelWindow { opacity: 0 y: -height - // Background — flush with bar above Rectangle { anchors.fill: parent color: M.Theme.base00 @@ -75,7 +75,6 @@ PanelWindow { anchors.centerIn: parent spacing: 10 - // Icon Text { text: M.OsdState.icon color: M.Theme.base0D @@ -84,7 +83,6 @@ PanelWindow { anchors.verticalCenter: parent.verticalCenter } - // Progress bar Item { width: 120 height: 6 @@ -108,7 +106,6 @@ PanelWindow { } } - // Percentage Text { text: Math.round(M.OsdState.value * 100) + "%" color: M.Theme.base05