summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBe <be@mixxx.org>2020-10-31 12:22:18 -0500
committerBe <be@mixxx.org>2020-10-31 12:22:18 -0500
commit2d0c5d7c74c4c23653825ba38aaa97f4cbc44c4d (patch)
treea655a1b07c2735f49057e0a302d143f17f5cfe73
parentca87f6a1c82f0a42263efd0019025cec92ee030b (diff)
parentbc10901de823bed00e98f422f6cc22bc4e2fd19d (diff)
Merge remote-tracking branch 'upstream/2.3' into main
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/effects/lv2/lv2effectprocessor.cpp6
-rw-r--r--src/library/librarycontrol.cpp8
-rw-r--r--src/mixxx.cpp21
-rw-r--r--src/mixxx.h1
-rw-r--r--src/mixxxapplication.cpp58
-rw-r--r--src/mixxxapplication.h6
-rw-r--r--src/widget/wwidget.cpp10
8 files changed, 72 insertions, 39 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4583be5f16..bca2c9088a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -87,6 +87,7 @@
* Use 6 instead of only 4 compatible musical keys (major/minor) [#3205](https://github.com/mixxxdj/mixxx/pull/3205)
* Fix possible memory corruption using JACK on Linux [#3160](https://github.com/mixxxdj/mixxx/pull/3160)
* Fix possible crash when trying to refocus the tracks table while another Mixxx window has focus [#3201](https://github.com/mixxxdj/mixxx/pull/3201)
+* Fix touch control [lp:1895431](https://bugs.launchpad.net/mixxx/+bug/1895431)
## [2.2.4](https://launchpad.net/mixxx/+milestone/2.2.4) (2020-06-27)
diff --git a/src/effects/lv2/lv2effectprocessor.cpp b/src/effects/lv2/lv2effectprocessor.cpp
index 8340aa7948..b5f8174110 100644
--- a/src/effects/lv2/lv2effectprocessor.cpp
+++ b/src/effects/lv2/lv2effectprocessor.cpp
@@ -114,14 +114,14 @@ void LV2EffectProcessor::process(const ChannelHandle& inputHandle,
if (!pState) {
SampleUtil::copyWithGain(pOutput, pInput, 1.0, bufferParameters.samplesPerBuffer());
return;
- }
+ }
for (int i = 0; i < m_parameters.size(); i++) {
m_params[i] = static_cast<float>(m_parameters[i]->value());
}
int j = 0;
- for (unsigned int i = 0; i < bufferParameters.samplesPerBuffer(); i += 2) {
+ for (SINT i = 0; i < bufferParameters.samplesPerBuffer(); i += 2) {
m_inputL[j] = pInput[i];
m_inputR[j] = pInput[i + 1];
j++;
@@ -130,7 +130,7 @@ void LV2EffectProcessor::process(const ChannelHandle& inputHandle,
lilv_instance_run(pState->lilvIinstance(), bufferParameters.framesPerBuffer());
j = 0;
- for (unsigned int i = 0; i < bufferParameters.samplesPerBuffer(); i += 2) {
+ for (SINT i = 0; i < bufferParameters.samplesPerBuffer(); i += 2) {
pOutput[i] = m_outputL[j];
pOutput[i + 1] = m_outputR[j];
j++;
diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp
index ae747479f4..f69af79e7e 100644
--- a/src/library/librarycontrol.cpp
+++ b/src/library/librarycontrol.cpp
@@ -603,10 +603,13 @@ void LibraryControl::emitKeyEvent(QKeyEvent&& event) {
if (keyIsTab && !QApplication::focusWidget()){
setLibraryFocus();
}
+
// Send the event pointer to the currently focused widget
auto focusWidget = QApplication::focusWidget();
- for (auto i = 0; i < event.count(); ++i) {
- QApplication::sendEvent(focusWidget, &event);
+ if (focusWidget) {
+ for (auto i = 0; i < event.count(); ++i) {
+ QApplication::sendEvent(focusWidget, &event);
+ }
}
}
@@ -617,6 +620,7 @@ void LibraryControl::setLibraryFocus() {
}
// Try to focus the sidebar.
m_pSidebarWidget->setFocus();
+
// This may have failed, for example when a Cover window still has focus,
// so make sure the sidebar is focused or we'll crash.
if (!m_pSidebarWidget->hasFocus()) {
diff --git a/src/mixxx.cpp b/src/mixxx.cpp
index 1ee7c51128..fb99dd4085 100644
--- a/src/mixxx.cpp
+++ b/src/mixxx.cpp
@@ -216,7 +216,6 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) {
pConfig->getValue(ConfigKey("[Controls]", "Tooltips"),
static_cast<int>(mixxx::TooltipsPreference::TOOLTIPS_ON)));
- setAttribute(Qt::WA_AcceptTouchEvents);
m_pTouchShift = new ControlPushButton(ConfigKey("[Controls]", "touch_shift"));
m_pDbConnectionPool = MixxxDb(pConfig).connectionPool();
@@ -1514,26 +1513,6 @@ bool MixxxMainWindow::eventFilter(QObject* obj, QEvent* event) {
return QObject::eventFilter(obj, event);
}
-bool MixxxMainWindow::event(QEvent* e) {
- switch(e->type()) {
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- {
- // If the touch event falls through to the main widget, no touch widget
- // was touched, so we resend it as a mouse event.
- // We have to accept it here, so QApplication will continue to deliver
- // the following events of this touch point as well.
- QTouchEvent* touchEvent = static_cast<QTouchEvent*>(e);
- touchEvent->accept();
- return true;
- }
- default:
- break;
- }
- return QWidget::event(e);
-}
-
void MixxxMainWindow::closeEvent(QCloseEvent *event) {
// WARNING: We can receive a CloseEvent while only partially
// initialized. This is because we call QApplication::processEvents to
diff --git a/src/mixxx.h b/src/mixxx.h
index 17aadc878f..c606b42ff2 100644
--- a/src/mixxx.h
+++ b/src/mixxx.h
@@ -96,7 +96,6 @@ class MixxxMainWindow : public QMainWindow {
/// Event filter to block certain events (eg. tooltips if tooltips are disabled)
bool eventFilter(QObject *obj, QEvent *event) override;
void closeEvent(QCloseEvent *event) override;
- bool event(QEvent* e) override;
private:
void initialize(QApplication *app, const CmdlineArgs& args);
diff --git a/src/mixxxapplication.cpp b/src/mixxxapplication.cpp
index f2b5e965ee..7bed455878 100644
--- a/src/mixxxapplication.cpp
+++ b/src/mixxxapplication.cpp
@@ -36,13 +36,24 @@ Q_IMPORT_PLUGIN(QGifPlugin)
//Q_IMPORT_PLUGIN(AccessibleFactory)
#endif
+namespace {
+
+/// This class allows to change the button of a mouse event on the fly.
+/// This is required because we want to change the behaviour of Qts mouse
+/// buttony synthesizer without duplicate all the code.
+class QMouseEventEditable : public QMouseEvent {
+ public:
+ void setButton(Qt::MouseButton button) {
+ b = button;
+ }
+};
+
+} // anonymous namespace
MixxxApplication::MixxxApplication(int& argc, char** argv)
: QApplication(argc, argv),
- m_fakeMouseSourcePointId(0),
- m_fakeMouseWidget(NULL),
- m_activeTouchButton(Qt::NoButton),
- m_pTouchShift(NULL) {
+ m_rightPressedButtons(0),
+ m_pTouchShift(nullptr) {
registerMetaTypes();
// Increase the size of the global thread pool to at least
@@ -86,10 +97,47 @@ void MixxxApplication::registerMetaTypes() {
qRegisterMetaType<std::optional<mixxx::RgbColor>>("std::optional<mixxx::RgbColor>");
}
+bool MixxxApplication::notify(QObject* target, QEvent* event) {
+ // All touch events are translated into two simultaneous events: one for
+ // the target QWidgetWindow and one for the target QWidget.
+ // A second touch becomes a mouse move without additional press and release
+ // events.
+ switch (event->type()) {
+ case QEvent::MouseButtonPress: {
+ QMouseEventEditable* mouseEvent = static_cast<QMouseEventEditable*>(event);
+ if (mouseEvent->source() == Qt::MouseEventSynthesizedByQt &&
+ mouseEvent->button() == Qt::LeftButton &&
+ touchIsRightButton()) {
+ // Assert the assumption that QT synthesizes only one click at a time
+ // = two events (see above)
+ VERIFY_OR_DEBUG_ASSERT(m_rightPressedButtons < 2) {
+ break;
+ }
+ mouseEvent->setButton(Qt::RightButton);
+ m_rightPressedButtons++;
+ }
+ break;
+ }
+ case QEvent::MouseButtonRelease: {
+ QMouseEventEditable* mouseEvent = static_cast<QMouseEventEditable*>(event);
+ if (mouseEvent->source() == Qt::MouseEventSynthesizedByQt &&
+ mouseEvent->button() == Qt::LeftButton &&
+ m_rightPressedButtons > 0) {
+ mouseEvent->setButton(Qt::RightButton);
+ m_rightPressedButtons--;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return QApplication::notify(target, event);
+}
+
bool MixxxApplication::touchIsRightButton() {
if (!m_pTouchShift) {
m_pTouchShift = new ControlProxy(
"[Controls]", "touch_shift", this);
}
- return (m_pTouchShift->get() != 0.0);
+ return m_pTouchShift->toBool();
}
diff --git a/src/mixxxapplication.h b/src/mixxxapplication.h
index 1348de29e2..a9a5a67524 100644
--- a/src/mixxxapplication.h
+++ b/src/mixxxapplication.h
@@ -11,13 +11,13 @@ class MixxxApplication : public QApplication {
MixxxApplication(int& argc, char** argv);
~MixxxApplication() override = default;
+ bool notify(QObject*, QEvent*) override;
+
private:
bool touchIsRightButton();
void registerMetaTypes();
- int m_fakeMouseSourcePointId;
- QWidget* m_fakeMouseWidget;
- enum Qt::MouseButton m_activeTouchButton;
+ int m_rightPressedButtons;
ControlProxy* m_pTouchShift;
};
diff --git a/src/widget/wwidget.cpp b/src/widget/wwidget.cpp
index 4f05531072..40b006e1ac 100644
--- a/src/widget/wwidget.cpp
+++ b/src/widget/wwidget.cpp
@@ -38,7 +38,7 @@ WWidget::~WWidget() {
}
bool WWidget::touchIsRightButton() {
- return (m_pTouchShift->get() != 0.0);
+ return m_pTouchShift->toBool();
}
bool WWidget::event(QEvent* e) {
@@ -92,11 +92,13 @@ bool WWidget::event(QEvent* e) {
const QTouchEvent::TouchPoint &touchPoint =
touchEvent->touchPoints().first();
QMouseEvent mouseEvent(eventType,
- touchPoint.pos().toPoint(),
- touchPoint.screenPos().toPoint(),
+ touchPoint.pos(),
+ touchPoint.pos(),
+ touchPoint.screenPos(),
m_activeTouchButton, // Button that causes the event
Qt::NoButton, // Not used, so no need to fake a proper value.
- touchEvent->modifiers());
+ touchEvent->modifiers(),
+ Qt::MouseEventSynthesizedByApplication);
return QWidget::event(&mouseEvent);
}