Skip to content

Commit

Permalink
Fixed volume change with hi-res mice and touchpad scrolling
Browse files Browse the repository at this point in the history
An angle of 15° is required for changing the volume — as with ordinary mice.

Also,

 * Changing the volume by touchpad scrolling is fixed; and
 * Tooltip flickering on wheel rotation is prevented.
  • Loading branch information
tsujan committed Jan 14, 2023
1 parent 38c8a8d commit 45506d1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
35 changes: 31 additions & 4 deletions plugin-volume/volumepopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include <XdgIcon>

#include <QTimer>
#include <QSlider>
#include <QStyleOptionButton>
#include <QPushButton>
Expand All @@ -47,7 +48,8 @@ VolumePopup::VolumePopup(QWidget* parent):
QDialog(parent, Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint),
m_pos(0,0),
m_anchor(Qt::TopLeftCorner),
m_device(nullptr)
m_device(nullptr),
mWheelTimer(new QTimer(this))
{
// Under some Wayland compositors, setting window flags in the c-tor of the base class
// may not be enough for a correct positioning of the popup.
Expand Down Expand Up @@ -84,6 +86,15 @@ VolumePopup::VolumePopup(QWidget* parent):
connect(m_mixerButton, &QPushButton::released, this, &VolumePopup::launchMixer);
connect(m_volumeSlider, &QSlider::valueChanged, this, &VolumePopup::handleSliderValueChanged);
connect(m_muteToggleButton, &QPushButton::clicked, this, &VolumePopup::handleMuteToggleClicked);

mWheelTimer->setSingleShot(true);
mWheelTimer->setInterval(350); // "QStyle::SH_ToolTip_WakeUpDelay" is 700 by default
connect(mWheelTimer, &QTimer::timeout, this, [this] {
QTimer::singleShot(0, this, [this] {
if (!QToolTip::isVisible())
QToolTip::showText(QCursor::pos(), m_volumeSlider->toolTip());
});
});
}

bool VolumePopup::event(QEvent *event)
Expand Down Expand Up @@ -127,7 +138,10 @@ void VolumePopup::handleSliderValueChanged(int value)
return;
// qDebug("VolumePopup::handleSliderValueChanged: %d\n", value);
m_device->setVolume(value);
QTimer::singleShot(0, this, [this] { QToolTip::showText(QCursor::pos(), m_volumeSlider->toolTip()); });
QTimer::singleShot(0, this, [this] {
if (!mWheelTimer->isActive()) // a wheel event immediately hides the tooltip
QToolTip::showText(QCursor::pos(), m_volumeSlider->toolTip());
});
}

void VolumePopup::handleMuteToggleClicked()
Expand Down Expand Up @@ -197,8 +211,21 @@ void VolumePopup::openAt(QPoint pos, Qt::Corner anchor)

void VolumePopup::handleWheelEvent(QWheelEvent *event)
{
m_volumeSlider->setSliderPosition(m_volumeSlider->sliderPosition()
+ (event->angleDelta().y() / QWheelEvent::DefaultDeltasPerStep * m_volumeSlider->singleStep()));
static int _delta = 0; // for high-resolution mice and touchpad scrolling

int delta = event->angleDelta().y();
if ((_delta ^ delta) < 0)
_delta = delta; // the wheel direction is reversed
else
_delta += delta;
if (qAbs(_delta) >= QWheelEvent::DefaultDeltasPerStep) {
m_volumeSlider->setSliderPosition(m_volumeSlider->sliderPosition()
+ (_delta / QWheelEvent::DefaultDeltasPerStep * m_volumeSlider->singleStep()));
_delta = 0;
}

// show the tooltip only after the wheel rotation is stopped
mWheelTimer->start();
}

void VolumePopup::setDevice(AudioDevice *device)
Expand Down
2 changes: 2 additions & 0 deletions plugin-volume/volumepopup.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include <QDialog>

class QTimer;
class QSlider;
class QPushButton;
class AudioDevice;
Expand Down Expand Up @@ -81,6 +82,7 @@ private slots:
QPoint m_pos;
Qt::Corner m_anchor;
AudioDevice *m_device;
QTimer *mWheelTimer; // for showing tooltip with high-resolution mice
};

#endif // VOLUMEPOPUP_H

0 comments on commit 45506d1

Please sign in to comment.