From aebd3235d755cb1ff95995b461e497fea2d52e8b Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Thu, 11 Sep 2025 14:43:11 +0200 Subject: ... --- .../shell/quickshell/ActiveWindowDisplay.qml | 182 ++++++--- accounts/gkleen@sif/shell/quickshell/Bar.qml | 12 +- .../gkleen@sif/shell/quickshell/BatteryWidget.qml | 71 +++- .../shell/quickshell/BrightnessWidget.qml | 47 ++- accounts/gkleen@sif/shell/quickshell/Clock.qml | 6 +- .../gkleen@sif/shell/quickshell/PipewireWidget.qml | 412 +++++++++++++-------- .../shell/quickshell/Services/Brightness.qml | 13 +- accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml | 4 +- 8 files changed, 527 insertions(+), 220 deletions(-) (limited to 'accounts/gkleen@sif/shell') diff --git a/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml b/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml index 57ade488..883f9001 100644 --- a/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml +++ b/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml @@ -22,72 +22,144 @@ Item { width: activeWindowDisplayContent.width height: parent.height - Row { - id: activeWindowDisplayContent + WrapperMouseArea { + id: widgetMouseArea - width: childrenRect.width - height: parent.height - anchors.verticalCenter: parent.verticalCenter - spacing: 8 + anchors.fill: parent - IconImage { - id: activeWindowIcon + hoverEnabled: true - height: 14 - width: 14 + Item { + anchors.fill: parent - anchors.verticalCenter: parent.verticalCenter + Row { + id: activeWindowDisplayContent - source: { - let icon = activeWindowDisplay.windowEntry?.icon - if (typeof icon === 'string' || icon instanceof String) { - if (icon.includes("?path=")) { - const split = icon.split("?path=") - if (split.length !== 2) + width: childrenRect.width + height: parent.height + anchors.verticalCenter: parent.verticalCenter + spacing: 8 + + IconImage { + id: activeWindowIcon + + implicitSize: 14 + + anchors.verticalCenter: parent.verticalCenter + + source: { + let icon = activeWindowDisplay.windowEntry?.icon + if (typeof icon === 'string' || icon instanceof String) { + if (icon.includes("?path=")) { + const split = icon.split("?path=") + if (split.length !== 2) + return icon + const name = split[0] + const path = split[1] + const fileName = name.substring( + name.lastIndexOf("/") + 1) + return `file://${path}/${fileName}` + } else + icon = Quickshell.iconPath(icon); return icon - const name = split[0] - const path = split[1] - const fileName = name.substring( - name.lastIndexOf("/") + 1) - return `file://${path}/${fileName}` - } else - icon = Quickshell.iconPath(icon); - return icon + } + return "" + } + asynchronous: true + smooth: true + mipmap: true + } + + Text { + id: windowTitle + + width: Math.min(implicitWidth, activeWindowDisplay.maxWidth - activeWindowIcon.width - activeWindowDisplayContent.spacing) + + property var appAliases: { "Firefox": "Mozilla Firefox", "mpv Media Player": "mpv", "Thunderbird": "Mozilla Thunderbird", "Thunderbird (LMU)": "Mozilla Thunderbird" } + + elide: Text.ElideRight + maximumLineCount: 1 + color: "white" + anchors.verticalCenter: parent.verticalCenter + text: { + if (!activeWindowDisplay.activeWindow) + return ""; + + var title = activeWindowDisplay.activeWindow.title; + var appName = activeWindowDisplay.windowEntry?.name; + if (appAliases[appName]) + appName = appAliases[appName]; + if (appName && title.endsWith(appName)) { + const oldTitle = title; + title = title.substring(0, title.length - appName.length); + title = title.replace(/\s*(—|-)\s*$/, ""); + if (!title) + title = oldTitle; + } + return title; + } } - return "" } - asynchronous: true - smooth: true - mipmap: true } + } + + Loader { + id: tooltipLoader + + active: false + + Connections { + target: widgetMouseArea + function onContainsMouseChanged() { + if (widgetMouseArea.containsMouse) + tooltipLoader.active = true; + } + } + + PopupWindow { + id: tooltip + + property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse + + anchor { + item: widgetMouseArea + edges: Edges.Bottom | Edges.Left + } + visible: false + + onNextVisibleChanged: hangTimer.restart() + + Timer { + id: hangTimer + interval: tooltip.visible ? 100 : 500 + onTriggered: { + tooltip.visible = tooltip.nextVisible; + if (!tooltip.visible) + tooltipLoader.active = false; + } + } + + implicitWidth: widgetTooltipText.contentWidth + 16 + implicitHeight: widgetTooltipText.contentHeight + 16 + color: "black" + + WrapperMouseArea { + id: tooltipMouseArea + + hoverEnabled: true + enabled: true + + anchors.centerIn: parent + + Text { + id: widgetTooltipText + + font.pointSize: 10 + font.family: "Fira Mono" + color: "white" - Text { - id: windowTitle - - width: Math.min(implicitWidth, activeWindowDisplay.maxWidth - activeWindowIcon.width - activeWindowDisplayContent.spacing) - - property var appAliases: { "Firefox": "Mozilla Firefox", "mpv Media Player": "mpv", "Thunderbird": "Mozilla Thunderbird", "Thunderbird (LMU)": "Mozilla Thunderbird" } - - elide: Text.ElideRight - maximumLineCount: 1 - color: "white" - anchors.verticalCenter: parent.verticalCenter - text: { - if (!activeWindowDisplay.activeWindow) - return ""; - - var title = activeWindowDisplay.activeWindow.title; - var appName = activeWindowDisplay.windowEntry?.name; - if (appAliases[appName]) - appName = appAliases[appName]; - if (appName && title.endsWith(appName)) { - const oldTitle = title; - title = title.substring(0, title.length - appName.length); - title = title.replace(/\s*(—|-)\s*$/, ""); - if (!title) - title = oldTitle; + text: JSON.stringify(Object.assign({}, activeWindowDisplay.activeWindow), null, 2) } - return title; } } } diff --git a/accounts/gkleen@sif/shell/quickshell/Bar.qml b/accounts/gkleen@sif/shell/quickshell/Bar.qml index d52740b2..52b9b344 100644 --- a/accounts/gkleen@sif/shell/quickshell/Bar.qml +++ b/accounts/gkleen@sif/shell/quickshell/Bar.qml @@ -70,23 +70,13 @@ PanelWindow { Item { enabled: privacy.active height: parent.height - width: 8 + width: 8 - 4 } BatteryWidget {} - Item { - height: parent.height - width: 8 - } - BrightnessWidget {} - Item { - height: parent.height - width: 4 - } - PipewireWidget {} SystemTray {} diff --git a/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml b/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml index 896440f1..fd031627 100644 --- a/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml +++ b/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml @@ -7,7 +7,7 @@ Item { id: root height: parent.height - width: batteryIcon.width + width: batteryIcon.width + 8 anchors.verticalCenter: parent.verticalCenter property var batteryDevice: Array.from(UPower.devices.values).find(dev => dev.isLaptopBattery) @@ -55,7 +55,76 @@ Item { return "#555"; } } + } + } + + PopupWindow { + id: tooltip + + property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse + + anchor { + item: widgetMouseArea + edges: Edges.Bottom | Edges.Left + } + visible: false + + onNextVisibleChanged: hangTimer.restart() + + Timer { + id: hangTimer + interval: 100 + onTriggered: tooltip.visible = tooltip.nextVisible + } + + implicitWidth: widgetTooltipText.contentWidth + 16 + implicitHeight: widgetTooltipText.contentHeight + 16 + color: "black" + WrapperMouseArea { + id: tooltipMouseArea + + hoverEnabled: true + enabled: true + + anchors.centerIn: parent + + Text { + id: widgetTooltipText + + font.pointSize: 10 + font.family: "Fira Sans" + color: "white" + + text: { + const stateStr = UPowerDeviceState.toString(root.batteryDevice.state); + var outStr = stateStr; + if (root.batteryDevice.state != UPowerDeviceState.FullyCharged) + outStr += ` ${Math.round(root.batteryDevice.percentage * 100)}%`; + + function formatTime(t) { + var res = ""; + for (const unit of [{ "s": "h", "v": 3600 }, { "s": "m", "v": 60 }, { "s": "s", "v": 1 }]) { + if (t < unit.v) + continue; + res += Math.floor(t / unit.v) + unit.s; + t %= unit.v; + } + return res; + } + if (root.batteryDevice.timeToEmpty != 0) { + const tStr = formatTime(Math.floor(root.batteryDevice.timeToEmpty / 60) * 60); + if (tStr) + outStr += " " + tStr; + } else if (root.batteryDevice.timeToFull != 0) { + const tStr = formatTime(Math.ceil(root.batteryDevice.timeToFull / 60) * 60); + if (tStr) + outStr += " " + tStr; + } + + return outStr; + } + } } } } diff --git a/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml b/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml index 664b28e2..7f9c1ad0 100644 --- a/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml +++ b/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml @@ -5,7 +5,7 @@ import qs.Services Item { height: parent.height - width: brightnessIcon.width + width: brightnessIcon.width + 8 anchors.verticalCenter: parent.verticalCenter WrapperMouseArea { @@ -13,6 +13,8 @@ Item { anchors.fill: parent + hoverEnabled: true + property real sensitivity: (1 / 50) / 120 onWheel: event => Brightness.currBrightness += event.angleDelta.y * sensitivity @@ -30,4 +32,47 @@ Item { } } } + + PopupWindow { + id: tooltip + + property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse + + anchor { + item: widgetMouseArea + edges: Edges.Bottom | Edges.Left + } + visible: false + + onNextVisibleChanged: hangTimer.restart() + + Timer { + id: hangTimer + interval: 100 + onTriggered: tooltip.visible = tooltip.nextVisible + } + + implicitWidth: widgetTooltipText.contentWidth + 16 + implicitHeight: widgetTooltipText.contentHeight + 16 + color: "black" + + WrapperMouseArea { + id: tooltipMouseArea + + hoverEnabled: true + enabled: true + + anchors.centerIn: parent + + Text { + id: widgetTooltipText + + font.pointSize: 10 + font.family: "Fira Sans" + color: "white" + + text: `${Math.round(Brightness.currBrightness * 100)}%` + } + } + } } diff --git a/accounts/gkleen@sif/shell/quickshell/Clock.qml b/accounts/gkleen@sif/shell/quickshell/Clock.qml index 4644d5e7..bb618f6a 100644 --- a/accounts/gkleen@sif/shell/quickshell/Clock.qml +++ b/accounts/gkleen@sif/shell/quickshell/Clock.qml @@ -73,7 +73,11 @@ Item { Timer { id: hangTimer interval: 100 - onTriggered: tooltip.visible = tooltip.nextVisible + onTriggered: { + tooltip.visible = tooltip.nextVisible; + if (!tooltip.visible) + tooltipLoader.active = false; + } } implicitWidth: clockTooltipContent.width diff --git a/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml b/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml index 007ce100..3e0b8fd9 100644 --- a/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml +++ b/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml @@ -114,232 +114,350 @@ Item { implicitWidth: tooltipContent.width implicitHeight: tooltipContent.height - color: "black" + color: "transparent" - WrapperMouseArea { - id: tooltipMouseArea + Rectangle { + width: tooltip.width + height: tooltipLayout.childrenRect.height + 16 + color: "black" + } - hoverEnabled: true - enabled: true + WrapperItem { + id: tooltipContent - anchors.fill: parent + bottomMargin: Math.max(0, 200 - tooltipLayout.implicitHeight) + + WrapperMouseArea { + id: tooltipMouseArea - WrapperItem { - id: tooltipContent + hoverEnabled: true + enabled: true - margin: 8 - bottomMargin: 8 + Math.max(0, 200 - tooltipLayout.implicitHeight) + WrapperItem { + margin: 8 + bottomMargin: 8 - GridLayout { - id: tooltipLayout + GridLayout { + id: tooltipLayout - columns: 4 + columns: 4 - Repeater { - model: Array.from(Pipewire.devices.values).filter(dev => dev.type == "Audio/Device") + Repeater { + model: Array.from(Pipewire.devices.values).filter(dev => dev.type == "Audio/Device") - Item { - id: descItem + Item { + id: descItem - required property var modelData - required property int index + required property var modelData + required property int index - Layout.column: 0 - Layout.row: index + Layout.column: 0 + Layout.row: index - implicitWidth: descText.contentWidth - implicitHeight: descText.contentHeight + implicitWidth: descText.contentWidth + implicitHeight: descText.contentHeight - Text { - id: descText + Text { + id: descText - color: "white" - font.pointSize: 10 - font.family: "Fira Sans" + color: "white" + font.pointSize: 10 + font.family: "Fira Sans" - text: descItem.modelData.description + text: descItem.modelData.description + } } } - } - Repeater { - id: defaultSinkRepeater + Repeater { + id: defaultSinkRepeater - model: { - Array.from(Pipewire.devices.values) - .filter(dev => dev.type == "Audio/Device") - .map(device => Array.from(Pipewire.nodes.values).find(node => node.type == PwNodeType.AudioSink && node.device?.id == device.id )); - } + model: { + Array.from(Pipewire.devices.values) + .filter(dev => dev.type == "Audio/Device") + .map(device => Array.from(Pipewire.nodes.values).find(node => node.type == PwNodeType.AudioSink && node.device?.id == device.id )); + } - Item { - id: defaultSinkItem + Item { + id: defaultSinkItem - required property var modelData - required property int index + required property var modelData + required property int index - PwObjectTracker { - objects: [defaultSinkItem.modelData] - } + visible: Boolean(modelData) - Layout.column: 1 - Layout.row: index + PwObjectTracker { + objects: [defaultSinkItem.modelData] + } - Layout.fillHeight: true + Layout.column: 1 + Layout.row: index - implicitWidth: 16 + 8 + Layout.fillHeight: true - WrapperMouseArea { - id: defaultSinkMouseArea + implicitWidth: 16 + 8 - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor + WrapperMouseArea { + id: defaultSinkMouseArea - onClicked: { - Pipewire.preferredDefaultAudioSink = defaultSinkItem.modelData - } + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor - Rectangle { - id: defaultSinkWidget + onClicked: { + Pipewire.preferredDefaultAudioSink = defaultSinkItem.modelData + } - anchors.fill: parent - color: { - if (defaultSinkMouseArea.containsMouse) - return "#33808080"; - return "transparent"; + onWheel: event => scrollVolume(event); + property real sensitivity: (1 / 40) / 120 + function scrollVolume(event) { + defaultSinkItem.modelData.audio.volume += event.angleDelta.y * sensitivity; } - MaterialDesignIcon { - width: 16 - height: 16 + Rectangle { + id: defaultSinkWidget + + anchors.fill: parent + color: { + if (defaultSinkMouseArea.containsMouse) + return "#33808080"; + return "transparent"; + } + + MaterialDesignIcon { + width: 16 + height: 16 + anchors.centerIn: parent + + icon: { + if (defaultSinkItem.modelData?.id == Pipewire.defaultAudioSink?.id) + return "speaker"; + return "speaker-off"; + } + color: icon == "speaker" ? "white" : "#555" + } + } + } + + PopupWindow { + id: volumeTooltip + + property bool nextVisible: defaultSinkMouseArea.containsMouse || volumeTooltipMouseArea.containsMouse + + anchor { + item: defaultSinkMouseArea + edges: Edges.Bottom | Edges.Left + } + visible: false + + onNextVisibleChanged: volumeHangTimer.restart() + + onVisibleChanged: tooltip.openPopup = volumeTooltip.visible + + Timer { + id: volumeHangTimer + interval: 100 + onTriggered: volumeTooltip.visible = volumeTooltip.nextVisible + } + + implicitWidth: volumeTooltipText.contentWidth + 16 + implicitHeight: volumeTooltipText.contentHeight + 16 + color: "black" + + WrapperMouseArea { + id: volumeTooltipMouseArea + + hoverEnabled: true + enabled: true + + onWheel: event => defaultSinkMouseArea.scrollVolume(event); + anchors.centerIn: parent - icon: { - if (defaultSinkItem.modelData?.id == Pipewire.defaultAudioSink?.id) - return "speaker"; - return "speaker-off"; + Text { + id: volumeTooltipText + + font.pointSize: 10 + font.family: "Fira Sans" + color: "white" + + text: `${Math.round(defaultSinkItem.modelData?.audio?.volume * 100)}%` } - color: icon == "speaker" ? "white" : "#555" } } } } - } - Repeater { - id: defaultSourceRepeater + Repeater { + id: defaultSourceRepeater - model: { - Array.from(Pipewire.devices.values) - .filter(dev => dev.type == "Audio/Device") - .map(device => Array.from(Pipewire.nodes.values).find(node => node.type == PwNodeType.AudioSource && node.device?.id == device.id )); - } + model: { + Array.from(Pipewire.devices.values) + .filter(dev => dev.type == "Audio/Device") + .map(device => Array.from(Pipewire.nodes.values).find(node => node.type == PwNodeType.AudioSource && node.device?.id == device.id )); + } - Item { - id: defaultSourceItem + Item { + id: defaultSourceItem - required property var modelData - required property int index + required property var modelData + required property int index - PwObjectTracker { - objects: [defaultSourceItem.modelData] - } + visible: Boolean(modelData) + + PwObjectTracker { + objects: [defaultSourceItem.modelData] + } + + Layout.column: 2 + Layout.row: index - Layout.column: 2 - Layout.row: index + Layout.fillHeight: true + + implicitWidth: 16 + 8 + + WrapperMouseArea { + id: defaultSourceMouseArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor - Layout.fillHeight: true + onClicked: { + Pipewire.preferredDefaultAudioSource = defaultSourceItem.modelData + } - implicitWidth: 16 + 8 + onWheel: event => scrollVolume(event); + property real sensitivity: (1 / 40) / 120 + function scrollVolume(event) { + defaultSourceItem.modelData.audio.volume += event.angleDelta.y * sensitivity; + } - WrapperMouseArea { - id: defaultSourceMouseArea + Rectangle { + id: defaultSourceWidget - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor + anchors.fill: parent + color: { + if (defaultSourceMouseArea.containsMouse) + return "#33808080"; + return "transparent"; + } - onClicked: { - Pipewire.preferredDefaultAudioSource = defaultSourceItem.modelData + MaterialDesignIcon { + width: 16 + height: 16 + anchors.centerIn: parent + + icon: { + if (defaultSourceItem.modelData?.id == Pipewire.defaultAudioSource?.id) + return "microphone"; + return "microphone-off"; + } + color: icon == "microphone" ? "white" : "#555" + } + } } - Rectangle { - id: defaultSourceWidget + PopupWindow { + id: volumeTooltip - anchors.fill: parent - color: { - if (defaultSourceMouseArea.containsMouse) - return "#33808080"; - return "transparent"; + property bool nextVisible: defaultSourceMouseArea.containsMouse || volumeTooltipMouseArea.containsMouse + + anchor { + item: defaultSourceMouseArea + edges: Edges.Bottom | Edges.Left } + visible: false + + onNextVisibleChanged: volumeHangTimer.restart() + + onVisibleChanged: tooltip.openPopup = volumeTooltip.visible + + Timer { + id: volumeHangTimer + interval: 100 + onTriggered: volumeTooltip.visible = volumeTooltip.nextVisible + } + + implicitWidth: volumeTooltipText.contentWidth + 16 + implicitHeight: volumeTooltipText.contentHeight + 16 + color: "black" + + WrapperMouseArea { + id: volumeTooltipMouseArea + + hoverEnabled: true + enabled: true + + onWheel: event => defaultSourceMouseArea.scrollVolume(event); - MaterialDesignIcon { - width: 16 - height: 16 anchors.centerIn: parent - icon: { - if (defaultSourceItem.modelData?.id == Pipewire.defaultAudioSource?.id) - return "microphone"; - return "microphone-off"; + Text { + id: volumeTooltipText + + font.pointSize: 10 + font.family: "Fira Sans" + color: "white" + + text: `${Math.round(defaultSourceItem.modelData?.audio?.volume * 100)}%` } - color: icon == "microphone" ? "white" : "#555" } } } } - } - Repeater { - id: profileRepeater + Repeater { + id: profileRepeater - model: Array.from(Pipewire.devices.values).filter(dev => dev.type == "Audio/Device") + model: Array.from(Pipewire.devices.values).filter(dev => dev.type == "Audio/Device") - Item { - id: profileItem + Item { + id: profileItem - required property var modelData - required property int index + required property var modelData + required property int index - PwObjectTracker { - objects: [profileItem.modelData] - } + PwObjectTracker { + objects: [profileItem.modelData] + } - Layout.column: 3 - Layout.row: index + Layout.column: 3 + Layout.row: index - Layout.fillWidth: true + Layout.fillWidth: true - implicitWidth: Math.max(profileBox.implicitWidth, 300) - implicitHeight: profileBox.height + implicitWidth: Math.max(profileBox.implicitWidth, 300) + implicitHeight: profileBox.height - ComboBox { - id: profileBox + ComboBox { + id: profileBox - model: profileItem.modelData.profiles + model: profileItem.modelData.profiles - textRole: "description" - valueRole: "index" - onActivated: profileItem.modelData.setProfile(currentValue) + textRole: "description" + valueRole: "index" + onActivated: profileItem.modelData.setProfile(currentValue) - anchors.fill: parent + anchors.fill: parent - implicitContentWidthPolicy: ComboBox.WidestText + implicitContentWidthPolicy: ComboBox.WidestText - Connections { - target: profileItem.modelData - function onCurrentProfileChanged() { + Connections { + target: profileItem.modelData + function onCurrentProfileChanged() { + profileBox.currentIndex = Array.from(profileItem.modelData.profiles).findIndex(profile => profile.index == profileItem.modelData.currentProfile); + } + } + Component.onCompleted: { profileBox.currentIndex = Array.from(profileItem.modelData.profiles).findIndex(profile => profile.index == profileItem.modelData.currentProfile); } - } - Component.onCompleted: { - profileBox.currentIndex = Array.from(profileItem.modelData.profiles).findIndex(profile => profile.index == profileItem.modelData.currentProfile); - } - Connections { - target: profileBox.popup - function onVisibleChanged() { - tooltip.openPopup = profileBox.popup.visible + Connections { + target: profileBox.popup + function onVisibleChanged() { + tooltip.openPopup = profileBox.popup.visible + } } } } diff --git a/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml b/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml index 87c7c05b..8318df50 100644 --- a/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml +++ b/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml @@ -23,14 +23,21 @@ Singleton { return val; } - Component.onCompleted: root.currBrightness = root.calcCurrBrightness() Connections { target: currFile - function onLoaded() { root.currBrightness = root.calcCurrBrightness(); } + function onLoaded() { + const b = root.calcCurrBrightness(); + if (typeof b !== 'undefined') + root.currBrightness = b; + } } Connections { target: maxFile - function onLoaded() { root.currBrightness = root.calcCurrBrightness(); } + function onLoaded() { + const b = root.calcCurrBrightness(); + if (typeof b !== 'undefined') + root.currBrightness = b; + } } onCurrBrightnessChanged: { diff --git a/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml b/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml index 16fb5dea..653f4763 100644 --- a/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml +++ b/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml @@ -122,6 +122,8 @@ Scope { } else if (root.show == "source") { if (!Pipewire.defaultAudioSource || Pipewire.defaultAudioSource.audio.muted) return "microphone-off"; + if (Pipewire.defaultAudioSource.audio.volume > 1) + return "microphone-plus"; return "microphone"; } return "volume-high"; @@ -148,7 +150,7 @@ Scope { if (root.show == "sink") return parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0); else if (root.show == "source") - return parent.width * (Pipewire.defaultAudioSource?.audio.volume ?? 0); + return parent.width * Math.min(1, (Pipewire.defaultAudioSource?.audio.volume ?? 0)); return 0; } } -- cgit v1.2.3