diff --git a/Bin/test-microphone-widget.sh b/Bin/test-microphone-widget.sh new file mode 100644 index 0000000..0cd6b8c --- /dev/null +++ b/Bin/test-microphone-widget.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Test script for the microphone widget +# This script tests the IPC commands that the microphone widget uses + +echo "Testing Microphone Widget Functionality" +echo "======================================" + +# Test input volume increase +echo "1. Testing input volume increase..." +qs -c noctalia-shell ipc call volume muteInput + +# Test input volume decrease +echo "2. Testing input volume decrease..." +qs -c noctalia-shell ipc call volume muteInput + +echo "Microphone widget test completed!" +echo "Check your bar to see if the Microphone widget is working correctly." +echo "" +echo "To add the Microphone widget to your bar:" +echo "1. Open the settings panel" +echo "2. Go to the Bar tab" +echo "3. Add 'Microphone' to your desired section (left, center, or right)" +echo "4. The widget will appear in your bar" diff --git a/Modules/Bar/Widgets/Microphone.qml b/Modules/Bar/Widgets/Microphone.qml new file mode 100644 index 0000000..6162ba0 --- /dev/null +++ b/Modules/Bar/Widgets/Microphone.qml @@ -0,0 +1,109 @@ +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Services.Pipewire +import qs.Commons +import qs.Modules.SettingsPanel +import qs.Services +import qs.Widgets + +Item { + id: root + + property ShellScreen screen + property real scaling: ScalingService.scale(screen) + property string barSection: "" + property int sectionWidgetIndex: 0 + property int sectionWidgetsCount: 0 + + // Used to avoid opening the pill on Quickshell startup + property bool firstInputVolumeReceived: false + property int wheelAccumulator: 0 + + implicitWidth: pill.width + implicitHeight: pill.height + + function getIcon() { + if (AudioService.inputMuted) { + return "mic_off" + } + return AudioService.inputVolume <= Number.EPSILON ? "mic_off" : (AudioService.inputVolume < 0.33 ? "mic" : "mic") + } + + // Connection used to open the pill when input volume changes + Connections { + target: AudioService.source?.audio ? AudioService.source?.audio : null + function onVolumeChanged() { + // Logger.log("Bar:Microphone", "onInputVolumeChanged") + if (!firstInputVolumeReceived) { + // Ignore the first volume change + firstInputVolumeReceived = true + } else { + pill.show() + externalHideTimer.restart() + } + } + } + + // Connection used to open the pill when input mute state changes + Connections { + target: AudioService.source?.audio ? AudioService.source?.audio : null + function onMutedChanged() { + // Logger.log("Bar:Microphone", "onInputMutedChanged") + if (!firstInputVolumeReceived) { + // Ignore the first mute change + firstInputVolumeReceived = true + } else { + pill.show() + externalHideTimer.restart() + } + } + } + + Timer { + id: externalHideTimer + running: false + interval: 1500 + onTriggered: { + pill.hide() + } + } + + NPill { + id: pill + + rightOpen: BarWidgetRegistry.getNPillDirection(root) + icon: getIcon() + iconCircleColor: Color.mPrimary + collapsedIconColor: Color.mOnSurface + autoHide: false // Important to be false so we can hover as long as we want + text: Math.floor(AudioService.inputVolume * 100) + "%" + tooltipText: "Microphone: " + Math.round(AudioService.inputVolume * 100) + + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute." + + onWheel: function (delta) { + wheelAccumulator += delta + if (wheelAccumulator >= 120) { + wheelAccumulator = 0 + AudioService.setInputVolume(AudioService.inputVolume + AudioService.stepVolume) + } else if (wheelAccumulator <= -120) { + wheelAccumulator = 0 + AudioService.setInputVolume(AudioService.inputVolume - AudioService.stepVolume) + } + } + onClicked: { + var settingsPanel = PanelService.getPanel("settingsPanel") + settingsPanel.requestedTab = SettingsPanel.Tab.AudioService + settingsPanel.open(screen) + } + onRightClicked: { + AudioService.setInputMuted(!AudioService.inputMuted) + } + } + + Process { + id: pwvucontrolProcess + command: ["pwvucontrol"] + running: false + } +} diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index 32b66d2..e27aaec 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -18,6 +18,7 @@ Singleton { "Clock": clockComponent, "KeyboardLayout": keyboardLayoutComponent, "MediaMini": mediaMiniComponent, + "Microphone": microphoneComponent, "NightLight": nightLightComponent, "NotificationHistory": notificationHistoryComponent, "PowerProfile": powerProfileComponent, @@ -56,6 +57,9 @@ Singleton { property Component mediaMiniComponent: Component { MediaMini {} } + property Component microphoneComponent: Component { + Microphone {} + } property Component nightLightComponent: Component { NightLight {} }