Skip to content

Commit

Permalink
FIX(client): Fix using the keyboad to change local volume adjustment
Browse files Browse the repository at this point in the history
Previously, when using keyboard arrows, the new slider widget action
applied the new local volume but did not save it. That was because it
used the sliderReleased event to save the value, which is not triggered
by keyboard updates.

We could simply save the local volume on every sliderChange instead of
on sliderRelease, but that would cause many writes to the disk
in a short period of time and possibly lag the client.

This commit introduces an event filter in addition to the sliderChanged event,
which is observing key releases. If the slider has focus and left/right is released,
it is then calling the save slot of the slider.

Fixes #6211
  • Loading branch information
Hartmnt committed Oct 12, 2023
1 parent ca3f296 commit 5d32ac3
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/mumble/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ set(MUMBLE_SOURCES

"widgets/CompletablePage.cpp"
"widgets/CompletablePage.h"
"widgets/EventFilters.cpp"
"widgets/EventFilters.h"
"widgets/MUComboBox.cpp"
"widgets/MUComboBox.h"
"widgets/MultiStyleWidgetWrapper.cpp"
Expand Down
2 changes: 1 addition & 1 deletion src/mumble/ListenerVolumeSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void ListenerVolumeSlider::on_VolumeSlider_valueChanged(int value) {
displayTooltip(value);
}

void ListenerVolumeSlider::on_VolumeSlider_sliderReleased() {
void ListenerVolumeSlider::on_VolumeSlider_changeCompleted() {
ServerHandlerPtr handler = Global::get().sh;

if (!handler || !m_channel || !m_volumeSlider) {
Expand Down
2 changes: 1 addition & 1 deletion src/mumble/ListenerVolumeSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ListenerVolumeSlider : public VolumeSliderWidgetAction {

private slots:
void on_VolumeSlider_valueChanged(int value) override;
void on_VolumeSlider_sliderReleased() override;
void on_VolumeSlider_changeCompleted() override;
};

#endif
2 changes: 1 addition & 1 deletion src/mumble/UserLocalVolumeSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void UserLocalVolumeSlider::on_VolumeSlider_valueChanged(int value) {
}
}

void UserLocalVolumeSlider::on_VolumeSlider_sliderReleased() {
void UserLocalVolumeSlider::on_VolumeSlider_changeCompleted() {
ClientUser *user = ClientUser::get(m_clientSession);
if (user) {
if (!user->qsHash.isEmpty()) {
Expand Down
2 changes: 1 addition & 1 deletion src/mumble/UserLocalVolumeSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class UserLocalVolumeSlider : public VolumeSliderWidgetAction {

private slots:
void on_VolumeSlider_valueChanged(int value);
void on_VolumeSlider_sliderReleased();
void on_VolumeSlider_changeCompleted();
};

#endif
9 changes: 8 additions & 1 deletion src/mumble/VolumeSliderWidgetAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "VolumeSliderWidgetAction.h"
#include "VolumeAdjustment.h"
#include "widgets/EventFilters.h"

#include <QSlider>
#include <QToolTip>
Expand All @@ -16,10 +17,16 @@ VolumeSliderWidgetAction::VolumeSliderWidgetAction(QObject *parent)
m_volumeSlider->setAccessibleName(tr("Slider for volume adjustment"));
m_volumeSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);

KeyEventObserver *eventFilter = new KeyEventObserver(this, QEvent::KeyRelease, false,
{ Qt::Key_Left, Qt::Key_Right, Qt::Key_Up, Qt::Key_Down });
m_volumeSlider->installEventFilter(eventFilter);

connect(m_volumeSlider.get(), &QSlider::valueChanged, this,
&VolumeSliderWidgetAction::on_VolumeSlider_valueChanged);
connect(m_volumeSlider.get(), &QSlider::sliderReleased, this,
&VolumeSliderWidgetAction::on_VolumeSlider_sliderReleased);
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);
connect(eventFilter, &KeyEventObserver::keyEventObserved, this,
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);

setDefaultWidget(m_volumeSlider.get());

Expand Down
2 changes: 1 addition & 1 deletion src/mumble/VolumeSliderWidgetAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class VolumeSliderWidgetAction : public QWidgetAction {

protected slots:
virtual void on_VolumeSlider_valueChanged(int){};
virtual void on_VolumeSlider_sliderReleased(){};
virtual void on_VolumeSlider_changeCompleted(){};
};

#endif
40 changes: 40 additions & 0 deletions src/mumble/widgets/EventFilters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "EventFilters.h"

#include <algorithm>

#include <QKeyEvent>
#include <QWidget>

KeyEventObserver::KeyEventObserver(QObject *parent, QEvent::Type eventType, bool consume,
std::initializer_list< Qt::Key > keys)
: QObject(parent), m_eventType(eventType), m_consume(consume), m_keys(keys) {
}

bool KeyEventObserver::eventFilter(QObject *obj, QEvent *event) {
QWidget *widget = static_cast< QWidget * >(obj);

if (!widget || !widget->hasFocus()) {
return false;
}

QKeyEvent *keyEvent = static_cast< QKeyEvent * >(event);

if (!keyEvent || keyEvent->type() != m_eventType) {
return false;
}

Qt::Key key = static_cast< Qt::Key >(keyEvent->key());

if (std::find(m_keys.begin(), m_keys.end(), key) == m_keys.end()) {
return false;
}

emit keyEventObserved();

return m_consume;
}
33 changes: 33 additions & 0 deletions src/mumble/widgets/EventFilters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#ifndef MUMBLE_MUMBLE_WIDGETS_EVENTFILTERS_H_
#define MUMBLE_MUMBLE_WIDGETS_EVENTFILTERS_H_

#include <initializer_list>
#include <vector>

#include <QEvent>
#include <QObject>

class KeyEventObserver : public QObject {
Q_OBJECT

private:
QEvent::Type m_eventType;
bool m_consume;
std::vector< Qt::Key > m_keys;

public:
KeyEventObserver(QObject *parent, QEvent::Type eventType, bool consume, std::initializer_list< Qt::Key > keys);

protected:
bool eventFilter(QObject *obj, QEvent *event) override;

signals:
void keyEventObserved();
};

#endif

0 comments on commit 5d32ac3

Please sign in to comment.