mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge pull request #1455 from chenkeao/main
feat(audio): implement volume feedback sound
This commit is contained in:
Binary file not shown.
@@ -680,7 +680,9 @@
|
||||
"volumes-step-size-description": "Adjust the step size for volume changes (scroll wheel, keyboard shortcuts).",
|
||||
"volumes-step-size-label": "Volume step size",
|
||||
"volumes-volume-overdrive-description": "Allow raising volume above 100%. May not be supported by all hardware.",
|
||||
"volumes-volume-overdrive-label": "Allow volume overdrive"
|
||||
"volumes-volume-overdrive-label": "Allow volume overdrive",
|
||||
"volumes-volume-feedback-label": "Play volume feedback sound",
|
||||
"volumes-volume-feedback-description": "Play a feedback sound when adjusting volume"
|
||||
},
|
||||
"bar": {
|
||||
"appearance-background-opacity-description": "Set the background opacity specifically for the bar.",
|
||||
|
||||
@@ -680,7 +680,9 @@
|
||||
"volumes-step-size-description": "调整音量变化的步长(滚轮、键盘快捷键)。",
|
||||
"volumes-step-size-label": "音量步长",
|
||||
"volumes-volume-overdrive-description": "允许将音量提高到100%以上。可能不被所有硬件支持。",
|
||||
"volumes-volume-overdrive-label": "允许音量过载"
|
||||
"volumes-volume-overdrive-label": "允许音量过载",
|
||||
"volumes-volume-feedback-label": "播放音量反馈",
|
||||
"volumes-volume-feedback-description": "调整音量时播放反馈音效"
|
||||
},
|
||||
"bar": {
|
||||
"appearance-background-opacity-description": "为状态栏设置背景不透明度。",
|
||||
|
||||
@@ -30,6 +30,7 @@ Noctalia Shell is made possible by the incredible work of many open-source proje
|
||||
## Audio Assets
|
||||
- **[Universfield on Pixabay](https://pixabay.com/users/universfield-28281460/)** - Notification sound effect
|
||||
- **[DrNI on Freesound](https://freesound.org/people/DrNI/sounds/34562/)** - Timer's alarm sound effect
|
||||
- **[Lucas McCallister on Freesound](http://www.freesound.org/samplesViewSingle.php?id=67091)** - Volume change feedback sound effect
|
||||
|
||||
|
||||
## Special Thanks
|
||||
|
||||
@@ -586,6 +586,7 @@ Singleton {
|
||||
property string visualizerType: "linear"
|
||||
property list<string> mprisBlacklist: []
|
||||
property string preferredPlayer: ""
|
||||
property bool volumeFeedback: false
|
||||
}
|
||||
|
||||
// brightness
|
||||
|
||||
@@ -61,6 +61,21 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
// Volume Feedback sound Toggle
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS
|
||||
Layout.fillWidth: true
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("panels.audio.volumes-volume-feedback-label")
|
||||
description: I18n.tr("panels.audio.volumes-volume-feedback-description")
|
||||
checked: Settings.data.audio.volumeFeedback
|
||||
defaultValue: Settings.getDefaultValue("audio.volumeFeedback")
|
||||
onToggled: checked => Settings.data.audio.volumeFeedback = checked
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mute Toggle
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS
|
||||
|
||||
@@ -4,10 +4,15 @@ import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pipewire
|
||||
import qs.Commons
|
||||
import qs.Services.System
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
// Rate limiting for volume feedback (minimum 100ms between sounds)
|
||||
property var lastVolumeFeedbackTime: 0
|
||||
readonly property int minVolumeFeedbackInterval: 100
|
||||
|
||||
// Devices
|
||||
readonly property PwNode sink: Pipewire.ready ? Pipewire.defaultAudioSink : null
|
||||
readonly property PwNode source: validatedSource
|
||||
@@ -230,6 +235,8 @@ Singleton {
|
||||
sink.audio.muted = false;
|
||||
sink.audio.volume = clampedVolume;
|
||||
|
||||
playVolumeFeedback(clampedVolume);
|
||||
|
||||
// Clear flag after a short delay to allow external changes to be detected
|
||||
Qt.callLater(() => {
|
||||
isSettingOutputVolume = false;
|
||||
@@ -305,6 +312,29 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function playVolumeFeedback(currentVolume: real) {
|
||||
if (!SoundService.multimediaAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Settings.data.audio.volumeFeedback) {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
if (now - lastVolumeFeedbackTime < minVolumeFeedbackInterval) {
|
||||
return;
|
||||
}
|
||||
lastVolumeFeedbackTime = now;
|
||||
|
||||
const feedbackVolume = currentVolume;
|
||||
SoundService.playSound("volume-change.wav", {
|
||||
volume: feedbackVolume,
|
||||
fallback: false,
|
||||
repeat: false
|
||||
});
|
||||
}
|
||||
|
||||
function setInputMuted(muted: bool) {
|
||||
if (!Pipewire.ready || !source?.audio) {
|
||||
Logger.w("AudioService", "No source available or Pipewire not ready");
|
||||
|
||||
Reference in New Issue
Block a user