diff --git a/settings/quickshell.nix b/settings/quickshell.nix index 8c66d5a..7aecf0f 100644 --- a/settings/quickshell.nix +++ b/settings/quickshell.nix @@ -368,6 +368,19 @@ in font.pixelSize: 16 } + // ── VolIcon: a slider's volume glyph that toggles its audio + // node's mute on click. Glyph reflects the mute state; pair it + // with a fill that greys when `audioNode.muted`. + component VolIcon: SIcon { + property var audioNode: null + text: (audioNode && audioNode.muted) ? "volume_off" : "volume_up" + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: if (audioNode) audioNode.muted = !audioNode.muted + } + } + // ── Card: the rounded base01 section surface used by every // dropdown. Children flow into a padded auto-height column, // so callers just set `width` and drop content in. @@ -1712,7 +1725,7 @@ in Row { spacing: 6 - SIcon { anchors.verticalCenter: parent.verticalCenter; text: "volume_up" } + VolIcon { anchors.verticalCenter: parent.verticalCenter; audioNode: volWidget.sink ? volWidget.sink.audio : null } SText { anchors.verticalCenter: parent.verticalCenter text: "Master" @@ -1824,8 +1837,16 @@ in width: parent.width spacing: 8 + VolIcon { + anchors.verticalCenter: parent.verticalCenter + width: 18 + color: Theme.base04 + font.pixelSize: 15 + audioNode: modelData.audio + } + PillSlider { - width: parent.width - appVolLabel.width - 8 + width: parent.width - 18 - appVolLabel.width - 16 anchors.verticalCenter: parent.verticalCenter height: 16 trackH: 4 @@ -2541,20 +2562,21 @@ in spacing: 8 visible: mediaCard.pwNode !== null && mediaCard.pwNode.audio !== null - SIcon { + VolIcon { anchors.verticalCenter: parent.verticalCenter - text: "volume_up" + width: 18 color: Theme.base04 font.pixelSize: 15 + audioNode: mediaCard.pwNode ? mediaCard.pwNode.audio : null } PillSlider { - width: parent.width - 22 - mediaVolLabel.width - 16 + width: parent.width - 18 - mediaVolLabel.width - 16 anchors.verticalCenter: parent.verticalCenter height: 16 trackH: 4 value: mediaCard.pwNode && mediaCard.pwNode.audio ? Math.min(1, mediaCard.pwNode.audio.volume) : 0 - fillColor: Theme.base0C + fillColor: mediaCard.pwNode && mediaCard.pwNode.audio && mediaCard.pwNode.audio.muted ? Theme.base03 : Theme.base0C onMoved: (v) => { if (mediaCard.pwNode && mediaCard.pwNode.audio) mediaCard.pwNode.audio.volume = v; } }