diff options
author | Be <be@mixxx.org> | 2020-10-31 12:22:18 -0500 |
---|---|---|
committer | Be <be@mixxx.org> | 2020-10-31 12:22:18 -0500 |
commit | 2d0c5d7c74c4c23653825ba38aaa97f4cbc44c4d (patch) | |
tree | a655a1b07c2735f49057e0a302d143f17f5cfe73 | |
parent | ca87f6a1c82f0a42263efd0019025cec92ee030b (diff) | |
parent | bc10901de823bed00e98f422f6cc22bc4e2fd19d (diff) |
Merge remote-tracking branch 'upstream/2.3' into main
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/effects/lv2/lv2effectprocessor.cpp | 6 | ||||
-rw-r--r-- | src/library/librarycontrol.cpp | 8 | ||||
-rw-r--r-- | src/mixxx.cpp | 21 | ||||
-rw-r--r-- | src/mixxx.h | 1 | ||||
-rw-r--r-- | src/mixxxapplication.cpp | 58 | ||||
-rw-r--r-- | src/mixxxapplication.h | 6 | ||||
-rw-r--r-- | src/widget/wwidget.cpp | 10 |
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); } |