#include #include #include #include "mixxxapplication.h" #include "library/crate/crateid.h" #include "control/controlproxy.h" #include "mixxx.h" // When linking Qt statically on Windows we have to Q_IMPORT_PLUGIN all the // plugins we link in build/depends.py. #ifdef QT_NODLL #include #if QT_VERSION >= 0x050000 // sqldrivers plugins Q_IMPORT_PLUGIN(QSQLiteDriverPlugin) // platform plugins Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) // style plugins Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) // imageformats plugins Q_IMPORT_PLUGIN(QSvgPlugin) Q_IMPORT_PLUGIN(QSvgIconPlugin) Q_IMPORT_PLUGIN(QICOPlugin) Q_IMPORT_PLUGIN(QTgaPlugin) Q_IMPORT_PLUGIN(QJpegPlugin) Q_IMPORT_PLUGIN(QGifPlugin) // accessible plugins // TODO(rryan): This is supposed to exist but does not in our builds. //Q_IMPORT_PLUGIN(AccessibleFactory) #else // iconengines plugins Q_IMPORT_PLUGIN(qsvgicon) // imageformats plugins Q_IMPORT_PLUGIN(qsvg) Q_IMPORT_PLUGIN(qico) Q_IMPORT_PLUGIN(qtga) // accessible plugins Q_IMPORT_PLUGIN(qtaccessiblewidgets) #endif #endif MixxxApplication::MixxxApplication(int& argc, char** argv) : QApplication(argc, argv), m_fakeMouseSourcePointId(0), m_fakeMouseWidget(NULL), m_activeTouchButton(Qt::NoButton), m_pTouchShift(NULL) { registerMetaTypes(); } MixxxApplication::~MixxxApplication() { } void MixxxApplication::registerMetaTypes() { // Register custom data types for signal processing qRegisterMetaType("TrackId"); qRegisterMetaType>("QList"); qRegisterMetaType>("QSet"); qRegisterMetaType("CrateId"); qRegisterMetaType>("QList"); qRegisterMetaType>("QSet"); qRegisterMetaType("TrackPointer"); qRegisterMetaType("mixxx::ReplayGain"); qRegisterMetaType("mixxx::Bpm"); qRegisterMetaType("mixxx::Duration"); } // Macs do not have touchscreens #ifndef Q_OS_MAC #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) extern void qt_translateRawTouchEvent(QWidget *window, QTouchEvent::DeviceType deviceType, const QList &touchPoints); bool MixxxApplication::notify(QObject* target, QEvent* event) { if (isMouseEventSynthesized()) { if (target->isWidgetType()) { QWidget* w = static_cast(target); if (w->testAttribute(Qt::WA_AcceptTouchEvents)) { // consume and discards Synthesized Mouse events // generated by the OS, to not perform the action // twice return true; } } } switch (event->type()) { case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: { QTouchEvent* touchEvent = static_cast(event); QList touchPoints = touchEvent->touchPoints(); QEvent::Type eventType = QEvent::None; Qt::MouseButtons buttons = Qt::NoButton; QWidget* fakeMouseWidget = NULL; bool baseReturn; //qDebug() << "&" << touchEvent->type() << target; if (touchEvent->deviceType() != QTouchEvent::TouchScreen) { break; } switch (event->type()) { case QEvent::TouchBegin: // try to deliver as touch event baseReturn = QApplication::notify(target, event); if (dynamic_cast(touchEvent->widget())) { // the touchEvent has fallen trough to the MixxxMainWindow, because there // was no touch enabled widget found. // Now we resent this event and all following events for this touch point // as Mouse events. eventType = QEvent::MouseButtonPress; if (touchIsRightButton()) { // touch is right click m_activeTouchButton = Qt::RightButton; buttons = Qt::RightButton; } else { m_activeTouchButton = Qt::LeftButton; buttons = Qt::LeftButton; } m_fakeMouseSourcePointId = touchPoints.first().id(); m_fakeMouseWidget = dynamic_cast(target); fakeMouseWidget = m_fakeMouseWidget; break; } return baseReturn; case QEvent::TouchUpdate: if (m_fakeMouseWidget) { eventType = QEvent::MouseMove; buttons = m_activeTouchButton; fakeMouseWidget = m_fakeMouseWidget; break; } return QApplication::notify(target, event); case QEvent::TouchEnd: if (m_fakeMouseWidget) { eventType = QEvent::MouseButtonRelease; m_fakeMouseSourcePointId = touchPoints.first().id(); fakeMouseWidget = m_fakeMouseWidget; m_fakeMouseWidget = NULL; break; } return QApplication::notify(target, event); default: return QApplication::notify(target, event); } for (int i = 0; i < touchPoints.count(); ++i) { const QTouchEvent::TouchPoint& touchPoint = touchPoints.at(i); if (touchPoint.id() == m_fakeMouseSourcePointId) { QMouseEvent mouseEvent(eventType, fakeMouseWidget->mapFromGlobal(touchPoint.screenPos().toPoint()), touchPoint.screenPos().toPoint(), m_activeTouchButton, // Button that causes the event buttons, touchEvent->modifiers()); //qDebug() << "#" << mouseEvent.type() << mouseEvent.button() << mouseEvent.buttons() << mouseEvent.pos() << mouseEvent.globalPos(); //if (m_fakeMouseWidget->focusPolicy() & Qt::ClickFocus) { // fakeMouseWidget->setFocus(); //} QApplication::notify(fakeMouseWidget, &mouseEvent); return true; } } //qDebug() << "return false"; return false; break; } case QEvent::MouseButtonRelease: { bool ret = QApplication::notify(target, event); if (m_fakeMouseWidget) { // It may happen the faked mouse event was grabbed by a non touch window. // eg.: if we have started to drag by touch. // In this case X11 generates a MouseButtonRelease instead of a TouchPointReleased Event. // QApplication still tracks the Touch point and prevent touch to other widgets // So we need to fake the Touch release event as well to clean up // QApplicationPrivate::widgetForTouchPointId and QApplicationPrivate::appCurrentTouchPoints; m_fakeMouseWidget = NULL; // Disable MouseButtonRelease fake QList touchPoints; QTouchEvent::TouchPoint tp; tp.setId(m_fakeMouseSourcePointId); tp.setState(Qt::TouchPointReleased); touchPoints.append(tp); qt_translateRawTouchEvent(NULL, QTouchEvent::TouchScreen, touchPoints); } return ret; } default: break; } // No touch event bool ret = QApplication::notify(target, event); return ret; } #endif // QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #endif // Q_OS_MAC bool MixxxApplication::touchIsRightButton() { if (!m_pTouchShift) { m_pTouchShift = new ControlProxy( "[Controls]", "touch_shift", this); } return (m_pTouchShift->get() != 0.0); }