Files
noctalia-shell/Modules/Panels/Settings/Tabs/Audio/VolumesSubTab.qml
T
Lysec 9f8bf988f0 fix(ntextinput): use onTextChanged for autosave, onEditingFinished instead of onAccepted
- Switch most settings from onEditingFinished to onTextChanged so
changes save on every keystroke
- Replace onAccepted with onEditingFinished (Enter + blur) for search,
pager, wifi, bluetooth
- Keep onEditingFinished for pager, wallhaven, path inputs, and
validation fields
2026-03-18 17:50:46 +01:00

197 lines
5.4 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.Media
import qs.Services.System
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
property real localVolume: AudioService.volume
Connections {
target: AudioService
function onSinkChanged() {
localVolume = AudioService.volume;
}
function onVolumeChanged() {
localVolume = AudioService.volume;
}
}
Connections {
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
function onVolumeChanged() {
localVolume = AudioService.volume;
}
}
// Output Volume
ColumnLayout {
spacing: Style.marginXXS
Layout.fillWidth: true
NValueSlider {
Layout.fillWidth: true
label: I18n.tr("panels.osd.types-volume-label")
description: I18n.tr("panels.audio.volumes-output-volume-description")
from: 0
to: Settings.data.audio.volumeOverdrive ? 1.5 : 1.0
value: localVolume
stepSize: 0.01
text: Math.round(AudioService.volume * 100) + "%"
onMoved: value => localVolume = value
}
Timer {
interval: 100
running: true
repeat: true
onTriggered: {
if (!AudioService.isSwitchingSink && Math.abs(localVolume - AudioService.volume) >= 0.01) {
AudioService.setVolume(localVolume);
}
}
}
}
// Mute Toggle
ColumnLayout {
spacing: Style.marginS
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.audio.volumes-mute-output-label")
description: I18n.tr("panels.audio.volumes-mute-output-description")
checked: AudioService.muted
onToggled: checked => AudioService.setOutputMuted(checked)
}
}
// 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
}
ColumnLayout {
enabled: SoundService.multimediaAvailable && Settings.data.audio.volumeFeedback
spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
label: I18n.tr("panels.audio.volumes-feedback-sound-file-label")
description: I18n.tr("panels.audio.volumes-feedback-sound-file-description")
}
NTextInputButton {
enabled: parent.enabled
Layout.fillWidth: true
placeholderText: I18n.tr("panels.notifications.sounds-files-placeholder")
text: Settings.data.audio.volumeFeedbackSoundFile ?? ""
buttonIcon: "folder-open"
buttonTooltip: I18n.tr("panels.notifications.sounds-files-select-file")
onInputTextChanged: text => Settings.data.audio.volumeFeedbackSoundFile = text
onButtonClicked: volumeFeedbackFilePicker.open()
}
}
}
NDivider {
Layout.fillWidth: true
}
// Input Volume
ColumnLayout {
spacing: Style.marginXS
Layout.fillWidth: true
NValueSlider {
Layout.fillWidth: true
label: I18n.tr("panels.osd.types-input-volume-label")
description: I18n.tr("panels.audio.volumes-input-volume-description")
from: 0
to: Settings.data.audio.volumeOverdrive ? 1.5 : 1.0
value: AudioService.inputVolume
stepSize: 0.01
text: Math.round(AudioService.inputVolume * 100) + "%"
onMoved: value => AudioService.setInputVolume(value)
}
}
// Input Mute Toggle
ColumnLayout {
spacing: Style.marginS
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.audio.volumes-mute-input-label")
description: I18n.tr("panels.audio.volumes-mute-input-description")
checked: AudioService.inputMuted
onToggled: checked => AudioService.setInputMuted(checked)
}
}
// Volume Step Size
ColumnLayout {
spacing: Style.marginS
Layout.fillWidth: true
NSpinBox {
Layout.fillWidth: true
label: I18n.tr("panels.audio.volumes-step-size-label")
description: I18n.tr("panels.audio.volumes-step-size-description")
minimum: 1
maximum: 25
value: Settings.data.audio.volumeStep
stepSize: 1
suffix: "%"
defaultValue: Settings.getDefaultValue("audio.volumeStep")
onValueChanged: Settings.data.audio.volumeStep = value
}
}
NDivider {
Layout.fillWidth: true
}
// Raise maximum volume above 100%
ColumnLayout {
spacing: Style.marginS
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.audio.volumes-volume-overdrive-label")
description: I18n.tr("panels.audio.volumes-volume-overdrive-description")
checked: Settings.data.audio.volumeOverdrive
defaultValue: Settings.getDefaultValue("audio.volumeOverdrive")
onToggled: checked => Settings.data.audio.volumeOverdrive = checked
}
}
NFilePicker {
id: volumeFeedbackFilePicker
title: I18n.tr("panels.audio.volumes-feedback-sound-file-select-title")
selectionMode: "files"
initialPath: Quickshell.env("HOME")
nameFilters: ["*.wav", "*.mp3", "*.ogg", "*.flac", "*.m4a", "*.aac"]
onAccepted: paths => {
if (paths.length > 0) {
Settings.data.audio.volumeFeedbackSoundFile = paths[0];
}
}
}
}