diff --git a/modules/Bar.qml b/modules/Bar.qml index f200738..e1efa6f 100644 --- a/modules/Bar.qml +++ b/modules/Bar.qml @@ -171,6 +171,7 @@ PanelWindow { } M.Volume { visible: M.Modules.volume.enable + bar: bar } } diff --git a/modules/HoverPanel.qml b/modules/HoverPanel.qml index da37516..377a75d 100644 --- a/modules/HoverPanel.qml +++ b/modules/HoverPanel.qml @@ -45,14 +45,12 @@ PanelWindow { WlrLayershell.exclusiveZone: 0 WlrLayershell.namespace: root.panelNamespace - property real topMargin: 0 - anchors.top: true anchors.left: true anchors.right: true anchors.bottom: true - margins.top: topMargin + margins.top: 0 function _updatePosition() { const scr = screen; diff --git a/modules/Volume.qml b/modules/Volume.qml index cf63c43..e505d75 100644 --- a/modules/Volume.qml +++ b/modules/Volume.qml @@ -38,13 +38,9 @@ M.BarSection { return streams; } - property bool _expanded: false property bool _osdActive: false readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered - readonly property bool _showPanel: _anyHover || _expanded || _osdActive - - on_ShowPanelChanged: if (!_showPanel) - _expanded = false + readonly property bool _showPanel: _anyHover || _osdActive onVolumeChanged: _flashPanel() onMutedChanged: _flashPanel() @@ -60,6 +56,8 @@ M.BarSection { onTriggered: root._osdActive = false } + required property var bar + M.BarIcon { icon: root._volumeIcon minIcon: "\uF028" @@ -93,6 +91,7 @@ M.BarSection { } } + // OSD panel — hover shows slider only, fixed height, no resize M.HoverPanel { id: hoverPanel showPanel: root._showPanel @@ -180,7 +179,7 @@ M.BarSection { } } - // Sink name + chevron + // Sink name row — click chevron to open mixer popup Item { width: parent.width height: 22 @@ -203,7 +202,7 @@ M.BarSection { anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter - text: root._expanded ? "\uF077" : "\uF078" + text: "\uF078" color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 3 font.family: M.Theme.iconFontFamily @@ -211,15 +210,23 @@ M.BarSection { TapHandler { cursorShape: Qt.PointingHandCursor - onTapped: root._expanded = !root._expanded + onTapped: mixerLoader.active = true } } + } - // Device + stream list - Column { - id: deviceList - width: parent.width - visible: root._expanded + // Mixer popup — separate window, no resize issues + LazyLoader { + id: mixerLoader + active: false + + M.HoverPanel { + popupMode: true + accentColor: root.accentColor + screen: root.bar.screen + anchorX: root.mapToGlobal(root.width / 2, 0).x - (root.bar.screen?.x ?? 0) + contentWidth: 220 + onDismissed: mixerLoader.active = false // Output devices Rectangle { @@ -246,7 +253,7 @@ M.BarSection { delegate: Item { required property var modelData - width: deviceList.width + width: 220 height: 28 readonly property bool _active: modelData === root.sink @@ -281,7 +288,7 @@ M.BarSection { TapHandler { onTapped: { Pipewire.preferredDefaultAudioSink = modelData; - root._expanded = false; + mixerLoader.active = false; } } } @@ -315,7 +322,7 @@ M.BarSection { id: streamEntry required property var modelData - width: deviceList.width + width: 220 height: 32 readonly property string _appName: modelData.properties["application.name"] || modelData.description || modelData.name || "Unknown" @@ -403,12 +410,6 @@ M.BarSection { } } } - - // Bottom padding - Item { - width: 1 - height: 4 - } } } }