diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 8e747f5bb..699edb558 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -183,7 +183,7 @@ Singleton { property bool waveProgressEnabled: true property bool scrollTitleEnabled: true property bool audioVisualizerEnabled: true - property bool audioScrollEnabled: true + property string audioScrollMode: "volume" property bool clockCompactMode: false property bool focusedWindowCompactMode: false property bool runningAppsCompactMode: true diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index 060a681e1..5998695ec 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -93,7 +93,7 @@ var SPEC = { waveProgressEnabled: { def: true }, scrollTitleEnabled: { def: true }, audioVisualizerEnabled: { def: true }, - audioScrollEnabled: { def: true }, + audioScrollMode: { def: "volume" }, clockCompactMode: { def: false }, focusedWindowCompactMode: { def: false }, runningAppsCompactMode: { def: true }, diff --git a/quickshell/Modules/DankBar/Widgets/Media.qml b/quickshell/Modules/DankBar/Widgets/Media.qml index 2f2d5b16a..a20cf9ed7 100644 --- a/quickshell/Modules/DankBar/Widgets/Media.qml +++ b/quickshell/Modules/DankBar/Widgets/Media.qml @@ -54,38 +54,67 @@ BasePill { property real touchpadThreshold: 100 onWheel: function (wheelEvent) { - if (!usePlayerVolume) - return; - if (!SettingsData.audioScrollEnabled) + if (SettingsData.audioScrollMode === "nothing") return; - wheelEvent.accepted = true; + if (SettingsData.audioScrollMode === "volume") { + if (!usePlayerVolume) + return; + + wheelEvent.accepted = true; - const deltaY = wheelEvent.angleDelta.y; - const isMouseWheelY = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0; + const deltaY = wheelEvent.angleDelta.y; + const isMouseWheelY = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0; - const currentVolume = activePlayer.volume * 100; + const currentVolume = activePlayer.volume * 100; - let newVolume = currentVolume; - if (isMouseWheelY) { - if (deltaY > 0) { - newVolume = Math.min(100, currentVolume + 5); - } else if (deltaY < 0) { - newVolume = Math.max(0, currentVolume - 5); + let newVolume = currentVolume; + if (isMouseWheelY) { + if (deltaY > 0) { + newVolume = Math.min(100, currentVolume + 5); + } else if (deltaY < 0) { + newVolume = Math.max(0, currentVolume - 5); + } + } else { + scrollAccumulatorY += deltaY; + if (Math.abs(scrollAccumulatorY) >= touchpadThreshold) { + if (scrollAccumulatorY > 0) { + newVolume = Math.min(100, currentVolume + 1); + } else { + newVolume = Math.max(0, currentVolume - 1); + } + scrollAccumulatorY = 0; + } } - } else { - scrollAccumulatorY += deltaY; - if (Math.abs(scrollAccumulatorY) >= touchpadThreshold) { - if (scrollAccumulatorY > 0) { - newVolume = Math.min(100, currentVolume + 1); + + activePlayer.volume = newVolume / 100; + } else if (SettingsData.audioScrollMode === "song") { + if (!activePlayer) + return; + + wheelEvent.accepted = true; + + const deltaY = wheelEvent.angleDelta.y; + const isMouseWheelY = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0; + + if (isMouseWheelY) { + if (deltaY > 0) { + activePlayer.previous(); } else { - newVolume = Math.max(0, currentVolume - 1); + activePlayer.next(); + } + } else { + scrollAccumulatorY += deltaY; + if (Math.abs(scrollAccumulatorY) >= touchpadThreshold) { + if (scrollAccumulatorY > 0) { + activePlayer.previous(); + } else { + activePlayer.next(); + } + scrollAccumulatorY = 0; } - scrollAccumulatorY = 0; } } - - activePlayer.volume = newVolume / 100; } content: Component { diff --git a/quickshell/Modules/Settings/MediaPlayerTab.qml b/quickshell/Modules/Settings/MediaPlayerTab.qml index 32aebefdd..a8f305484 100644 --- a/quickshell/Modules/Settings/MediaPlayerTab.qml +++ b/quickshell/Modules/Settings/MediaPlayerTab.qml @@ -46,11 +46,24 @@ Item { onToggled: checked => SettingsData.set("audioVisualizerEnabled", checked) } - SettingsToggleRow { + SettingsDropdownRow { + property var scrollOpts: { + "Change Volume": "volume", + "Change Song": "song", + "Nothing": "nothing" + } + text: I18n.tr("Scroll Wheel") - description: I18n.tr("Scroll on widget changes media volume") - checked: SettingsData.audioScrollEnabled - onToggled: checked => SettingsData.set("audioScrollEnabled", checked) + description: I18n.tr("Scroll wheel behavior on media widget") + settingKey: "audioScrollMode" + tags: ["media", "music", "scroll"] + options: Object.keys(scrollOpts).sort() + currentValue: { + Object.keys(scrollOpts).find(key => scrollOpts[key] === SettingsData.audioScrollMode) ?? "volume" + } + onValueChanged: value => { + SettingsData.set("audioScrollMode", scrollOpts[value]) + } } } } diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index fa9d8c327..416554f9e 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -2496,6 +2496,27 @@ "icon": "lock", "description": "If the field is hidden, it will appear as soon as a key is pressed." }, + { + "section": "lockBeforeSuspend", + "label": "Lock before suspend", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "automatic", + "automatically", + "before", + "lock", + "login", + "password", + "prepares", + "screen", + "security", + "sleep", + "suspend", + "system" + ], + "description": "Automatically lock the screen when the system prepares to suspend" + }, { "section": "lockScreenShowPasswordField", "label": "Show Password Field", @@ -2928,6 +2949,7 @@ "playback", "player", "progress", + "scroll", "settings", "spotify", "statusbar", @@ -2938,6 +2960,24 @@ "icon": "music_note", "description": "Use animated wave progress bars for media playback" }, + { + "section": "audioScrollMode", + "label": "Scroll Wheel", + "tabIndex": 16, + "category": "Media Player", + "keywords": [ + "behavior", + "media", + "mpris", + "music", + "player", + "scroll", + "spotify", + "wheel", + "widget" + ], + "description": "Scroll wheel behavior on media widget" + }, { "section": "notificationTimeoutCritical", "label": "Critical Priority", @@ -3413,27 +3453,6 @@ "icon": "schedule", "description": "Gradually fade the screen before locking with a configurable grace period" }, - { - "section": "lockBeforeSuspend", - "label": "Lock before suspend", - "tabIndex": 21, - "category": "Power & Sleep", - "keywords": [ - "automatically", - "before", - "energy", - "lock", - "power", - "prepares", - "screen", - "security", - "shutdown", - "sleep", - "suspend", - "system" - ], - "description": "Automatically lock the screen when the system prepares to suspend" - }, { "section": "powerConfirmation", "label": "Power Action Confirmation",