Create Microphone widget as requested in #180

Microphone: hook up microphone functionallity to bar widget
This commit is contained in:
Ly-sec 2025-09-01 14:22:45 +02:00
parent 00c94755c5
commit 0fd83498ea
3 changed files with 137 additions and 0 deletions

View file

@ -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"

View file

@ -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
}
}

View file

@ -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 {}
}