bool UBMousePressFilter::eventFilter(QObject *obj, QEvent *event) { const bool isMousePress = event->type() == QEvent::MouseButtonPress; const bool isMouseRelease = event->type() == QEvent::MouseButtonRelease; const bool isMouseMove = event->type() == QEvent::MouseMove; if (isMousePress) { QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event); if (mouseEvent) { if (mPendingEvent) { delete mPendingEvent; } mPendingEvent = new QMouseEvent(QEvent::MouseButtonDblClick, mouseEvent->pos(), mouseEvent->globalPos(), mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers()); mObject = obj; QTimer::singleShot(1000, this, SLOT(mouseDownElapsed())); } } else if (isMouseRelease || isMouseMove) { if (mPendingEvent) { QTabletEvent * tabletEvent = static_cast<QTabletEvent *>(event); QPoint point = tabletEvent->globalPos() - mPendingEvent->globalPos(); if (isMouseRelease || point.manhattanLength() > QApplication::startDragDistance()) { delete mPendingEvent; mPendingEvent = 0; mObject = 0; } } } return false; }
bool TabletWidget::eventFilter(QObject *, QEvent *ev) { switch (ev->type()) { case QEvent::TabletEnterProximity: case QEvent::TabletLeaveProximity: case QEvent::TabletMove: case QEvent::TabletPress: case QEvent::TabletRelease: { QTabletEvent *event = static_cast<QTabletEvent*>(ev); mType = event->type(); mPos = event->pos(); mGPos = event->globalPos(); mHiResGlobalPos = event->hiResGlobalPos(); mDev = event->device(); mPointerType = event->pointerType(); mUnique = event->uniqueId(); mXT = event->xTilt(); mYT = event->yTilt(); mZ = event->z(); mPress = event->pressure(); mTangential = event->tangentialPressure(); mRot = event->rotation(); mButton = event->button(); mButtons = event->buttons(); if (isVisible()) update(); break; } case QEvent::MouseMove: if (mMouseToo) { resetAttributes(); QMouseEvent *event = static_cast<QMouseEvent*>(ev); mType = event->type(); mPos = event->pos(); mGPos = event->globalPos(); } default: break; } return false; }
// override QApplication::notify() for greatest control over event handling bool TouchApplication::notify(QObject* receiver, QEvent* event) { //DebugEventFilter::printEvent(receiver, event); QEvent::Type evtype = event->type(); // first, try to pass TabletPress/TouchBegin event and see if anyone accepts it // In Qt, events are first sent to a QWindow, which then figures out what widget they should be sent to. // Unfortunately, QWindow event handler always returns true and doesn't change accepted state of event (it // sends a copy of the event and discards the accepted state of the copy), so we must save result from // sending event to final widget (by incrementing acceptCount) // When faking mouse events, we must send them to the QWindow instead of a widget, since some of the // routing logic is there, e.g., for handling popup windows if((evtype == QEvent::TabletPress || evtype == QEvent::TouchBegin) && inputState == None) { if(receiver->isWindowType()) { int prevacceptcount = acceptCount; receiver = getRecvWindow(receiver); QApplication::notify(receiver, event); if(acceptCount > prevacceptcount) { acceptCount = prevacceptcount; inputState = PassThru; return true; } // else, fall through and resend as mouse event // we must send a tablet release to put QWidgetWindow in consistent state // doesn't appear to be necessary for TouchBegin if(evtype == QEvent::TabletPress) { QTabletEvent* tev = static_cast<QTabletEvent*>(event); QTabletEvent rlev(QEvent::TabletRelease, tev->posF(), tev->globalPosF(), tev->device(), tev->pointerType(), 0, 0, 0, 0, 0, 0, tev->modifiers(), tev->uniqueId()); QApplication::notify(receiver, &rlev); } } else { event->setAccepted(false); bool res = QApplication::notify(receiver, event); if(event->isAccepted()) acceptCount++; return res; } } switch(evtype) { // reject external mouse events if we are translating touch or tablet input case QEvent::MouseButtonRelease: case QEvent::MouseMove: case QEvent::MouseButtonPress: // QWidgetWindow always forwards mouse event to widget as spontaneous event (why?) if(inputState != None && event->spontaneous() && receiver->isWindowType()) return true; // qDebug("This event should be rejected!"); break; case QEvent::TabletRelease: if(inputState == PassThru) inputState = None; case QEvent::TabletMove: case QEvent::TabletPress: { // TODO: should this only be done if inputState == TabletInput? receiver = getRecvWindow(receiver); QTabletEvent* tabletevent = static_cast<QTabletEvent*>(event); QEvent::Type mevtype = QEvent::MouseMove; if(inputState == None && evtype == QEvent::TabletPress) { mevtype = QEvent::MouseButtonPress; inputState = TabletInput; } else if(inputState != TabletInput) // this covers PassThru break; if(evtype == QEvent::TabletRelease) { mevtype = QEvent::MouseButtonRelease; inputState = None; } return sendMouseEvent(receiver, mevtype, tabletevent->globalPos(), tabletevent->modifiers()); } #ifdef QT_5 case QEvent::TouchCancel: evtype = QEvent::TouchEnd; #endif case QEvent::TouchEnd: if(inputState == PassThru) // && touchPoints.count() == 1) inputState = None; case QEvent::TouchUpdate: case QEvent::TouchBegin: { receiver = getRecvWindow(receiver); QTouchEvent* touchevent = static_cast<QTouchEvent*>(event); QEvent::Type mevtype = QEvent::MouseMove; if(inputState == None && evtype == QEvent::TouchBegin && touchevent->touchPoints().size() == 1 && touchevent->device()->type() != QTouchDevice::TouchPad) { activeTouchId = touchevent->touchPoints().first().id(); mevtype = QEvent::MouseButtonPress; inputState = TouchInput; } else if(inputState != TouchInput) // this covers PassThru break; if(evtype == QEvent::TouchEnd) inputState = None; event->setAccepted(true); QList<QTouchEvent::TouchPoint> touchPoints = touchevent->touchPoints(); for(int ii = 0; ii < touchPoints.count(); ++ii) { const QTouchEvent::TouchPoint& touchpt = touchPoints.at(ii); if(touchpt.id() == activeTouchId) { if(touchpt.state() == Qt::TouchPointReleased) { mevtype = QEvent::MouseButtonRelease; activeTouchId = -1; } return sendMouseEvent(receiver, mevtype, touchpt.screenPos().toPoint(), touchevent->modifiers()); } } // swallow all touch events until TouchEnd // another option would be to propagate the touch event with the activeTouchId point removed, if >1 point return true; } default: break; } return QApplication::notify(receiver, event); }