diff --git a/applets/mediacontroller/contents/ui/main.qml b/applets/mediacontroller/contents/ui/main.qml --- a/applets/mediacontroller/contents/ui/main.qml +++ b/applets/mediacontroller/contents/ui/main.qml @@ -147,6 +147,12 @@ anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton + + onWheel: { + var delta = (wheel.angleDelta.y / 120) * 0.03 + mpris2Source.serviceForSource(mpris2Source.current).changeVolume(delta, true); + } + onClicked: { switch (mouse.button) { case Qt.MiddleButton: diff --git a/dataengines/mpris2/multiplexedservice.h b/dataengines/mpris2/multiplexedservice.h --- a/dataengines/mpris2/multiplexedservice.h +++ b/dataengines/mpris2/multiplexedservice.h @@ -35,6 +35,10 @@ public: MultiplexedService(Multiplexer *multiplexer, QObject *parent = nullptr); + Q_INVOKABLE void changeVolume(double delta, bool showOSD) { + if (m_control) m_control->changeVolume(delta, showOSD); + } + protected: Plasma::ServiceJob *createJob(const QString &operation, QMap ¶meters) override; diff --git a/dataengines/mpris2/multiplexedservice.cpp b/dataengines/mpris2/multiplexedservice.cpp --- a/dataengines/mpris2/multiplexedservice.cpp +++ b/dataengines/mpris2/multiplexedservice.cpp @@ -126,5 +126,19 @@ } } ); + + QAction *volumeupAction = m_actionCollection->addAction(QStringLiteral("mediavolumeup")); + volumeupAction->setText(i18n("Media volume up")); + KGlobalAccel::setGlobalShortcut(volumeupAction, QKeySequence()); + connect(volumeupAction, &QAction::triggered, this, + [this] { changeVolume(0.05, true); } + ); + + QAction *volumedownAction = m_actionCollection->addAction(QStringLiteral("mediavolumedown")); + volumedownAction->setText(i18n("Media volume down")); + KGlobalAccel::setGlobalShortcut(volumedownAction, QKeySequence()); + connect(volumedownAction, &QAction::triggered, this, + [this] { changeVolume(-0.05, true); } + ); } diff --git a/dataengines/mpris2/playercontrol.h b/dataengines/mpris2/playercontrol.h --- a/dataengines/mpris2/playercontrol.h +++ b/dataengines/mpris2/playercontrol.h @@ -46,6 +46,8 @@ { m_container->updatePosition(); } QDBusObjectPath trackId() const; + Q_INVOKABLE void changeVolume(double delta, bool showOSD); + Plasma::ServiceJob* createJob(const QString& operation, QMap& parameters) override; diff --git a/dataengines/mpris2/playercontrol.cpp b/dataengines/mpris2/playercontrol.cpp --- a/dataengines/mpris2/playercontrol.cpp +++ b/dataengines/mpris2/playercontrol.cpp @@ -89,6 +89,31 @@ m_container = 0; } +void PlayerControl::changeVolume(double delta, bool showOSD) { + const double volume = playerInterface()->volume(); + const double newVolume = qBound(0.0, volume + delta, qMax(volume, 1.0)); + playerInterface()->setVolume(newVolume); + + if (showOSD) { + const auto& data = m_container->data(); + + QDBusMessage msg = QDBusMessage::createMethodCall( + QStringLiteral("org.kde.plasmashell"), + QStringLiteral("/org/kde/osdService"), + QStringLiteral("org.kde.osdService"), + QStringLiteral("mediaPlayerVolumeChanged") + ); + + msg.setArguments({ + (int)(100 * newVolume), + data.value("Identity", ""), + data.value("Desktop Icon Name", "") + }); + + QDBusConnection::sessionBus().asyncCall(msg); + } +} + Plasma::ServiceJob* PlayerControl::createJob(const QString& operation, QMap& parameters) {